~ubuntu-branches/ubuntu/saucy/drizzle/saucy-proposed

« back to all changes in this revision

Viewing changes to libdrizzle/handshake.c

  • Committer: Package Import Robot
  • Author(s): Clint Byrum
  • Date: 2012-06-19 10:46:49 UTC
  • mfrom: (1.1.6)
  • mto: This revision was merged to the branch mainline in revision 29.
  • Revision ID: package-import@ubuntu.com-20120619104649-e2l0ggd4oz3um0f4
Tags: upstream-7.1.36-stable
ImportĀ upstreamĀ versionĀ 7.1.36-stable

Show diffs side-by-side

added added

removed removed

Lines of Context:
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
 
 
42
 
#include "common.h"
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= 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_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= 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)
404
 
    con->scramble= NULL;
405
 
  else
406
 
  {
407
 
    if (scramble_size != DRIZZLE_MAX_SCRAMBLE_SIZE)
408
 
    {
409
 
      drizzle_set_error(con->drizzle, "drizzle_state_handshake_client_read",
410
 
                        "wrong scramble size");
411
 
      return DRIZZLE_RETURN_BAD_HANDSHAKE_PACKET;
412
 
    }
413
 
 
414
 
    real_size+= scramble_size;
415
 
    con->scramble= con->scramble_buffer;
416
 
    memcpy(con->scramble, con->buffer_ptr, DRIZZLE_MAX_SCRAMBLE_SIZE);
417
 
 
418
 
    con->buffer_ptr+= DRIZZLE_MAX_SCRAMBLE_SIZE;
419
 
  }
420
 
 
421
 
  /* Look for null-terminated db string. */
422
 
  if ((34 + strlen(con->user) + scramble_size) == con->packet_size)
423
 
    con->db[0]= 0;
424
 
  else
425
 
  {
426
 
    ptr= memchr(con->buffer_ptr, 0, con->buffer_size -
427
 
                                    (34 + strlen(con->user) + scramble_size));
428
 
    if (ptr == NULL)
429
 
    {
430
 
      drizzle_set_error(con->drizzle, "drizzle_state_handshake_client_read",
431
 
                        "db string not found");
432
 
      return DRIZZLE_RETURN_BAD_HANDSHAKE_PACKET;
433
 
    }
434
 
 
435
 
    real_size+= ((size_t)(ptr - con->buffer_ptr) + 1);
436
 
    if (con->packet_size != real_size)
437
 
    {
438
 
      drizzle_set_error(con->drizzle, "drizzle_state_handshake_client_read",
439
 
                        "bad packet size:%zu:%zu", real_size, con->packet_size);
440
 
      return DRIZZLE_RETURN_BAD_HANDSHAKE_PACKET;
441
 
    }
442
 
 
443
 
    if (con->buffer_ptr == ptr)
444
 
    {
445
 
      con->db[0]= 0;
446
 
      con->buffer_ptr++;
447
 
    }
448
 
    else
449
 
    {
450
 
      strncpy(con->db, (char *)con->buffer_ptr, DRIZZLE_MAX_DB_SIZE);
451
 
      con->db[DRIZZLE_MAX_DB_SIZE - 1]= 0;
452
 
      con->buffer_ptr+= ((ptr - con->buffer_ptr) + 1);
453
 
    }
454
 
  }
455
 
 
456
 
  con->buffer_size-= con->packet_size;
457
 
  if (con->buffer_size != 0)
458
 
  {
459
 
    drizzle_set_error(con->drizzle, "drizzle_state_handshake_client_read",
460
 
                      "unexpected data after packet:%zu", con->buffer_size);
461
 
    return DRIZZLE_RETURN_UNEXPECTED_DATA;
462
 
  }
463
 
 
464
 
  con->buffer_ptr= con->buffer;
465
 
 
466
 
  drizzle_state_pop(con);
467
 
  return DRIZZLE_RETURN_OK;
468
 
}
469
 
 
470
 
drizzle_return_t drizzle_state_handshake_client_write(drizzle_con_st *con)
471
 
{
472
 
  uint8_t *ptr;
473
 
  drizzle_capabilities_t capabilities;
474
 
  drizzle_return_t ret;
475
 
 
476
 
  drizzle_log_debug(con->drizzle, "drizzle_state_handshake_client_write");
477
 
 
478
 
  /* Calculate max packet size. */
479
 
  con->packet_size= 4   /* Capabilities */
480
 
                  + 4   /* Max packet size */
481
 
                  + 1   /* Charset */
482
 
                  + 23  /* Unused */
483
 
                  + strlen(con->user) + 1
484
 
                  + 1   /* Scramble size */
485
 
                  + DRIZZLE_MAX_SCRAMBLE_SIZE
486
 
                  + strlen(con->db) + 1;
487
 
 
488
 
  /* Assume the entire handshake packet will fit in the buffer. */
489
 
  if ((con->packet_size + 4) > DRIZZLE_MAX_BUFFER_SIZE)
490
 
  {
491
 
    drizzle_set_error(con->drizzle, "drizzle_state_handshake_client_write",
492
 
                      "buffer too small:%zu", con->packet_size + 4);
493
 
    return DRIZZLE_RETURN_INTERNAL_ERROR;
494
 
  }
495
 
 
496
 
  ptr= con->buffer_ptr;
497
 
 
498
 
  /* Store packet size at the end since it may change. */
499
 
  ptr[3]= con->packet_number;
500
 
  con->packet_number++;
501
 
  ptr+= 4;
502
 
 
503
 
  if (con->options & DRIZZLE_CON_MYSQL)
504
 
    con->capabilities|= DRIZZLE_CAPABILITIES_PROTOCOL_41;
505
 
 
506
 
  capabilities= con->capabilities & DRIZZLE_CAPABILITIES_CLIENT;
507
 
  if (!(con->options & DRIZZLE_CON_FOUND_ROWS))
508
 
    capabilities&= ~DRIZZLE_CAPABILITIES_FOUND_ROWS;
509
 
 
510
 
  if (con->options & DRIZZLE_CON_ADMIN)
511
 
    capabilities|= DRIZZLE_CAPABILITIES_ADMIN;
512
 
 
513
 
  if (con->options & DRIZZLE_CON_INTERACTIVE)
514
 
  {
515
 
    capabilities|= DRIZZLE_CAPABILITIES_INTERACTIVE;
516
 
  }
517
 
 
518
 
  if (con->options & DRIZZLE_CON_MULTI_STATEMENTS)
519
 
  {
520
 
    capabilities|= DRIZZLE_CAPABILITIES_MULTI_STATEMENTS;
521
 
  }
522
 
 
523
 
  if (con->options & DRIZZLE_CON_AUTH_PLUGIN)
524
 
  {
525
 
    capabilities|= DRIZZLE_CAPABILITIES_PLUGIN_AUTH;
526
 
  }
527
 
 
528
 
  capabilities&= ~(DRIZZLE_CAPABILITIES_COMPRESS | DRIZZLE_CAPABILITIES_SSL);
529
 
  if (con->db[0] == 0)
530
 
    capabilities&= ~DRIZZLE_CAPABILITIES_CONNECT_WITH_DB;
531
 
 
532
 
  drizzle_set_byte4(ptr, capabilities);
533
 
  ptr+= 4;
534
 
 
535
 
  drizzle_set_byte4(ptr, con->max_packet_size);
536
 
  ptr+= 4;
537
 
 
538
 
  ptr[0]= con->charset;
539
 
  ptr++;
540
 
 
541
 
  memset(ptr, 0, 23);
542
 
  ptr+= 23;
543
 
 
544
 
  ptr= drizzle_pack_auth(con, ptr, &ret);
545
 
  if (ret != DRIZZLE_RETURN_OK)
546
 
    return ret;
547
 
 
548
 
  con->buffer_size+= (4 + con->packet_size);
549
 
 
550
 
  /* Make sure we packed it correctly. */
551
 
  if ((size_t)(ptr - con->buffer_ptr) != (4 + con->packet_size))
552
 
  {
553
 
    drizzle_set_error(con->drizzle, "drizzle_state_handshake_client_write",
554
 
                      "error packing client handshake:%zu:%zu",
555
 
                      (size_t)(ptr - con->buffer_ptr), 4 + con->packet_size);
556
 
    return DRIZZLE_RETURN_INTERNAL_ERROR;
557
 
  }
558
 
 
559
 
  /* Store packet size now. */
560
 
  drizzle_set_byte3(con->buffer_ptr, con->packet_size);
561
 
 
562
 
  drizzle_state_pop(con);
563
 
  return DRIZZLE_RETURN_OK;
564
 
}
565
 
 
566
 
drizzle_return_t drizzle_state_handshake_result_read(drizzle_con_st *con)
567
 
{
568
 
  drizzle_return_t ret;
569
 
  drizzle_result_st result;
570
 
 
571
 
  drizzle_log_debug(con->drizzle, "drizzle_state_handshake_result_read");
572
 
 
573
 
  if (drizzle_result_create(con, &result) == NULL)
574
 
    return DRIZZLE_RETURN_MEMORY;
575
 
 
576
 
  con->result= &result;
577
 
 
578
 
  ret= drizzle_state_result_read(con);
579
 
  if (drizzle_state_none(con))
580
 
  {
581
 
    if (ret == DRIZZLE_RETURN_OK)
582
 
    {
583
 
      if (drizzle_result_eof(&result))
584
 
      {
585
 
        drizzle_set_error(con->drizzle, "drizzle_state_handshake_result_read",
586
 
                         "old insecure authentication mechanism not supported");
587
 
        ret= DRIZZLE_RETURN_AUTH_FAILED;
588
 
      }
589
 
      else
590
 
        con->options|= DRIZZLE_CON_READY;
591
 
    }
592
 
  }
593
 
 
594
 
  drizzle_result_free(&result);
595
 
 
596
 
  if (ret == DRIZZLE_RETURN_ERROR_CODE)
597
 
    return DRIZZLE_RETURN_HANDSHAKE_FAILED;
598
 
 
599
 
  return ret;
600
 
}