1 /*
2   +----------------------------------------------------------------------+
3   | PHP Version 7                                                        |
4   +----------------------------------------------------------------------+
5   | Copyright (c) The PHP Group                                          |
6   +----------------------------------------------------------------------+
7   | This source file is subject to version 3.01 of the PHP license,      |
8   | that is bundled with this package in the file LICENSE, and is        |
9   | available through the world-wide-web at the following url:           |
10   | http://www.php.net/license/3_01.txt                                  |
11   | If you did not receive a copy of the PHP license and are unable to   |
12   | obtain it through the world-wide-web, please send a note to          |
13   | license@php.net so we can mail you a copy immediately.               |
14   +----------------------------------------------------------------------+
15   | Author: Wez Furlong <wez@thebrainroom.com>                           |
16   +----------------------------------------------------------------------+
17 */
18 
19 #ifdef PHP_WIN32
20 #include "config.w32.h"
21 #include <Ws2tcpip.h>
22 #endif
23 
24 #if HAVE_SYS_SOCKET_H
25 # include <sys/socket.h>
26 #endif
27 
28 typedef php_stream *(php_stream_transport_factory_func)(const char *proto, size_t protolen,
29 		const char *resourcename, size_t resourcenamelen,
30 		const char *persistent_id, int options, int flags,
31 		struct timeval *timeout,
32 		php_stream_context *context STREAMS_DC);
33 typedef php_stream_transport_factory_func *php_stream_transport_factory;
34 
35 BEGIN_EXTERN_C()
36 PHPAPI int php_stream_xport_register(const char *protocol, php_stream_transport_factory factory);
37 PHPAPI int php_stream_xport_unregister(const char *protocol);
38 
39 #define STREAM_XPORT_CLIENT			0
40 #define STREAM_XPORT_SERVER			1
41 
42 #define STREAM_XPORT_CONNECT		2
43 #define STREAM_XPORT_BIND			4
44 #define STREAM_XPORT_LISTEN			8
45 #define STREAM_XPORT_CONNECT_ASYNC	16
46 
47 /* Open a client or server socket connection */
48 PHPAPI php_stream *_php_stream_xport_create(const char *name, size_t namelen, int options,
49 		int flags, const char *persistent_id,
50 		struct timeval *timeout,
51 		php_stream_context *context,
52 		zend_string **error_string,
53 		int *error_code
54 		STREAMS_DC);
55 
56 #define php_stream_xport_create(name, namelen, options, flags, persistent_id, timeout, context, estr, ecode) \
57 	_php_stream_xport_create(name, namelen, options, flags, persistent_id, timeout, context, estr, ecode STREAMS_CC)
58 
59 /* Bind the stream to a local address */
60 PHPAPI int php_stream_xport_bind(php_stream *stream,
61 		const char *name, size_t namelen,
62 		zend_string **error_text
63 		);
64 
65 /* Connect to a remote address */
66 PHPAPI int php_stream_xport_connect(php_stream *stream,
67 		const char *name, size_t namelen,
68 		int asynchronous,
69 		struct timeval *timeout,
70 		zend_string **error_text,
71 		int *error_code
72 		);
73 
74 /* Prepare to listen */
75 PHPAPI int php_stream_xport_listen(php_stream *stream,
76 		int backlog,
77 		zend_string **error_text
78 		);
79 
80 /* Get the next client and their address as a string, or the underlying address
81  * structure.  You must efree either of these if you request them */
82 PHPAPI int php_stream_xport_accept(php_stream *stream, php_stream **client,
83 		zend_string **textaddr,
84 		void **addr, socklen_t *addrlen,
85 		struct timeval *timeout,
86 		zend_string **error_text
87 		);
88 
89 /* Get the name of either the socket or it's peer */
90 PHPAPI int php_stream_xport_get_name(php_stream *stream, int want_peer,
91 		zend_string **textaddr,
92 		void **addr, socklen_t *addrlen
93 		);
94 
95 enum php_stream_xport_send_recv_flags {
96 	STREAM_OOB = 1,
97 	STREAM_PEEK = 2
98 };
99 
100 /* Similar to recv() system call; read data from the stream, optionally
101  * peeking, optionally retrieving OOB data */
102 PHPAPI int php_stream_xport_recvfrom(php_stream *stream, char *buf, size_t buflen,
103 		int flags, void **addr, socklen_t *addrlen,
104 		zend_string **textaddr);
105 
106 /* Similar to send() system call; send data to the stream, optionally
107  * sending it as OOB data */
108 PHPAPI int php_stream_xport_sendto(php_stream *stream, const char *buf, size_t buflen,
109 		int flags, void *addr, socklen_t addrlen);
110 
111 typedef enum {
112 	STREAM_SHUT_RD,
113 	STREAM_SHUT_WR,
114 	STREAM_SHUT_RDWR
115 } stream_shutdown_t;
116 
117 /* Similar to shutdown() system call; shut down part of a full-duplex
118  * connection */
119 PHPAPI int php_stream_xport_shutdown(php_stream *stream, stream_shutdown_t how);
120 END_EXTERN_C()
121 
122 
123 /* Structure definition for the set_option interface that the above functions wrap */
124 
125 typedef struct _php_stream_xport_param {
126 	enum {
127 		STREAM_XPORT_OP_BIND, STREAM_XPORT_OP_CONNECT,
128 		STREAM_XPORT_OP_LISTEN, STREAM_XPORT_OP_ACCEPT,
129 		STREAM_XPORT_OP_CONNECT_ASYNC,
130 		STREAM_XPORT_OP_GET_NAME,
131 		STREAM_XPORT_OP_GET_PEER_NAME,
132 		STREAM_XPORT_OP_RECV,
133 		STREAM_XPORT_OP_SEND,
134 		STREAM_XPORT_OP_SHUTDOWN
135 	} op;
136 	unsigned int want_addr:1;
137 	unsigned int want_textaddr:1;
138 	unsigned int want_errortext:1;
139 	unsigned int how:2;
140 
141 	struct {
142 		char *name;
143 		size_t namelen;
144 		struct timeval *timeout;
145 		struct sockaddr *addr;
146 		char *buf;
147 		size_t buflen;
148 		socklen_t addrlen;
149 		int backlog;
150 		int flags;
151 	} inputs;
152 	struct {
153 		php_stream *client;
154 		struct sockaddr *addr;
155 		socklen_t addrlen;
156 		zend_string *textaddr;
157 		zend_string *error_text;
158 		int returncode;
159 		int error_code;
160 	} outputs;
161 } php_stream_xport_param;
162 
163 /* Because both client and server streams use the same mechanisms
164    for encryption we use the LSB to denote clients.
165 */
166 typedef enum {
167 	STREAM_CRYPTO_METHOD_SSLv2_CLIENT = (1 << 1 | 1),
168 	STREAM_CRYPTO_METHOD_SSLv3_CLIENT = (1 << 2 | 1),
169 	/* v23 no longer negotiates SSL2 or SSL3 */
170 	STREAM_CRYPTO_METHOD_SSLv23_CLIENT = ((1 << 3) | (1 << 4) | (1 << 5) | 1),
171 	STREAM_CRYPTO_METHOD_TLSv1_0_CLIENT = (1 << 3 | 1),
172 	STREAM_CRYPTO_METHOD_TLSv1_1_CLIENT = (1 << 4 | 1),
173 	STREAM_CRYPTO_METHOD_TLSv1_2_CLIENT = (1 << 5 | 1),
174 	STREAM_CRYPTO_METHOD_TLSv1_3_CLIENT = (1 << 6 | 1),
175 	/* TLS equates to TLS_ANY as of PHP 7.2 */
176 	STREAM_CRYPTO_METHOD_TLS_CLIENT = ((1 << 3) | (1 << 4) | (1 << 5) | (1 << 6) | 1),
177 	STREAM_CRYPTO_METHOD_TLS_ANY_CLIENT = ((1 << 3) | (1 << 4) | (1 << 5) | (1 << 6) | 1),
178 	STREAM_CRYPTO_METHOD_ANY_CLIENT = ((1 << 1) | (1 << 2) | (1 << 3) | (1 << 4) | (1 << 5) | (1 << 6) | 1),
179 	STREAM_CRYPTO_METHOD_SSLv2_SERVER = (1 << 1),
180 	STREAM_CRYPTO_METHOD_SSLv3_SERVER = (1 << 2),
181 	/* v23 no longer negotiates SSL2 or SSL3 */
182 	STREAM_CRYPTO_METHOD_SSLv23_SERVER = ((1 << 3) | (1 << 4) | (1 << 5) | (1 << 6)),
183 	STREAM_CRYPTO_METHOD_TLSv1_0_SERVER = (1 << 3),
184 	STREAM_CRYPTO_METHOD_TLSv1_1_SERVER = (1 << 4),
185 	STREAM_CRYPTO_METHOD_TLSv1_2_SERVER = (1 << 5),
186 	STREAM_CRYPTO_METHOD_TLSv1_3_SERVER = (1 << 6),
187 	/* TLS equates to TLS_ANY as of PHP 7.2 */
188 	STREAM_CRYPTO_METHOD_TLS_SERVER = ((1 << 3) | (1 << 4) | (1 << 5) | (1 << 6)),
189 	STREAM_CRYPTO_METHOD_TLS_ANY_SERVER = ((1 << 3) | (1 << 4) | (1 << 5) | (1 << 6)),
190 	STREAM_CRYPTO_METHOD_ANY_SERVER = ((1 << 1) | (1 << 2) | (1 << 3) | (1 << 4) | (1 << 5) | (1 << 6))
191 } php_stream_xport_crypt_method_t;
192 
193 /* These functions provide crypto support on the underlying transport */
194 
195 BEGIN_EXTERN_C()
196 PHPAPI int php_stream_xport_crypto_setup(php_stream *stream, php_stream_xport_crypt_method_t crypto_method, php_stream *session_stream);
197 PHPAPI int php_stream_xport_crypto_enable(php_stream *stream, int activate);
198 END_EXTERN_C()
199 
200 typedef struct _php_stream_xport_crypto_param {
201 	struct {
202 		php_stream *session;
203 		int activate;
204 		php_stream_xport_crypt_method_t method;
205 	} inputs;
206 	struct {
207 		int returncode;
208 	} outputs;
209 	enum {
210 		STREAM_XPORT_CRYPTO_OP_SETUP,
211 		STREAM_XPORT_CRYPTO_OP_ENABLE
212 	} op;
213 } php_stream_xport_crypto_param;
214 
215 BEGIN_EXTERN_C()
216 PHPAPI HashTable *php_stream_xport_get_hash(void);
217 PHPAPI php_stream_transport_factory_func php_stream_generic_socket_factory;
218 END_EXTERN_C()
219