1 /* vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
2 *
3 * Drizzle Client & Protocol Library
4 *
5 * Copyright (C) 2008-2013 Drizzle Developer Group
6 * Copyright (C) 2008 Eric Day (eday@oddments.org)
7 * All rights reserved.
8 *
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions are
11 * met:
12 *
13 * * Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer.
15 *
16 * * Redistributions in binary form must reproduce the above
17 * copyright notice, this list of conditions and the following disclaimer
18 * in the documentation and/or other materials provided with the
19 * distribution.
20 *
21 * * The names of its contributors may not be used to endorse or
22 * promote products derived from this software without specific prior
23 * written permission.
24 *
25 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
26 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
27 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
28 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
29 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
30 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
31 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
32 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
33 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
34 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
35 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
36 *
37 */
38
39 /**
40 * @file
41 * @brief Handshake Definitions
42 */
43
44 #include "config.h"
45 #include "libdrizzle/common.h"
46
47 /*
48 * Client Definitions
49 */
50
drizzle_handshake_server_read(drizzle_st * con)51 drizzle_return_t drizzle_handshake_server_read(drizzle_st *con)
52 {
53 if (con->has_state())
54 {
55 con->push_state(drizzle_state_handshake_server_read);
56 con->push_state(drizzle_state_packet_read);
57 }
58
59 return drizzle_state_loop(con);
60 }
61
drizzle_handshake_client_write(drizzle_st * con)62 drizzle_return_t drizzle_handshake_client_write(drizzle_st *con)
63 {
64 if (con->has_state())
65 {
66 con->push_state(drizzle_state_write);
67 con->push_state(drizzle_state_handshake_client_write);
68
69 if (con->ssl)
70 {
71 con->push_state(drizzle_state_write);
72 con->push_state(drizzle_state_handshake_ssl_client_write);
73 }
74 }
75
76 return drizzle_state_loop(con);
77 }
78
79 /*
80 * State Definitions
81 */
82
drizzle_state_handshake_server_read(drizzle_st * con)83 drizzle_return_t drizzle_state_handshake_server_read(drizzle_st *con)
84 {
85 unsigned char *ptr;
86 ptrdiff_t extra_length;
87 unsigned char* packet_end;
88
89 if (con == NULL)
90 {
91 return DRIZZLE_RETURN_INVALID_ARGUMENT;
92 }
93 drizzle_log_debug(con, "drizzle_state_handshake_server_read");
94
95 /* Assume the entire handshake packet will fit in the buffer. */
96 if (con->buffer_size < con->packet_size)
97 {
98 con->push_state(drizzle_state_read);
99 return DRIZZLE_RETURN_OK;
100 }
101
102 if (con->packet_size < 46)
103 {
104 drizzle_set_error(con, "drizzle_state_handshake_server_read",
105 "bad packet size:>=46:%zu", con->packet_size);
106 return DRIZZLE_RETURN_BAD_HANDSHAKE_PACKET;
107 }
108
109 packet_end= con->buffer_ptr + con->packet_size;
110 con->protocol_version= con->buffer_ptr[0];
111 con->buffer_ptr++;
112
113 if (con->protocol_version != 10)
114 {
115 /* This is a special case where the server determines that authentication
116 will be impossible and denies any attempt right away. */
117 if (con->protocol_version == 255)
118 {
119 drizzle_set_error(con, "drizzle_state_handshake_server_read",
120 "%.*s", (int)con->packet_size - 3,
121 con->buffer_ptr + 2);
122 return DRIZZLE_RETURN_AUTH_FAILED;
123 }
124
125 drizzle_set_error(con, "drizzle_state_handshake_server_read",
126 "protocol version not supported:%d",
127 con->protocol_version);
128 return DRIZZLE_RETURN_PROTOCOL_NOT_SUPPORTED;
129 }
130
131 /* Look for null-terminated server version string. */
132 ptr= (unsigned char*)memchr(con->buffer_ptr, 0, con->buffer_size - 1);
133 if (ptr == NULL)
134 {
135 drizzle_set_error(con, "drizzle_state_handshake_server_read",
136 "server version string not found");
137 return DRIZZLE_RETURN_BAD_HANDSHAKE_PACKET;
138 }
139
140 if (con->packet_size < (46 + (size_t)(ptr - con->buffer_ptr)))
141 {
142 drizzle_set_error(con, "drizzle_state_handshake_server_read",
143 "bad packet size:%zu:%zu",
144 (46 + (size_t)(ptr - con->buffer_ptr)), con->packet_size);
145 return DRIZZLE_RETURN_BAD_HANDSHAKE_PACKET;
146 }
147
148 strncpy(con->server_version, (char *)con->buffer_ptr,
149 DRIZZLE_MAX_SERVER_VERSION_SIZE);
150 con->server_version[DRIZZLE_MAX_SERVER_VERSION_SIZE - 1]= 0;
151 con->buffer_ptr+= ((ptr - con->buffer_ptr) + 1);
152
153 con->thread_id= (uint32_t)drizzle_get_byte4(con->buffer_ptr);
154 con->buffer_ptr+= 4;
155
156 con->scramble= con->scramble_buffer;
157 memcpy(con->scramble, con->buffer_ptr, 8);
158 /* Skip scramble and filler. */
159 con->buffer_ptr+= 9;
160
161 /* Even though drizzle_capabilities is more than 2 bytes, the protocol only
162 allows for 2. This means some capabilities are not possible during this
163 handshake step. The options beyond 2 bytes are for client response only. */
164 con->capabilities= (drizzle_capabilities_t)drizzle_get_byte2(con->buffer_ptr);
165 con->buffer_ptr+= 2;
166
167 if (!(con->capabilities & DRIZZLE_CAPABILITIES_PROTOCOL_41))
168 {
169 drizzle_set_error(con, "drizzle_state_handshake_server_read",
170 "protocol version not supported, must be MySQL 4.1+");
171 return DRIZZLE_RETURN_PROTOCOL_NOT_SUPPORTED;
172 }
173
174 con->charset= (drizzle_charset_t)con->buffer_ptr[0];
175 con->buffer_ptr+= 1;
176
177 con->status= (drizzle_status_t)drizzle_get_byte2(con->buffer_ptr);
178 /* Skip status and filler. */
179 con->buffer_ptr+= 15;
180
181 memcpy(con->scramble + 8, con->buffer_ptr, 12);
182 con->buffer_ptr+= 13;
183
184 /* MySQL 5.5 adds "mysql_native_password" after the server greeting. */
185 extra_length= packet_end - con->buffer_ptr;
186 assert(extra_length >= 0);
187 if (extra_length > DRIZZLE_MAX_SERVER_EXTRA_SIZE - 1)
188 extra_length= DRIZZLE_MAX_SERVER_EXTRA_SIZE - 1;
189 memcpy(con->server_extra, (char *)con->buffer_ptr, extra_length);
190 con->server_extra[extra_length]= 0;
191
192 con->buffer_size-= con->packet_size;
193 if (con->buffer_size != 0)
194 {
195 drizzle_set_error(con, "drizzle_state_handshake_server_read",
196 "unexpected data after packet:%zu", con->buffer_size);
197 return DRIZZLE_RETURN_UNEXPECTED_DATA;
198 }
199
200 con->buffer_ptr= con->buffer;
201
202 con->pop_state();
203
204 if (con->state.raw_packet == false)
205 {
206 con->push_state(drizzle_state_handshake_result_read);
207 con->push_state(drizzle_state_packet_read);
208 con->push_state(drizzle_state_write);
209 con->push_state(drizzle_state_handshake_client_write);
210 if (con->ssl)
211 {
212 con->push_state(drizzle_state_write);
213 con->push_state(drizzle_state_handshake_ssl_client_write);
214 }
215 }
216
217 return DRIZZLE_RETURN_OK;
218 }
219
drizzle_state_handshake_server_write(drizzle_st * con)220 drizzle_return_t drizzle_state_handshake_server_write(drizzle_st *con)
221 {
222 unsigned char *ptr;
223
224 if (con == NULL)
225 {
226 return DRIZZLE_RETURN_INVALID_ARGUMENT;
227 }
228 drizzle_log_debug(con, "drizzle_state_handshake_server_write");
229
230 /* Calculate max packet size. */
231 con->packet_size= 1 /* Protocol version */
232 + strlen(con->server_version) + 1
233 + 4 /* Thread ID */
234 + 8 /* Scramble */
235 + 1 /* NULL */
236 + 2 /* Capabilities */
237 + 1 /* Language */
238 + 2 /* Status */
239 + 13 /* Unused */
240 + 12 /* Scramble */
241 + 1; /* NULL */
242
243 /* Assume the entire handshake packet will fit in the buffer. */
244 if ((con->packet_size + 4) > con->buffer_allocation)
245 {
246 drizzle_set_error(con, "drizzle_state_handshake_server_write",
247 "buffer too small:%zu", con->packet_size + 4);
248 return DRIZZLE_RETURN_INTERNAL_ERROR;
249 }
250
251 ptr= con->buffer_ptr;
252
253 /* Store packet size and packet number first. */
254 drizzle_set_byte3(ptr, con->packet_size);
255 ptr[3]= 0;
256 con->packet_number= 1;
257 ptr+= 4;
258
259 ptr[0]= con->protocol_version;
260 ptr++;
261
262 memcpy(ptr, con->server_version, strlen(con->server_version));
263 ptr+= strlen(con->server_version);
264
265 ptr[0]= 0;
266 ptr++;
267
268 drizzle_set_byte4(ptr, con->thread_id);
269 ptr+= 4;
270
271 if (con->scramble == NULL)
272 {
273 memset(ptr, 0, 8);
274 }
275 else
276 {
277 memcpy(ptr, con->scramble, 8);
278 }
279 ptr+= 8;
280
281 ptr[0]= 0;
282 ptr++;
283
284 con->capabilities = (drizzle_capabilities_t)((int) con->capabilities | (int)DRIZZLE_CAPABILITIES_PROTOCOL_41);
285
286 /* We can only send two bytes worth, this is a protocol limitation. */
287 drizzle_set_byte2(ptr, con->capabilities);
288 ptr+= 2;
289
290 ptr[0]= con->charset;
291 ptr++;
292
293 drizzle_set_byte2(ptr, con->status);
294 ptr+= 2;
295
296 memset(ptr, 0, 13);
297 ptr+= 13;
298
299 if (con->scramble == NULL)
300 {
301 memset(ptr, 0, 12);
302 }
303 else
304 {
305 memcpy(ptr, con->scramble + 8, 12);
306 }
307 ptr+= 12;
308
309 ptr[0]= 0;
310 ptr++;
311
312 con->buffer_size+= (4 + con->packet_size);
313
314 /* Make sure we packed it correctly. */
315 if ((size_t)(ptr - con->buffer_ptr) != (4 + con->packet_size))
316 {
317 drizzle_set_error(con, "drizzle_state_handshake_server_write",
318 "error packing server handshake:%zu:%zu",
319 (size_t)(ptr - con->buffer_ptr), 4 + con->packet_size);
320 return DRIZZLE_RETURN_INTERNAL_ERROR;
321 }
322
323 con->pop_state();
324 return DRIZZLE_RETURN_OK;
325 }
326
drizzle_state_handshake_client_read(drizzle_st * con)327 drizzle_return_t drizzle_state_handshake_client_read(drizzle_st *con)
328 {
329 size_t real_size;
330 uint8_t scramble_size;
331
332 if (con == NULL)
333 {
334 return DRIZZLE_RETURN_INVALID_ARGUMENT;
335 }
336 drizzle_log_debug(con, "drizzle_state_handshake_client_read");
337
338 /* Assume the entire handshake packet will fit in the buffer. */
339 if (con->buffer_size < con->packet_size)
340 {
341 con->push_state(drizzle_state_read);
342 return DRIZZLE_RETURN_OK;
343 }
344
345 /* This is the minimum packet size. */
346 if (con->packet_size < 34)
347 {
348 drizzle_set_error(con, "drizzle_state_handshake_client_read",
349 "bad packet size:>=34:%zu", con->packet_size);
350 return DRIZZLE_RETURN_BAD_HANDSHAKE_PACKET;
351 }
352
353 real_size= 34;
354
355 con->capabilities= (drizzle_capabilities_t) drizzle_get_byte4(con->buffer_ptr);
356 con->buffer_ptr+= 4;
357
358 if (!(con->capabilities & DRIZZLE_CAPABILITIES_PROTOCOL_41))
359 {
360 drizzle_set_error(con, "drizzle_state_handshake_client_read",
361 "protocol version not supported, must be MySQL 4.1+");
362 return DRIZZLE_RETURN_PROTOCOL_NOT_SUPPORTED;
363 }
364
365 con->max_packet_size= (uint32_t)drizzle_get_byte4(con->buffer_ptr);
366 con->buffer_ptr+= 4;
367
368 con->charset= (drizzle_charset_t)con->buffer_ptr[0];
369 con->buffer_ptr+= 1;
370
371 /* Skip unused. */
372 con->buffer_ptr+= 23;
373
374 /* Look for null-terminated user string. */
375 unsigned char *ptr= (unsigned char*)memchr(con->buffer_ptr, 0, con->buffer_size - 32);
376 if (ptr == NULL)
377 {
378 drizzle_set_error(con, "drizzle_state_handshake_client_read",
379 "user string not found");
380 return DRIZZLE_RETURN_BAD_HANDSHAKE_PACKET;
381 }
382
383 if (con->buffer_ptr == ptr)
384 {
385 con->user[0]= 0;
386 con->buffer_ptr++;
387 }
388 else
389 {
390 real_size+= (size_t)(ptr - con->buffer_ptr);
391 if (con->packet_size < real_size)
392 {
393 drizzle_set_error(con, "drizzle_state_handshake_client_read",
394 "bad packet size:>=%zu:%zu", real_size,
395 con->packet_size);
396 return DRIZZLE_RETURN_BAD_HANDSHAKE_PACKET;
397 }
398
399 strncpy(con->user, (char *)con->buffer_ptr, DRIZZLE_MAX_USER_SIZE);
400 con->user[DRIZZLE_MAX_USER_SIZE - 1]= 0;
401 con->buffer_ptr+= ((ptr - con->buffer_ptr) + 1);
402 }
403
404 scramble_size= con->buffer_ptr[0];
405 con->buffer_ptr+= 1;
406
407 if (scramble_size == 0)
408 {
409 con->scramble= NULL;
410 }
411 else
412 {
413 if (scramble_size != DRIZZLE_MAX_SCRAMBLE_SIZE)
414 {
415 drizzle_set_error(con, "drizzle_state_handshake_client_read",
416 "wrong scramble size");
417 return DRIZZLE_RETURN_BAD_HANDSHAKE_PACKET;
418 }
419
420 real_size+= scramble_size;
421 con->scramble= con->scramble_buffer;
422 memcpy(con->scramble, con->buffer_ptr, DRIZZLE_MAX_SCRAMBLE_SIZE);
423
424 con->buffer_ptr+= DRIZZLE_MAX_SCRAMBLE_SIZE;
425 }
426
427 /* Look for null-terminated db string. */
428 if ((34 + strlen(con->user) + scramble_size) == con->packet_size)
429 {
430 con->db[0]= 0;
431 }
432 else
433 {
434 ptr= (unsigned char*)memchr(con->buffer_ptr, 0, con->buffer_size -
435 (34 + strlen(con->user) + scramble_size));
436 if (ptr == NULL)
437 {
438 drizzle_set_error(con, "drizzle_state_handshake_client_read",
439 "db string not found");
440 return DRIZZLE_RETURN_BAD_HANDSHAKE_PACKET;
441 }
442
443 real_size+= ((size_t)(ptr - con->buffer_ptr) + 1);
444 if (con->packet_size != real_size)
445 {
446 drizzle_set_error(con, "drizzle_state_handshake_client_read",
447 "bad packet size:%zu:%zu", real_size, con->packet_size);
448 return DRIZZLE_RETURN_BAD_HANDSHAKE_PACKET;
449 }
450
451 if (con->buffer_ptr == ptr)
452 {
453 con->db[0]= 0;
454 con->buffer_ptr++;
455 }
456 else
457 {
458 strncpy(con->db, (char *)con->buffer_ptr, DRIZZLE_MAX_DB_SIZE);
459 con->db[DRIZZLE_MAX_DB_SIZE - 1]= 0;
460 con->buffer_ptr+= ((ptr - con->buffer_ptr) + 1);
461 }
462 }
463
464 con->buffer_size-= con->packet_size;
465 if (con->buffer_size != 0)
466 {
467 drizzle_set_error(con, "drizzle_state_handshake_client_read",
468 "unexpected data after packet:%zu", con->buffer_size);
469 return DRIZZLE_RETURN_UNEXPECTED_DATA;
470 }
471
472 con->buffer_ptr= con->buffer;
473
474 con->pop_state();
475 return DRIZZLE_RETURN_OK;
476 }
477
drizzle_compile_capabilities(drizzle_st * con)478 int drizzle_compile_capabilities(drizzle_st *con)
479 {
480 int capabilities;
481
482 con->capabilities = (drizzle_capabilities_t)((int)con->capabilities | (int)DRIZZLE_CAPABILITIES_PROTOCOL_41);
483
484 capabilities= con->capabilities & DRIZZLE_CAPABILITIES_CLIENT;
485 if (con->options.found_rows == false)
486 {
487 capabilities&= ~DRIZZLE_CAPABILITIES_FOUND_ROWS;
488 }
489
490 if (con->options.interactive)
491 {
492 capabilities|= DRIZZLE_CAPABILITIES_INTERACTIVE;
493 }
494
495 if (con->options.multi_statements)
496 {
497 capabilities|= DRIZZLE_CAPABILITIES_MULTI_STATEMENTS;
498 }
499
500 if (con->options.auth_plugin)
501 {
502 capabilities|= DRIZZLE_CAPABILITIES_PLUGIN_AUTH;
503 }
504 #ifdef USE_OPENSSL
505 if (con->ssl)
506 {
507 capabilities|= DRIZZLE_CAPABILITIES_SSL;
508 }
509 #endif
510 capabilities&= ~DRIZZLE_CAPABILITIES_COMPRESS;
511 if (con->db[0] == 0)
512 capabilities&= ~DRIZZLE_CAPABILITIES_CONNECT_WITH_DB;
513
514 return capabilities;
515 }
516
drizzle_state_handshake_client_write(drizzle_st * con)517 drizzle_return_t drizzle_state_handshake_client_write(drizzle_st *con)
518 {
519 unsigned char *ptr;
520 int capabilities;
521 #ifdef USE_OPENSSL
522 int ssl_ret;
523 #endif
524 drizzle_return_t ret;
525
526 if (con == NULL)
527 {
528 return DRIZZLE_RETURN_INVALID_ARGUMENT;
529 }
530 drizzle_log_debug(con, "drizzle_state_handshake_client_write");
531 #ifdef USE_OPENSSL
532 if (con->ssl)
533 {
534 ssl_ret= SSL_connect(con->ssl);
535 if (ssl_ret != 1)
536 {
537 drizzle_set_error(con, "drizzle_state_handshake_client_write", "SSL error: %d", SSL_get_error(con->ssl, ssl_ret));
538 return DRIZZLE_RETURN_SSL_ERROR;
539 }
540 con->ssl_state= DRIZZLE_SSL_STATE_HANDSHAKE_COMPLETE;
541 }
542 #endif
543 /* Calculate max packet size. */
544 con->packet_size= 4 /* Capabilities */
545 + 4 /* Max packet size */
546 + 1 /* Charset */
547 + 23 /* Unused */
548 + strlen(con->user) + 1
549 + 1 /* Scramble size */
550 + DRIZZLE_MAX_SCRAMBLE_SIZE
551 + strlen(con->db) + 1;
552
553 /* Assume the entire handshake packet will fit in the buffer. */
554 if ((con->packet_size + 4) > con->buffer_allocation)
555 {
556 drizzle_set_error(con, "drizzle_state_handshake_client_write",
557 "buffer too small:%zu", con->packet_size + 4);
558 return DRIZZLE_RETURN_INTERNAL_ERROR;
559 }
560
561 ptr= con->buffer_ptr;
562
563 /* Store packet size at the end since it may change. */
564 ptr[3]= con->packet_number;
565 con->packet_number++;
566 ptr+= 4;
567
568 capabilities= drizzle_compile_capabilities(con);
569
570 drizzle_set_byte4(ptr, capabilities);
571 ptr+= 4;
572
573 drizzle_set_byte4(ptr, con->max_packet_size);
574 ptr+= 4;
575
576 ptr[0]= con->charset;
577 ptr++;
578
579 memset(ptr, 0, 23);
580 ptr+= 23;
581
582 ptr= drizzle_pack_auth(con, ptr, &ret);
583 if (ret != DRIZZLE_RETURN_OK)
584 return ret;
585
586 con->buffer_size+= (4 + con->packet_size);
587
588 /* Make sure we packed it correctly. */
589 if ((size_t)(ptr - con->buffer_ptr) != (4 + con->packet_size))
590 {
591 drizzle_set_error(con, "drizzle_state_handshake_client_write",
592 "error packing client handshake:%zu:%zu",
593 (size_t)(ptr - con->buffer_ptr), 4 + con->packet_size);
594 return DRIZZLE_RETURN_INTERNAL_ERROR;
595 }
596
597 /* Store packet size now. */
598 drizzle_set_byte3(con->buffer_ptr, con->packet_size);
599
600 con->pop_state();
601 return DRIZZLE_RETURN_OK;
602 }
603
drizzle_state_handshake_ssl_client_write(drizzle_st * con)604 drizzle_return_t drizzle_state_handshake_ssl_client_write(drizzle_st *con)
605 {
606 unsigned char *ptr;
607 int capabilities;
608
609 drizzle_log_debug(con, "drizzle_state_handshake_ssl_client_write");
610
611 /* SSL handshake packet structure */
612 con->packet_size= 4 /* Capabilities */
613 + 4 /* Max packet size */
614 + 1 /* Charset */
615 + 23; /* Padding unused bytes */
616
617 ptr= con->buffer_ptr;
618 drizzle_set_byte3(ptr, con->packet_size);
619 ptr[3]= con->packet_number;
620 con->packet_number++;
621 ptr+= 4;
622
623 capabilities= drizzle_compile_capabilities(con);
624 drizzle_set_byte4(ptr, capabilities);
625 ptr+= 4;
626 drizzle_set_byte4(ptr, con->max_packet_size);
627 ptr+= 4;
628
629 ptr[0]= con->charset;
630
631 con->buffer_size+= con->packet_size + 4;
632 ptr++;
633
634 memset(ptr, 0, 23);
635
636 con->pop_state();
637 return DRIZZLE_RETURN_OK;
638 }
639
drizzle_state_handshake_result_read(drizzle_st * con)640 drizzle_return_t drizzle_state_handshake_result_read(drizzle_st *con)
641 {
642 if (con == NULL)
643 {
644 return DRIZZLE_RETURN_INVALID_ARGUMENT;
645 }
646 drizzle_log_debug(con, "drizzle_state_handshake_result_read");
647
648 drizzle_result_st *result = drizzle_result_create(con);
649
650 if (result == NULL)
651 {
652 return DRIZZLE_RETURN_MEMORY;
653 }
654
655 con->result= result;
656
657 drizzle_return_t ret= drizzle_state_result_read(con);
658 if (con->has_state())
659 {
660 if (ret == DRIZZLE_RETURN_OK)
661 {
662 if (drizzle_result_eof(result))
663 {
664 drizzle_set_error(con, "drizzle_state_handshake_result_read",
665 "old insecure authentication mechanism not supported");
666 ret= DRIZZLE_RETURN_AUTH_FAILED;
667 }
668 else
669 {
670 con->state.ready= true;
671 }
672 }
673 }
674
675 drizzle_result_free(result);
676
677 if (ret == DRIZZLE_RETURN_ERROR_CODE)
678 {
679 return DRIZZLE_RETURN_HANDSHAKE_FAILED;
680 }
681
682 return ret;
683 }
684