~drizzle-trunk/drizzle/development

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