~drizzle-trunk/drizzle/development

2472.1.1 by Brian Aker
Formatting, and valgrind cleanups (just mismatch of free/delete).
1
/* vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
2
 *
1712.1.1 by Monty Taylor
Merged libdrizzle directly into tree.
3
 * Drizzle Client & Protocol Library
4
 *
5
 * Copyright (C) 2008 Eric Day (eday@oddments.org)
6
 * All rights reserved.
7
 *
1971.2.1 by kalebral at gmail
update files that did not have license or had incorrect license structure
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
 *
1712.1.1 by Monty Taylor
Merged libdrizzle directly into tree.
36
 */
37
38
/**
39
 * @file
40
 * @brief Handshake Definitions
41
 */
42
2449.1.4 by Brian Aker
Complete update of libdrizzle
43
#include <libdrizzle-1.0/common.h>
1712.1.1 by Monty Taylor
Merged libdrizzle directly into tree.
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
68
  return drizzle_state_loop(con);
69
}
70
71
/*
72
 * Server Definitions
73
 */
74
75
drizzle_return_t drizzle_handshake_server_write(drizzle_con_st *con)
76
{
77
  if (drizzle_state_none(con))
78
  {
79
    drizzle_state_push(con, drizzle_state_write);
80
    drizzle_state_push(con, drizzle_state_handshake_server_write);
81
  }
82
83
  return drizzle_state_loop(con);
84
}
85
86
drizzle_return_t drizzle_handshake_client_read(drizzle_con_st *con)
87
{
88
  if (drizzle_state_none(con))
89
  {
90
    drizzle_state_push(con, drizzle_state_handshake_client_read);
91
    drizzle_state_push(con, drizzle_state_packet_read);
92
  }
93
94
  return drizzle_state_loop(con);
95
}
96
97
/*
98
 * State Definitions
99
 */
100
101
drizzle_return_t drizzle_state_handshake_server_read(drizzle_con_st *con)
102
{
103
  uint8_t *ptr;
1939.2.1 by Evan Jones
Adds protocol support for MySQL 5.5.7
104
  int extra_length;
105
  unsigned char* packet_end;
1712.1.1 by Monty Taylor
Merged libdrizzle directly into tree.
106
107
  drizzle_log_debug(con->drizzle, "drizzle_state_handshake_server_read");
108
109
  /* Assume the entire handshake packet will fit in the buffer. */
110
  if (con->buffer_size < con->packet_size)
111
  {
112
    drizzle_state_push(con, drizzle_state_read);
113
    return DRIZZLE_RETURN_OK;
114
  }
115
116
  if (con->packet_size < 46)
117
  {
118
    drizzle_set_error(con->drizzle, "drizzle_state_handshake_server_read",
119
                      "bad packet size:>=46:%zu", con->packet_size);
120
    return DRIZZLE_RETURN_BAD_HANDSHAKE_PACKET;
121
  }
122
1939.2.2 by Monty Taylor
Cleaned up a minor style violation.
123
  packet_end= con->buffer_ptr + con->packet_size;
1712.1.1 by Monty Taylor
Merged libdrizzle directly into tree.
124
  con->protocol_version= con->buffer_ptr[0];
125
  con->buffer_ptr++;
126
127
  if (con->protocol_version != 10)
128
  {
129
    /* This is a special case where the server determines that authentication
130
       will be impossible and denies any attempt right away. */
131
    if (con->protocol_version == 255)
132
    {
133
      drizzle_set_error(con->drizzle, "drizzle_state_handshake_server_read",
134
                        "%.*s", (int32_t)con->packet_size - 3,
135
                        con->buffer_ptr + 2);
136
      return DRIZZLE_RETURN_AUTH_FAILED;
137
    }
138
139
    drizzle_set_error(con->drizzle, "drizzle_state_handshake_server_read",
140
                      "protocol version not supported:%d",
141
                      con->protocol_version);
142
    return DRIZZLE_RETURN_PROTOCOL_NOT_SUPPORTED;
143
  }
144
145
  /* Look for null-terminated server version string. */
2464.1.2 by Brian Aker
Fix compiling issues for 1.0, and cleanup header files.
146
  ptr= (uint8_t*)memchr(con->buffer_ptr, 0, con->buffer_size - 1);
1712.1.1 by Monty Taylor
Merged libdrizzle directly into tree.
147
  if (ptr == NULL)
148
  {
149
    drizzle_set_error(con->drizzle, "drizzle_state_handshake_server_read",
150
                      "server version string not found");
151
    return DRIZZLE_RETURN_BAD_HANDSHAKE_PACKET;
152
  }
153
1939.2.1 by Evan Jones
Adds protocol support for MySQL 5.5.7
154
  if (con->packet_size < (46 + (size_t)(ptr - con->buffer_ptr)))
1712.1.1 by Monty Taylor
Merged libdrizzle directly into tree.
155
  {
156
    drizzle_set_error(con->drizzle, "drizzle_state_handshake_server_read",
157
                      "bad packet size:%zu:%zu",
158
                      (46 + (size_t)(ptr - con->buffer_ptr)), con->packet_size);
159
    return DRIZZLE_RETURN_BAD_HANDSHAKE_PACKET;
160
  }
161
162
  strncpy(con->server_version, (char *)con->buffer_ptr,
163
          DRIZZLE_MAX_SERVER_VERSION_SIZE);
164
  con->server_version[DRIZZLE_MAX_SERVER_VERSION_SIZE - 1]= 0;
165
  con->buffer_ptr+= ((ptr - con->buffer_ptr) + 1);
166
167
  con->thread_id= (uint32_t)drizzle_get_byte4(con->buffer_ptr);
168
  con->buffer_ptr+= 4;
169
170
  con->scramble= con->scramble_buffer;
171
  memcpy(con->scramble, con->buffer_ptr, 8);
172
  /* Skip scramble and filler. */
173
  con->buffer_ptr+= 9;
174
175
  /* Even though drizzle_capabilities is more than 2 bytes, the protocol only
176
     allows for 2. This means some capabilities are not possible during this
177
     handshake step. The options beyond 2 bytes are for client response only. */
178
  con->capabilities= (drizzle_capabilities_t)drizzle_get_byte2(con->buffer_ptr);
179
  con->buffer_ptr+= 2;
180
181
  if (con->options & DRIZZLE_CON_MYSQL &&
182
      !(con->capabilities & DRIZZLE_CAPABILITIES_PROTOCOL_41))
183
  {
184
    drizzle_set_error(con->drizzle, "drizzle_state_handshake_server_read",
185
                      "protocol version not supported, must be MySQL 4.1+");
186
    return DRIZZLE_RETURN_PROTOCOL_NOT_SUPPORTED;
187
  }
188
189
  con->charset= con->buffer_ptr[0];
190
  con->buffer_ptr+= 1;
191
2464.1.2 by Brian Aker
Fix compiling issues for 1.0, and cleanup header files.
192
  con->status= drizzle_con_status_t(drizzle_get_byte2(con->buffer_ptr));
1712.1.1 by Monty Taylor
Merged libdrizzle directly into tree.
193
  /* Skip status and filler. */
194
  con->buffer_ptr+= 15;
195
196
  memcpy(con->scramble + 8, con->buffer_ptr, 12);
197
  con->buffer_ptr+= 13;
198
1939.2.1 by Evan Jones
Adds protocol support for MySQL 5.5.7
199
  /* MySQL 5.5 adds "mysql_native_password" after the server greeting. */
1939.2.2 by Monty Taylor
Cleaned up a minor style violation.
200
  extra_length= packet_end - con->buffer_ptr;
1939.2.1 by Evan Jones
Adds protocol support for MySQL 5.5.7
201
  assert(extra_length >= 0);
202
  if (extra_length > DRIZZLE_MAX_SERVER_EXTRA_SIZE - 1)
1939.2.2 by Monty Taylor
Cleaned up a minor style violation.
203
    extra_length= DRIZZLE_MAX_SERVER_EXTRA_SIZE - 1;
1939.2.1 by Evan Jones
Adds protocol support for MySQL 5.5.7
204
  memcpy(con->server_extra, (char *)con->buffer_ptr, extra_length);
1939.2.2 by Monty Taylor
Cleaned up a minor style violation.
205
  con->server_extra[extra_length]= 0;
1939.2.1 by Evan Jones
Adds protocol support for MySQL 5.5.7
206
1712.1.1 by Monty Taylor
Merged libdrizzle directly into tree.
207
  con->buffer_size-= con->packet_size;
208
  if (con->buffer_size != 0)
209
  {
210
    drizzle_set_error(con->drizzle, "drizzle_state_handshake_server_read",
211
                      "unexpected data after packet:%zu", con->buffer_size);
212
    return DRIZZLE_RETURN_UNEXPECTED_DATA;
213
  }
214
215
  con->buffer_ptr= con->buffer;
216
217
  drizzle_state_pop(con);
218
219
  if (!(con->options & DRIZZLE_CON_RAW_PACKET))
220
  {
221
    drizzle_state_push(con, drizzle_state_handshake_result_read);
222
    drizzle_state_push(con, drizzle_state_packet_read);
223
    drizzle_state_push(con, drizzle_state_write);
224
    drizzle_state_push(con, drizzle_state_handshake_client_write);
225
  }
226
227
  return DRIZZLE_RETURN_OK;
228
}
229
230
drizzle_return_t drizzle_state_handshake_server_write(drizzle_con_st *con)
231
{
232
  uint8_t *ptr;
233
234
  drizzle_log_debug(con->drizzle, "drizzle_state_handshake_server_write");
235
236
  /* Calculate max packet size. */
237
  con->packet_size= 1   /* Protocol version */
238
                  + strlen(con->server_version) + 1
239
                  + 4   /* Thread ID */
240
                  + 8   /* Scramble */
241
                  + 1   /* NULL */
242
                  + 2   /* Capabilities */
243
                  + 1   /* Language */
244
                  + 2   /* Status */
245
                  + 13  /* Unused */
246
                  + 12  /* Scramble */
247
                  + 1;  /* NULL */
248
249
  /* Assume the entire handshake packet will fit in the buffer. */
250
  if ((con->packet_size + 4) > DRIZZLE_MAX_BUFFER_SIZE)
251
  {
252
    drizzle_set_error(con->drizzle, "drizzle_state_handshake_server_write",
253
                      "buffer too small:%zu", con->packet_size + 4);
254
    return DRIZZLE_RETURN_INTERNAL_ERROR;
255
  }
256
257
  ptr= con->buffer_ptr;
258
259
  /* Store packet size and packet number first. */
260
  drizzle_set_byte3(ptr, con->packet_size);
261
  ptr[3]= 0;
262
  con->packet_number= 1;
263
  ptr+= 4;
264
265
  ptr[0]= con->protocol_version;
266
  ptr++;
267
268
  memcpy(ptr, con->server_version, strlen(con->server_version));
269
  ptr+= strlen(con->server_version);
270
271
  ptr[0]= 0;
272
  ptr++;
273
274
  drizzle_set_byte4(ptr, con->thread_id);
275
  ptr+= 4;
276
277
  if (con->scramble == NULL)
278
    memset(ptr, 0, 8);
279
  else
280
    memcpy(ptr, con->scramble, 8);
281
  ptr+= 8;
282
283
  ptr[0]= 0;
284
  ptr++;
285
286
  if (con->options & DRIZZLE_CON_MYSQL)
287
    con->capabilities|= DRIZZLE_CAPABILITIES_PROTOCOL_41;
288
289
  /* We can only send two bytes worth, this is a protocol limitation. */
290
  drizzle_set_byte2(ptr, con->capabilities);
291
  ptr+= 2;
292
293
  ptr[0]= con->charset;
294
  ptr++;
295
296
  drizzle_set_byte2(ptr, con->status);
297
  ptr+= 2;
298
299
  memset(ptr, 0, 13);
300
  ptr+= 13;
301
302
  if (con->scramble == NULL)
303
    memset(ptr, 0, 12);
304
  else
305
    memcpy(ptr, con->scramble + 8, 12);
306
  ptr+= 12;
307
308
  ptr[0]= 0;
309
  ptr++;
310
311
  con->buffer_size+= (4 + con->packet_size);
312
313
  /* Make sure we packed it correctly. */
314
  if ((size_t)(ptr - con->buffer_ptr) != (4 + con->packet_size))
315
  {
316
    drizzle_set_error(con->drizzle, "drizzle_state_handshake_server_write",
317
                      "error packing server handshake:%zu:%zu",
318
                      (size_t)(ptr - con->buffer_ptr), 4 + con->packet_size);
319
    return DRIZZLE_RETURN_INTERNAL_ERROR;
320
  }
321
322
  drizzle_state_pop(con);
323
  return DRIZZLE_RETURN_OK;
324
}
325
326
drizzle_return_t drizzle_state_handshake_client_read(drizzle_con_st *con)
327
{
328
  size_t real_size;
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. */
2464.1.2 by Brian Aker
Fix compiling issues for 1.0, and cleanup header files.
371
  uint8_t *ptr= (uint8_t*)memchr(con->buffer_ptr, 0, con->buffer_size - 32);
1712.1.1 by Monty Taylor
Merged libdrizzle directly into tree.
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)
2464.1.2 by Brian Aker
Fix compiling issues for 1.0, and cleanup header files.
404
  {
1712.1.1 by Monty Taylor
Merged libdrizzle directly into tree.
405
    con->scramble= NULL;
2464.1.2 by Brian Aker
Fix compiling issues for 1.0, and cleanup header files.
406
  }
1712.1.1 by Monty Taylor
Merged libdrizzle directly into tree.
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
423
  /* Look for null-terminated db string. */
424
  if ((34 + strlen(con->user) + scramble_size) == con->packet_size)
2464.1.2 by Brian Aker
Fix compiling issues for 1.0, and cleanup header files.
425
  {
1712.1.1 by Monty Taylor
Merged libdrizzle directly into tree.
426
    con->db[0]= 0;
2464.1.2 by Brian Aker
Fix compiling issues for 1.0, and cleanup header files.
427
  }
1712.1.1 by Monty Taylor
Merged libdrizzle directly into tree.
428
  else
429
  {
2464.1.2 by Brian Aker
Fix compiling issues for 1.0, and cleanup header files.
430
    ptr= (uint8_t*)memchr(con->buffer_ptr, 0, con->buffer_size -
1992.6.7 by Monty Taylor
Revert -Wc++-compat change.
431
                                    (34 + strlen(con->user) + scramble_size));
1712.1.1 by Monty Taylor
Merged libdrizzle directly into tree.
432
    if (ptr == NULL)
433
    {
434
      drizzle_set_error(con->drizzle, "drizzle_state_handshake_client_read",
435
                        "db string not found");
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
    {
449
      con->db[0]= 0;
450
      con->buffer_ptr++;
451
    }
452
    else
453
    {
454
      strncpy(con->db, (char *)con->buffer_ptr, DRIZZLE_MAX_DB_SIZE);
455
      con->db[DRIZZLE_MAX_DB_SIZE - 1]= 0;
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;
2464.1.2 by Brian Aker
Fix compiling issues for 1.0, and cleanup header files.
477
  int capabilities;
1712.1.1 by Monty Taylor
Merged libdrizzle directly into tree.
478
  drizzle_return_t ret;
479
480
  drizzle_log_debug(con->drizzle, "drizzle_state_handshake_client_write");
481
482
  /* Calculate max packet size. */
483
  con->packet_size= 4   /* Capabilities */
484
                  + 4   /* Max packet size */
485
                  + 1   /* Charset */
486
                  + 23  /* Unused */
487
                  + strlen(con->user) + 1
488
                  + 1   /* Scramble size */
489
                  + DRIZZLE_MAX_SCRAMBLE_SIZE
490
                  + strlen(con->db) + 1;
491
492
  /* Assume the entire handshake packet will fit in the buffer. */
493
  if ((con->packet_size + 4) > DRIZZLE_MAX_BUFFER_SIZE)
494
  {
495
    drizzle_set_error(con->drizzle, "drizzle_state_handshake_client_write",
496
                      "buffer too small:%zu", con->packet_size + 4);
497
    return DRIZZLE_RETURN_INTERNAL_ERROR;
498
  }
499
500
  ptr= con->buffer_ptr;
501
502
  /* Store packet size at the end since it may change. */
503
  ptr[3]= con->packet_number;
504
  con->packet_number++;
505
  ptr+= 4;
506
507
  if (con->options & DRIZZLE_CON_MYSQL)
508
    con->capabilities|= DRIZZLE_CAPABILITIES_PROTOCOL_41;
509
2464.1.2 by Brian Aker
Fix compiling issues for 1.0, and cleanup header files.
510
  capabilities= con->capabilities & int(DRIZZLE_CAPABILITIES_CLIENT);
1712.1.1 by Monty Taylor
Merged libdrizzle directly into tree.
511
  if (!(con->options & DRIZZLE_CON_FOUND_ROWS))
2464.1.2 by Brian Aker
Fix compiling issues for 1.0, and cleanup header files.
512
    capabilities&= ~int(DRIZZLE_CAPABILITIES_FOUND_ROWS);
1712.1.1 by Monty Taylor
Merged libdrizzle directly into tree.
513
2191.1.4 by Brian Aker
Add in interactive mode back to protocol.
514
  if (con->options & DRIZZLE_CON_INTERACTIVE)
515
  {
2464.1.2 by Brian Aker
Fix compiling issues for 1.0, and cleanup header files.
516
    capabilities|= int(DRIZZLE_CAPABILITIES_INTERACTIVE);
2191.1.4 by Brian Aker
Add in interactive mode back to protocol.
517
  }
518
2221.9.1 by Andrew Hutchings
Add DRIZZLE_CON_MULTI_STATEMENTS libdrizzle option to enable DRIZZLE_CAPABILITIES_MULTI_STATEMENTS
519
  if (con->options & DRIZZLE_CON_MULTI_STATEMENTS)
520
  {
2464.1.2 by Brian Aker
Fix compiling issues for 1.0, and cleanup header files.
521
    capabilities|= int(DRIZZLE_CAPABILITIES_MULTI_STATEMENTS);
2221.9.1 by Andrew Hutchings
Add DRIZZLE_CON_MULTI_STATEMENTS libdrizzle option to enable DRIZZLE_CAPABILITIES_MULTI_STATEMENTS
522
  }
523
2203.2.2 by Brian Aker
First pass through in going over work for MySQL AUTH PLUGIN style support.
524
  if (con->options & DRIZZLE_CON_AUTH_PLUGIN)
525
  {
2464.1.2 by Brian Aker
Fix compiling issues for 1.0, and cleanup header files.
526
    capabilities|= int(DRIZZLE_CAPABILITIES_PLUGIN_AUTH);
2203.2.2 by Brian Aker
First pass through in going over work for MySQL AUTH PLUGIN style support.
527
  }
528
2464.1.2 by Brian Aker
Fix compiling issues for 1.0, and cleanup header files.
529
  capabilities&= ~(int(DRIZZLE_CAPABILITIES_COMPRESS) | int(DRIZZLE_CAPABILITIES_SSL));
1712.1.1 by Monty Taylor
Merged libdrizzle directly into tree.
530
  if (con->db[0] == 0)
2464.1.2 by Brian Aker
Fix compiling issues for 1.0, and cleanup header files.
531
    capabilities&= ~int(DRIZZLE_CAPABILITIES_CONNECT_WITH_DB);
1712.1.1 by Monty Taylor
Merged libdrizzle directly into tree.
532
533
  drizzle_set_byte4(ptr, capabilities);
534
  ptr+= 4;
535
536
  drizzle_set_byte4(ptr, con->max_packet_size);
537
  ptr+= 4;
538
539
  ptr[0]= con->charset;
540
  ptr++;
541
542
  memset(ptr, 0, 23);
543
  ptr+= 23;
544
545
  ptr= drizzle_pack_auth(con, ptr, &ret);
546
  if (ret != DRIZZLE_RETURN_OK)
547
    return ret;
548
549
  con->buffer_size+= (4 + con->packet_size);
550
551
  /* Make sure we packed it correctly. */
552
  if ((size_t)(ptr - con->buffer_ptr) != (4 + con->packet_size))
553
  {
554
    drizzle_set_error(con->drizzle, "drizzle_state_handshake_client_write",
555
                      "error packing client handshake:%zu:%zu",
556
                      (size_t)(ptr - con->buffer_ptr), 4 + con->packet_size);
557
    return DRIZZLE_RETURN_INTERNAL_ERROR;
558
  }
559
560
  /* Store packet size now. */
561
  drizzle_set_byte3(con->buffer_ptr, con->packet_size);
562
563
  drizzle_state_pop(con);
564
  return DRIZZLE_RETURN_OK;
565
}
566
567
drizzle_return_t drizzle_state_handshake_result_read(drizzle_con_st *con)
568
{
569
  drizzle_return_t ret;
570
  drizzle_result_st result;
571
572
  drizzle_log_debug(con->drizzle, "drizzle_state_handshake_result_read");
573
574
  if (drizzle_result_create(con, &result) == NULL)
575
    return DRIZZLE_RETURN_MEMORY;
576
577
  con->result= &result;
578
579
  ret= drizzle_state_result_read(con);
580
  if (drizzle_state_none(con))
581
  {
582
    if (ret == DRIZZLE_RETURN_OK)
583
    {
584
      if (drizzle_result_eof(&result))
585
      {
586
        drizzle_set_error(con->drizzle, "drizzle_state_handshake_result_read",
587
                         "old insecure authentication mechanism not supported");
588
        ret= DRIZZLE_RETURN_AUTH_FAILED;
589
      }
590
      else
591
        con->options|= DRIZZLE_CON_READY;
592
    }
593
  }
594
595
  drizzle_result_free(&result);
596
597
  if (ret == DRIZZLE_RETURN_ERROR_CODE)
598
    return DRIZZLE_RETURN_HANDSHAKE_FAILED;
599
600
  return ret;
601
}