49 drizzle_return_t drizzle_handshake_server_read(drizzle_con_st *con)
60 drizzle_return_t drizzle_handshake_client_write(drizzle_con_st *con)
81 drizzle_return_t drizzle_handshake_server_write(drizzle_con_st *con)
92 drizzle_return_t drizzle_handshake_client_read(drizzle_con_st *con)
107 drizzle_return_t drizzle_state_handshake_server_read(drizzle_con_st *con)
111 unsigned char* packet_end;
115 return DRIZZLE_RETURN_INVALID_ARGUMENT;
120 if (con->buffer_size < con->packet_size)
123 return DRIZZLE_RETURN_OK;
126 if (con->packet_size < 46)
129 "bad packet size:>=46:%zu", con->packet_size);
130 return DRIZZLE_RETURN_BAD_HANDSHAKE_PACKET;
133 packet_end= con->buffer_ptr + con->packet_size;
134 con->protocol_version= con->buffer_ptr[0];
137 if (con->protocol_version != 10)
141 if (con->protocol_version == 255)
144 "%.*s", (int32_t)con->packet_size - 3,
145 con->buffer_ptr + 2);
146 return DRIZZLE_RETURN_AUTH_FAILED;
150 "protocol version not supported:%d",
151 con->protocol_version);
152 return DRIZZLE_RETURN_PROTOCOL_NOT_SUPPORTED;
156 ptr= (uint8_t*)memchr(con->buffer_ptr, 0, con->buffer_size - 1);
160 "server version string not found");
161 return DRIZZLE_RETURN_BAD_HANDSHAKE_PACKET;
164 if (con->packet_size < (46 + (
size_t)(ptr - con->buffer_ptr)))
167 "bad packet size:%zu:%zu",
168 (46 + (
size_t)(ptr - con->buffer_ptr)), con->packet_size);
169 return DRIZZLE_RETURN_BAD_HANDSHAKE_PACKET;
172 strncpy(con->server_version, (
char *)con->buffer_ptr,
173 DRIZZLE_MAX_SERVER_VERSION_SIZE);
174 con->server_version[DRIZZLE_MAX_SERVER_VERSION_SIZE - 1]= 0;
175 con->buffer_ptr+= ((ptr - con->buffer_ptr) + 1);
177 con->thread_id= (uint32_t)drizzle_get_byte4(con->buffer_ptr);
180 con->scramble= con->scramble_buffer;
181 memcpy(con->scramble, con->buffer_ptr, 8);
188 con->capabilities= (drizzle_capabilities_t)drizzle_get_byte2(con->buffer_ptr);
191 if (con->options & DRIZZLE_CON_MYSQL &&
192 !(con->capabilities & DRIZZLE_CAPABILITIES_PROTOCOL_41))
195 "protocol version not supported, must be MySQL 4.1+");
196 return DRIZZLE_RETURN_PROTOCOL_NOT_SUPPORTED;
199 con->charset= con->buffer_ptr[0];
202 con->status= drizzle_con_status_t(drizzle_get_byte2(con->buffer_ptr));
204 con->buffer_ptr+= 15;
206 memcpy(con->scramble + 8, con->buffer_ptr, 12);
207 con->buffer_ptr+= 13;
210 extra_length= packet_end - con->buffer_ptr;
211 assert(extra_length >= 0);
212 if (extra_length > DRIZZLE_MAX_SERVER_EXTRA_SIZE - 1)
213 extra_length= DRIZZLE_MAX_SERVER_EXTRA_SIZE - 1;
214 memcpy(con->server_extra, (
char *)con->buffer_ptr, extra_length);
215 con->server_extra[extra_length]= 0;
217 con->buffer_size-= con->packet_size;
218 if (con->buffer_size != 0)
221 "unexpected data after packet:%zu", con->buffer_size);
222 return DRIZZLE_RETURN_UNEXPECTED_DATA;
225 con->buffer_ptr= con->buffer;
229 if (!(con->options & DRIZZLE_CON_RAW_PACKET))
242 return DRIZZLE_RETURN_OK;
245 drizzle_return_t drizzle_state_handshake_server_write(drizzle_con_st *con)
251 return DRIZZLE_RETURN_INVALID_ARGUMENT;
257 + strlen(con->server_version) + 1
269 if ((con->packet_size + 4) > DRIZZLE_MAX_BUFFER_SIZE)
272 "buffer too small:%zu", con->packet_size + 4);
273 return DRIZZLE_RETURN_INTERNAL_ERROR;
276 ptr= con->buffer_ptr;
279 drizzle_set_byte3(ptr, con->packet_size);
281 con->packet_number= 1;
284 ptr[0]= con->protocol_version;
287 memcpy(ptr, con->server_version, strlen(con->server_version));
288 ptr+= strlen(con->server_version);
293 drizzle_set_byte4(ptr, con->thread_id);
296 if (con->scramble == NULL)
302 memcpy(ptr, con->scramble, 8);
309 if (con->options & DRIZZLE_CON_MYSQL)
310 con->capabilities|= DRIZZLE_CAPABILITIES_PROTOCOL_41;
313 drizzle_set_byte2(ptr, con->capabilities);
316 ptr[0]= con->charset;
319 drizzle_set_byte2(ptr, con->status);
325 if (con->scramble == NULL)
331 memcpy(ptr, con->scramble + 8, 12);
338 con->buffer_size+= (4 + con->packet_size);
341 if ((
size_t)(ptr - con->buffer_ptr) != (4 + con->packet_size))
344 "error packing server handshake:%zu:%zu",
345 (
size_t)(ptr - con->buffer_ptr), 4 + con->packet_size);
346 return DRIZZLE_RETURN_INTERNAL_ERROR;
350 return DRIZZLE_RETURN_OK;
353 drizzle_return_t drizzle_state_handshake_client_read(drizzle_con_st *con)
356 uint8_t scramble_size;
360 return DRIZZLE_RETURN_INVALID_ARGUMENT;
365 if (con->buffer_size < con->packet_size)
368 return DRIZZLE_RETURN_OK;
372 if (con->packet_size < 34)
375 "bad packet size:>=34:%zu", con->packet_size);
376 return DRIZZLE_RETURN_BAD_HANDSHAKE_PACKET;
381 con->capabilities= drizzle_get_byte4(con->buffer_ptr);
384 if (con->options & DRIZZLE_CON_MYSQL &&
385 !(con->capabilities & DRIZZLE_CAPABILITIES_PROTOCOL_41))
388 "protocol version not supported, must be MySQL 4.1+");
389 return DRIZZLE_RETURN_PROTOCOL_NOT_SUPPORTED;
392 con->max_packet_size= (uint32_t)drizzle_get_byte4(con->buffer_ptr);
395 con->charset= con->buffer_ptr[0];
399 con->buffer_ptr+= 23;
402 uint8_t *ptr= (uint8_t*)memchr(con->buffer_ptr, 0, con->buffer_size - 32);
406 "user string not found");
407 return DRIZZLE_RETURN_BAD_HANDSHAKE_PACKET;
410 if (con->buffer_ptr == ptr)
417 real_size+= (size_t)(ptr - con->buffer_ptr);
418 if (con->packet_size < real_size)
421 "bad packet size:>=%zu:%zu", real_size,
423 return DRIZZLE_RETURN_BAD_HANDSHAKE_PACKET;
426 strncpy(con->user, (
char *)con->buffer_ptr, DRIZZLE_MAX_USER_SIZE);
427 con->user[DRIZZLE_MAX_USER_SIZE - 1]= 0;
428 con->buffer_ptr+= ((ptr - con->buffer_ptr) + 1);
431 scramble_size= con->buffer_ptr[0];
434 if (scramble_size == 0)
440 if (scramble_size != DRIZZLE_MAX_SCRAMBLE_SIZE)
443 "wrong scramble size");
444 return DRIZZLE_RETURN_BAD_HANDSHAKE_PACKET;
447 real_size+= scramble_size;
448 con->scramble= con->scramble_buffer;
449 memcpy(con->scramble, con->buffer_ptr, DRIZZLE_MAX_SCRAMBLE_SIZE);
451 con->buffer_ptr+= DRIZZLE_MAX_SCRAMBLE_SIZE;
455 if ((34 + strlen(con->user) + scramble_size) == con->packet_size)
461 ptr= (uint8_t*)memchr(con->buffer_ptr, 0, con->buffer_size -
462 (34 + strlen(con->user) + scramble_size));
466 "db string not found");
467 return DRIZZLE_RETURN_BAD_HANDSHAKE_PACKET;
470 real_size+= ((size_t)(ptr - con->buffer_ptr) + 1);
471 if (con->packet_size != real_size)
474 "bad packet size:%zu:%zu", real_size, con->packet_size);
475 return DRIZZLE_RETURN_BAD_HANDSHAKE_PACKET;
478 if (con->buffer_ptr == ptr)
485 strncpy(con->db, (
char *)con->buffer_ptr, DRIZZLE_MAX_DB_SIZE);
486 con->db[DRIZZLE_MAX_DB_SIZE - 1]= 0;
487 con->buffer_ptr+= ((ptr - con->buffer_ptr) + 1);
491 con->buffer_size-= con->packet_size;
492 if (con->buffer_size != 0)
495 "unexpected data after packet:%zu", con->buffer_size);
496 return DRIZZLE_RETURN_UNEXPECTED_DATA;
499 con->buffer_ptr= con->buffer;
502 return DRIZZLE_RETURN_OK;
505 int drizzle_compile_capabilities(drizzle_con_st *con)
509 if (con->options & DRIZZLE_CON_MYSQL)
510 con->capabilities|= DRIZZLE_CAPABILITIES_PROTOCOL_41;
512 capabilities= con->capabilities & int(DRIZZLE_CAPABILITIES_CLIENT);
513 if (!(con->options & DRIZZLE_CON_FOUND_ROWS))
514 capabilities&= ~int(DRIZZLE_CAPABILITIES_FOUND_ROWS);
516 if (con->options & DRIZZLE_CON_INTERACTIVE)
518 capabilities|= int(DRIZZLE_CAPABILITIES_INTERACTIVE);
521 if (con->options & DRIZZLE_CON_MULTI_STATEMENTS)
523 capabilities|= int(DRIZZLE_CAPABILITIES_MULTI_STATEMENTS);
526 if (con->options & DRIZZLE_CON_AUTH_PLUGIN)
528 capabilities|= int(DRIZZLE_CAPABILITIES_PLUGIN_AUTH);
533 capabilities|= int(DRIZZLE_CAPABILITIES_SSL);
536 capabilities&= ~(int(DRIZZLE_CAPABILITIES_COMPRESS));
538 capabilities&= ~int(DRIZZLE_CAPABILITIES_CONNECT_WITH_DB);
543 drizzle_return_t drizzle_state_handshake_client_write(drizzle_con_st *con)
548 drizzle_return_t ret;
552 return DRIZZLE_RETURN_INVALID_ARGUMENT;
558 ssl_ret= SSL_connect(con->ssl);
561 drizzle_set_error(con->drizzle,
"drizzle_state_handshake_client_write",
"SSL error: %d", SSL_get_error(con->ssl, ssl_ret));
562 return DRIZZLE_RETURN_SSL_ERROR;
564 con->ssl_state= DRIZZLE_SSL_STATE_HANDSHAKE_COMPLETE;
572 + strlen(con->user) + 1
574 + DRIZZLE_MAX_SCRAMBLE_SIZE
575 + strlen(con->db) + 1;
578 if ((con->packet_size + 4) > DRIZZLE_MAX_BUFFER_SIZE)
581 "buffer too small:%zu", con->packet_size + 4);
582 return DRIZZLE_RETURN_INTERNAL_ERROR;
585 ptr= con->buffer_ptr;
588 ptr[3]= con->packet_number;
589 con->packet_number++;
592 capabilities= drizzle_compile_capabilities(con);
594 drizzle_set_byte4(ptr, capabilities);
597 drizzle_set_byte4(ptr, con->max_packet_size);
600 ptr[0]= con->charset;
607 if (ret != DRIZZLE_RETURN_OK)
610 con->buffer_size+= (4 + con->packet_size);
613 if ((
size_t)(ptr - con->buffer_ptr) != (4 + con->packet_size))
616 "error packing client handshake:%zu:%zu",
617 (
size_t)(ptr - con->buffer_ptr), 4 + con->packet_size);
618 return DRIZZLE_RETURN_INTERNAL_ERROR;
622 drizzle_set_byte3(con->buffer_ptr, con->packet_size);
625 return DRIZZLE_RETURN_OK;
628 drizzle_return_t drizzle_state_handshake_ssl_client_write(drizzle_con_st *con)
641 ptr= con->buffer_ptr;
642 drizzle_set_byte3(ptr, con->packet_size);
643 ptr[3]= con->packet_number;
644 con->packet_number++;
647 capabilities= drizzle_compile_capabilities(con);
648 drizzle_set_byte4(ptr, capabilities);
650 drizzle_set_byte4(ptr, con->max_packet_size);
653 ptr[0]= con->charset;
655 con->buffer_size+= con->packet_size + 4;
661 return DRIZZLE_RETURN_OK;
664 drizzle_return_t drizzle_state_handshake_result_read(drizzle_con_st *con)
668 return DRIZZLE_RETURN_INVALID_ARGUMENT;
672 drizzle_result_st result;
673 if (drizzle_result_create(con, &result) == NULL)
675 return DRIZZLE_RETURN_MEMORY;
678 con->result= &result;
680 drizzle_return_t ret= drizzle_state_result_read(con);
683 if (ret == DRIZZLE_RETURN_OK)
685 if (drizzle_result_eof(&result))
688 "old insecure authentication mechanism not supported");
689 ret= DRIZZLE_RETURN_AUTH_FAILED;
693 con->options|= DRIZZLE_CON_READY;
698 drizzle_result_free(&result);
700 if (ret == DRIZZLE_RETURN_ERROR_CODE)
702 return DRIZZLE_RETURN_HANDSHAKE_FAILED;