Drizzled Public API Documentation

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