1 /*
2   +----------------------------------------------------------------------+
3   | Copyright (c) The PHP Group                                          |
4   +----------------------------------------------------------------------+
5   | This source file is subject to version 3.01 of the PHP license,      |
6   | that is bundled with this package in the file LICENSE, and is        |
7   | available through the world-wide-web at the following url:           |
8   | https://www.php.net/license/3_01.txt                                 |
9   | If you did not receive a copy of the PHP license and are unable to   |
10   | obtain it through the world-wide-web, please send a note to          |
11   | license@php.net so we can mail you a copy immediately.               |
12   +----------------------------------------------------------------------+
13   | Authors: Andrey Hristov <andrey@php.net>                             |
14   |          Ulf Wendel <uw@php.net>                                     |
15   +----------------------------------------------------------------------+
16 */
17 
18 #ifndef MYSQLND_WIREPROTOCOL_H
19 #define MYSQLND_WIREPROTOCOL_H
20 
21 #define MYSQLND_HEADER_SIZE 4
22 #define COMPRESSED_HEADER_SIZE 3
23 
24 #define MYSQLND_NULL_LENGTH	(zend_ulong) ~0
25 
26 /* Used in mysqlnd_debug.c */
27 PHPAPI extern const char mysqlnd_read_header_name[];
28 PHPAPI extern const char mysqlnd_read_body_name[];
29 
30 
31 /* Packet handling */
32 #define PACKET_WRITE(conn, packet)	((packet)->header.m->write_to_net((conn), (packet)))
33 #define PACKET_READ(conn, packet)	((packet)->header.m->read_from_net((conn), (packet)))
34 #define PACKET_FREE(packet) \
35 	do { \
36 		DBG_INF_FMT("PACKET_FREE(%p)", packet); \
37 		if ((packet)->header.m->free_mem) { \
38 			((packet)->header.m->free_mem((packet))); \
39 		} \
40 	} while (0);
41 
42 PHPAPI extern const char * const mysqlnd_command_to_text[COM_END];
43 
44 /* Low-level extraction functionality */
45 typedef struct st_mysqlnd_packet_methods {
46 	enum_func_status	(*read_from_net)(MYSQLND_CONN_DATA * conn, void * packet);
47 	size_t				(*write_to_net)(MYSQLND_CONN_DATA * conn, void * packet);
48 	void				(*free_mem)(void *packet);
49 } mysqlnd_packet_methods;
50 
51 
52 typedef struct st_mysqlnd_packet_header {
53 	size_t		size;
54 	zend_uchar	packet_no;
55 
56 	mysqlnd_packet_methods *m;
57 } MYSQLND_PACKET_HEADER;
58 
59 /* Server greets the client */
60 typedef struct st_mysqlnd_packet_greet {
61 	MYSQLND_PACKET_HEADER		header;
62 	uint8_t		protocol_version;
63 	char		*server_version;
64 	uint32_t	thread_id;
65 	char		intern_auth_plugin_data[SCRAMBLE_LENGTH];
66 	MYSQLND_STRING authentication_plugin_data;
67 	/* 1 byte pad */
68 	uint32_t	server_capabilities;
69 	uint8_t		charset_no;
70 	uint16_t	server_status;
71 	/* 13 byte pad, in 5.5 first 2 bytes are more capabilities followed by 1 byte scramble_length */
72 	bool	pre41;
73 	/* If error packet, we use these */
74 	char 		error[MYSQLND_ERRMSG_SIZE+1];
75 	char 		sqlstate[MYSQLND_SQLSTATE_LENGTH + 1];
76 	unsigned int	error_no;
77 	char		*auth_protocol;
78 } MYSQLND_PACKET_GREET;
79 
80 
81 /* Client authenticates */
82 typedef struct st_mysqlnd_packet_auth {
83 	MYSQLND_PACKET_HEADER		header;
84 	const char	*user;
85 	const zend_uchar	*auth_data;
86 	size_t		auth_data_len;
87 	const char	*db;
88 	const char	*auth_plugin_name;
89 	uint32_t	client_flags;
90 	uint32_t	max_packet_size;
91 	uint8_t		charset_no;
92 	/* Here the packet ends. This is user supplied data */
93 	bool	send_auth_data;
94 	bool	is_change_user_packet;
95 	bool	silent;
96 	HashTable	*connect_attr;
97 	size_t		db_len;
98 } MYSQLND_PACKET_AUTH;
99 
100 /* Auth response packet */
101 typedef struct st_mysqlnd_packet_auth_response {
102 	MYSQLND_PACKET_HEADER		header;
103 	uint8_t		response_code;
104 	uint64_t	affected_rows;
105 	uint64_t	last_insert_id;
106 	uint16_t	server_status;
107 	uint16_t	warning_count;
108 	char		*message;
109 	size_t		message_len;
110 	/* If error packet, we use these */
111 	char 		error[MYSQLND_ERRMSG_SIZE+1];
112 	char 		sqlstate[MYSQLND_SQLSTATE_LENGTH + 1];
113 	unsigned int 	error_no;
114 
115 	char		*new_auth_protocol;
116 	size_t		new_auth_protocol_len;
117 	zend_uchar	*new_auth_protocol_data;
118 	size_t		new_auth_protocol_data_len;
119 } MYSQLND_PACKET_AUTH_RESPONSE;
120 
121 
122 /* Auth response packet */
123 typedef struct st_mysqlnd_packet_change_auth_response {
124 	MYSQLND_PACKET_HEADER		header;
125 	const zend_uchar	*auth_data;
126 	size_t				auth_data_len;
127 } MYSQLND_PACKET_CHANGE_AUTH_RESPONSE;
128 
129 
130 /* OK packet */
131 typedef struct st_mysqlnd_packet_ok {
132 	MYSQLND_PACKET_HEADER		header;
133 	uint8_t		field_count; /* always 0x0 */
134 	uint64_t	affected_rows;
135 	uint64_t	last_insert_id;
136 	uint16_t	server_status;
137 	uint16_t	warning_count;
138 	char		*message;
139 	size_t		message_len;
140 	/* If error packet, we use these */
141 	char 		error[MYSQLND_ERRMSG_SIZE+1];
142 	char 		sqlstate[MYSQLND_SQLSTATE_LENGTH + 1];
143 	unsigned int 	error_no;
144 } MYSQLND_PACKET_OK;
145 
146 
147 /* Command packet */
148 typedef struct st_mysqlnd_packet_command {
149 	MYSQLND_PACKET_HEADER			header;
150 	enum php_mysqlnd_server_command	command;
151 	MYSQLND_CSTRING	argument;
152 } MYSQLND_PACKET_COMMAND;
153 
154 
155 /* EOF packet */
156 typedef struct st_mysqlnd_packet_eof {
157 	MYSQLND_PACKET_HEADER		header;
158 	uint8_t		field_count; /* 0xFE */
159 	uint16_t	warning_count;
160 	uint16_t	server_status;
161 	/* If error packet, we use these */
162 	char 		error[MYSQLND_ERRMSG_SIZE+1];
163 	char 		sqlstate[MYSQLND_SQLSTATE_LENGTH + 1];
164 	unsigned int 	error_no;
165 } MYSQLND_PACKET_EOF;
166 /* EOF packet */
167 
168 
169 /* Result Set header*/
170 typedef struct st_mysqlnd_packet_rset_header {
171 	MYSQLND_PACKET_HEADER header;
172 	/*
173 	  0x00 => ok
174 	  ~0   => LOAD DATA LOCAL
175 	  error_no != 0 => error
176 	  others => result set -> Read res_field packets up to field_count
177 	*/
178 	zend_ulong		field_count;
179 	/*
180 	  These are filled if no SELECT query. For SELECT warning_count
181 	  and server status are in the last row packet, the EOF packet.
182 	*/
183 	uint16_t	warning_count;
184 	uint16_t	server_status;
185 	uint64_t	affected_rows;
186 	uint64_t	last_insert_id;
187 	/* This is for both LOAD DATA or info, when no result set */
188 	MYSQLND_STRING info_or_local_file;
189 	/* If error packet, we use these */
190 	MYSQLND_ERROR_INFO	error_info;
191 } MYSQLND_PACKET_RSET_HEADER;
192 
193 
194 /* Result set field packet */
195 typedef struct st_mysqlnd_packet_res_field {
196 	MYSQLND_PACKET_HEADER	header;
197 	MYSQLND_MEMORY_POOL		*memory_pool;
198 	MYSQLND_FIELD			*metadata;
199 	/* For table definitions, empty for result sets */
200 	bool				skip_parsing;
201 
202 	MYSQLND_ERROR_INFO		error_info;
203 } MYSQLND_PACKET_RES_FIELD;
204 
205 
206 /* Row packet */
207 typedef struct st_mysqlnd_packet_row {
208 	MYSQLND_PACKET_HEADER	header;
209 	uint32_t	field_count;
210 	bool	eof;
211 	/*
212 	  These are, of course, only for SELECT in the EOF packet,
213 	  which is detected by this packet
214 	*/
215 	uint16_t	warning_count;
216 	uint16_t	server_status;
217 
218 	MYSQLND_ROW_BUFFER	row_buffer;
219 	MYSQLND_MEMORY_POOL * result_set_memory_pool;
220 
221 	bool		binary_protocol;
222 	MYSQLND_FIELD	*fields_metadata;
223 
224 	/* If error packet, we use these */
225 	MYSQLND_ERROR_INFO	error_info;
226 } MYSQLND_PACKET_ROW;
227 
228 
229 /* Statistics packet */
230 typedef struct st_mysqlnd_packet_stats {
231 	MYSQLND_PACKET_HEADER	header;
232 	MYSQLND_STRING message;
233 } MYSQLND_PACKET_STATS;
234 
235 
236 /* COM_PREPARE response packet */
237 typedef struct st_mysqlnd_packet_prepare_response {
238 	MYSQLND_PACKET_HEADER	header;
239 	/* also known as field_count 0x00=OK , 0xFF=error */
240 	unsigned char	error_code;
241 	zend_ulong	stmt_id;
242 	unsigned int	field_count;
243 	unsigned int	param_count;
244 	unsigned int	warning_count;
245 
246 	/* present in case of error */
247 	MYSQLND_ERROR_INFO	error_info;
248 } MYSQLND_PACKET_PREPARE_RESPONSE;
249 
250 
251 /* Statistics packet */
252 typedef struct st_mysqlnd_packet_chg_user_resp {
253 	MYSQLND_PACKET_HEADER	header;
254 	uint32_t			response_code;
255 
256 	/* message_len is not part of the packet*/
257 	uint16_t			server_capabilities;
258 	/* If error packet, we use these */
259 	MYSQLND_ERROR_INFO	error_info;
260 	bool			server_asked_323_auth;
261 
262 	char		*new_auth_protocol;
263 	size_t		new_auth_protocol_len;
264 	zend_uchar	*new_auth_protocol_data;
265 	size_t		new_auth_protocol_data_len;
266 } MYSQLND_PACKET_CHG_USER_RESPONSE;
267 
268 
269 /* Command packet */
270 typedef struct st_mysqlnd_packet_sha256_pk_request {
271 	MYSQLND_PACKET_HEADER			header;
272 } MYSQLND_PACKET_SHA256_PK_REQUEST;
273 
274 typedef struct  st_mysqlnd_packet_sha256_pk_request_response {
275 	MYSQLND_PACKET_HEADER	header;
276 	zend_uchar 				*public_key;
277 	size_t					public_key_len;
278 } MYSQLND_PACKET_SHA256_PK_REQUEST_RESPONSE;
279 
280 typedef struct st_mysqlnd_packet_cached_sha2_result {
281 	MYSQLND_PACKET_HEADER		header;
282 	uint8_t		response_code;
283 	uint8_t 	result;
284 	uint8_t 	request;
285 	zend_uchar * password;
286 	size_t password_len;
287 	/* Used for auth switch request */
288 	char		*new_auth_protocol;
289 	size_t		new_auth_protocol_len;
290 	zend_uchar	*new_auth_protocol_data;
291 	size_t		new_auth_protocol_data_len;
292 	/* Used for error result */
293 	char 		error[MYSQLND_ERRMSG_SIZE+1];
294 	char 		sqlstate[MYSQLND_SQLSTATE_LENGTH + 1];
295 	unsigned int 	error_no;
296 } MYSQLND_PACKET_CACHED_SHA2_RESULT;
297 
298 
299 
300 zend_ulong		php_mysqlnd_net_field_length(const zend_uchar **packet);
301 zend_uchar *	php_mysqlnd_net_store_length(zend_uchar *packet, const uint64_t length);
302 size_t			php_mysqlnd_net_store_length_size(uint64_t length);
303 
304 PHPAPI extern const char * const mysqlnd_empty_string;
305 
306 enum_func_status php_mysqlnd_rowp_read_binary_protocol(MYSQLND_ROW_BUFFER * row_buffer, zval * fields,
307 										 unsigned int field_count, const MYSQLND_FIELD * fields_metadata,
308 										 bool as_int_or_float, MYSQLND_STATS * stats);
309 
310 
311 enum_func_status php_mysqlnd_rowp_read_text_protocol(MYSQLND_ROW_BUFFER * row_buffer, zval * fields,
312 										 unsigned int field_count, const MYSQLND_FIELD * fields_metadata,
313 										 bool as_int_or_float, MYSQLND_STATS * stats);
314 
315 
316 PHPAPI MYSQLND_PROTOCOL_PAYLOAD_DECODER_FACTORY * mysqlnd_protocol_payload_decoder_factory_init(MYSQLND_CONN_DATA * conn, const bool persistent);
317 PHPAPI void mysqlnd_protocol_payload_decoder_factory_free(MYSQLND_PROTOCOL_PAYLOAD_DECODER_FACTORY * const payload_decoder_factory);
318 
319 #endif /* MYSQLND_WIREPROTOCOL_H */
320