~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
2478.1.2 by Brian Aker
Fix race condition in bison build, also fix NULL issue on FreeBSD.
43
#include <libdrizzle/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
2472.1.2 by Brian Aker
Null safety fix for libdrizzle
107
  if (con == NULL)
108
  {
109
    return DRIZZLE_RETURN_INVALID_ARGUMENT;
110
  }
1712.1.1 by Monty Taylor
Merged libdrizzle directly into tree.
111
  drizzle_log_debug(con->drizzle, "drizzle_state_handshake_server_read");
112
113
  /* Assume the entire handshake packet will fit in the buffer. */
114
  if (con->buffer_size < con->packet_size)
115
  {
116
    drizzle_state_push(con, drizzle_state_read);
117
    return DRIZZLE_RETURN_OK;
118
  }
119
120
  if (con->packet_size < 46)
121
  {
122
    drizzle_set_error(con->drizzle, "drizzle_state_handshake_server_read",
123
                      "bad packet size:>=46:%zu", con->packet_size);
124
    return DRIZZLE_RETURN_BAD_HANDSHAKE_PACKET;
125
  }
126
1939.2.2 by Monty Taylor
Cleaned up a minor style violation.
127
  packet_end= con->buffer_ptr + con->packet_size;
1712.1.1 by Monty Taylor
Merged libdrizzle directly into tree.
128
  con->protocol_version= con->buffer_ptr[0];
129
  con->buffer_ptr++;
130
131
  if (con->protocol_version != 10)
132
  {
133
    /* This is a special case where the server determines that authentication
134
       will be impossible and denies any attempt right away. */
135
    if (con->protocol_version == 255)
136
    {
137
      drizzle_set_error(con->drizzle, "drizzle_state_handshake_server_read",
138
                        "%.*s", (int32_t)con->packet_size - 3,
139
                        con->buffer_ptr + 2);
140
      return DRIZZLE_RETURN_AUTH_FAILED;
141
    }
142
143
    drizzle_set_error(con->drizzle, "drizzle_state_handshake_server_read",
144
                      "protocol version not supported:%d",
145
                      con->protocol_version);
146
    return DRIZZLE_RETURN_PROTOCOL_NOT_SUPPORTED;
147
  }
148
149
  /* Look for null-terminated server version string. */
2464.1.2 by Brian Aker
Fix compiling issues for 1.0, and cleanup header files.
150
  ptr= (uint8_t*)memchr(con->buffer_ptr, 0, con->buffer_size - 1);
1712.1.1 by Monty Taylor
Merged libdrizzle directly into tree.
151
  if (ptr == NULL)
152
  {
153
    drizzle_set_error(con->drizzle, "drizzle_state_handshake_server_read",
154
                      "server version string not found");
155
    return DRIZZLE_RETURN_BAD_HANDSHAKE_PACKET;
156
  }
157
1939.2.1 by Evan Jones
Adds protocol support for MySQL 5.5.7
158
  if (con->packet_size < (46 + (size_t)(ptr - con->buffer_ptr)))
1712.1.1 by Monty Taylor
Merged libdrizzle directly into tree.
159
  {
160
    drizzle_set_error(con->drizzle, "drizzle_state_handshake_server_read",
161
                      "bad packet size:%zu:%zu",
162
                      (46 + (size_t)(ptr - con->buffer_ptr)), con->packet_size);
163
    return DRIZZLE_RETURN_BAD_HANDSHAKE_PACKET;
164
  }
165
166
  strncpy(con->server_version, (char *)con->buffer_ptr,
167
          DRIZZLE_MAX_SERVER_VERSION_SIZE);
168
  con->server_version[DRIZZLE_MAX_SERVER_VERSION_SIZE - 1]= 0;
169
  con->buffer_ptr+= ((ptr - con->buffer_ptr) + 1);
170
171
  con->thread_id= (uint32_t)drizzle_get_byte4(con->buffer_ptr);
172
  con->buffer_ptr+= 4;
173
174
  con->scramble= con->scramble_buffer;
175
  memcpy(con->scramble, con->buffer_ptr, 8);
176
  /* Skip scramble and filler. */
177
  con->buffer_ptr+= 9;
178
179
  /* Even though drizzle_capabilities is more than 2 bytes, the protocol only
180
     allows for 2. This means some capabilities are not possible during this
181
     handshake step. The options beyond 2 bytes are for client response only. */
182
  con->capabilities= (drizzle_capabilities_t)drizzle_get_byte2(con->buffer_ptr);
183
  con->buffer_ptr+= 2;
184
185
  if (con->options & DRIZZLE_CON_MYSQL &&
186
      !(con->capabilities & DRIZZLE_CAPABILITIES_PROTOCOL_41))
187
  {
188
    drizzle_set_error(con->drizzle, "drizzle_state_handshake_server_read",
189
                      "protocol version not supported, must be MySQL 4.1+");
190
    return DRIZZLE_RETURN_PROTOCOL_NOT_SUPPORTED;
191
  }
192
193
  con->charset= con->buffer_ptr[0];
194
  con->buffer_ptr+= 1;
195
2464.1.2 by Brian Aker
Fix compiling issues for 1.0, and cleanup header files.
196
  con->status= drizzle_con_status_t(drizzle_get_byte2(con->buffer_ptr));
1712.1.1 by Monty Taylor
Merged libdrizzle directly into tree.
197
  /* Skip status and filler. */
198
  con->buffer_ptr+= 15;
199
200
  memcpy(con->scramble + 8, con->buffer_ptr, 12);
201
  con->buffer_ptr+= 13;
202
1939.2.1 by Evan Jones
Adds protocol support for MySQL 5.5.7
203
  /* MySQL 5.5 adds "mysql_native_password" after the server greeting. */
1939.2.2 by Monty Taylor
Cleaned up a minor style violation.
204
  extra_length= packet_end - con->buffer_ptr;
1939.2.1 by Evan Jones
Adds protocol support for MySQL 5.5.7
205
  assert(extra_length >= 0);
206
  if (extra_length > DRIZZLE_MAX_SERVER_EXTRA_SIZE - 1)
1939.2.2 by Monty Taylor
Cleaned up a minor style violation.
207
    extra_length= DRIZZLE_MAX_SERVER_EXTRA_SIZE - 1;
1939.2.1 by Evan Jones
Adds protocol support for MySQL 5.5.7
208
  memcpy(con->server_extra, (char *)con->buffer_ptr, extra_length);
1939.2.2 by Monty Taylor
Cleaned up a minor style violation.
209
  con->server_extra[extra_length]= 0;
1939.2.1 by Evan Jones
Adds protocol support for MySQL 5.5.7
210
1712.1.1 by Monty Taylor
Merged libdrizzle directly into tree.
211
  con->buffer_size-= con->packet_size;
212
  if (con->buffer_size != 0)
213
  {
214
    drizzle_set_error(con->drizzle, "drizzle_state_handshake_server_read",
215
                      "unexpected data after packet:%zu", con->buffer_size);
216
    return DRIZZLE_RETURN_UNEXPECTED_DATA;
217
  }
218
219
  con->buffer_ptr= con->buffer;
220
221
  drizzle_state_pop(con);
222
223
  if (!(con->options & DRIZZLE_CON_RAW_PACKET))
224
  {
225
    drizzle_state_push(con, drizzle_state_handshake_result_read);
226
    drizzle_state_push(con, drizzle_state_packet_read);
227
    drizzle_state_push(con, drizzle_state_write);
228
    drizzle_state_push(con, drizzle_state_handshake_client_write);
229
  }
230
231
  return DRIZZLE_RETURN_OK;
232
}
233
234
drizzle_return_t drizzle_state_handshake_server_write(drizzle_con_st *con)
235
{
236
  uint8_t *ptr;
237
2472.1.2 by Brian Aker
Null safety fix for libdrizzle
238
  if (con == NULL)
239
  {
240
    return DRIZZLE_RETURN_INVALID_ARGUMENT;
241
  }
1712.1.1 by Monty Taylor
Merged libdrizzle directly into tree.
242
  drizzle_log_debug(con->drizzle, "drizzle_state_handshake_server_write");
243
244
  /* Calculate max packet size. */
245
  con->packet_size= 1   /* Protocol version */
246
                  + strlen(con->server_version) + 1
247
                  + 4   /* Thread ID */
248
                  + 8   /* Scramble */
249
                  + 1   /* NULL */
250
                  + 2   /* Capabilities */
251
                  + 1   /* Language */
252
                  + 2   /* Status */
253
                  + 13  /* Unused */
254
                  + 12  /* Scramble */
255
                  + 1;  /* NULL */
256
257
  /* Assume the entire handshake packet will fit in the buffer. */
258
  if ((con->packet_size + 4) > DRIZZLE_MAX_BUFFER_SIZE)
259
  {
260
    drizzle_set_error(con->drizzle, "drizzle_state_handshake_server_write",
261
                      "buffer too small:%zu", con->packet_size + 4);
262
    return DRIZZLE_RETURN_INTERNAL_ERROR;
263
  }
264
265
  ptr= con->buffer_ptr;
266
267
  /* Store packet size and packet number first. */
268
  drizzle_set_byte3(ptr, con->packet_size);
269
  ptr[3]= 0;
270
  con->packet_number= 1;
271
  ptr+= 4;
272
273
  ptr[0]= con->protocol_version;
274
  ptr++;
275
276
  memcpy(ptr, con->server_version, strlen(con->server_version));
277
  ptr+= strlen(con->server_version);
278
279
  ptr[0]= 0;
280
  ptr++;
281
282
  drizzle_set_byte4(ptr, con->thread_id);
283
  ptr+= 4;
284
285
  if (con->scramble == NULL)
2472.1.4 by Brian Aker
Remove memset in case where we are using new()
286
  {
1712.1.1 by Monty Taylor
Merged libdrizzle directly into tree.
287
    memset(ptr, 0, 8);
2472.1.4 by Brian Aker
Remove memset in case where we are using new()
288
  }
1712.1.1 by Monty Taylor
Merged libdrizzle directly into tree.
289
  else
2472.1.4 by Brian Aker
Remove memset in case where we are using new()
290
  {
1712.1.1 by Monty Taylor
Merged libdrizzle directly into tree.
291
    memcpy(ptr, con->scramble, 8);
2472.1.4 by Brian Aker
Remove memset in case where we are using new()
292
  }
1712.1.1 by Monty Taylor
Merged libdrizzle directly into tree.
293
  ptr+= 8;
294
295
  ptr[0]= 0;
296
  ptr++;
297
298
  if (con->options & DRIZZLE_CON_MYSQL)
299
    con->capabilities|= DRIZZLE_CAPABILITIES_PROTOCOL_41;
300
301
  /* We can only send two bytes worth, this is a protocol limitation. */
302
  drizzle_set_byte2(ptr, con->capabilities);
303
  ptr+= 2;
304
305
  ptr[0]= con->charset;
306
  ptr++;
307
308
  drizzle_set_byte2(ptr, con->status);
309
  ptr+= 2;
310
311
  memset(ptr, 0, 13);
312
  ptr+= 13;
313
314
  if (con->scramble == NULL)
2472.1.4 by Brian Aker
Remove memset in case where we are using new()
315
  {
1712.1.1 by Monty Taylor
Merged libdrizzle directly into tree.
316
    memset(ptr, 0, 12);
2472.1.4 by Brian Aker
Remove memset in case where we are using new()
317
  }
1712.1.1 by Monty Taylor
Merged libdrizzle directly into tree.
318
  else
2472.1.4 by Brian Aker
Remove memset in case where we are using new()
319
  {
1712.1.1 by Monty Taylor
Merged libdrizzle directly into tree.
320
    memcpy(ptr, con->scramble + 8, 12);
2472.1.4 by Brian Aker
Remove memset in case where we are using new()
321
  }
1712.1.1 by Monty Taylor
Merged libdrizzle directly into tree.
322
  ptr+= 12;
323
324
  ptr[0]= 0;
325
  ptr++;
326
327
  con->buffer_size+= (4 + con->packet_size);
328
329
  /* Make sure we packed it correctly. */
330
  if ((size_t)(ptr - con->buffer_ptr) != (4 + con->packet_size))
331
  {
332
    drizzle_set_error(con->drizzle, "drizzle_state_handshake_server_write",
333
                      "error packing server handshake:%zu:%zu",
334
                      (size_t)(ptr - con->buffer_ptr), 4 + con->packet_size);
335
    return DRIZZLE_RETURN_INTERNAL_ERROR;
336
  }
337
338
  drizzle_state_pop(con);
339
  return DRIZZLE_RETURN_OK;
340
}
341
342
drizzle_return_t drizzle_state_handshake_client_read(drizzle_con_st *con)
343
{
344
  size_t real_size;
345
  uint8_t scramble_size;
346
2472.1.2 by Brian Aker
Null safety fix for libdrizzle
347
  if (con == NULL)
348
  {
349
    return DRIZZLE_RETURN_INVALID_ARGUMENT;
350
  }
1712.1.1 by Monty Taylor
Merged libdrizzle directly into tree.
351
  drizzle_log_debug(con->drizzle, "drizzle_state_handshake_client_read");
352
353
  /* Assume the entire handshake packet will fit in the buffer. */
354
  if (con->buffer_size < con->packet_size)
355
  {
356
    drizzle_state_push(con, drizzle_state_read);
357
    return DRIZZLE_RETURN_OK;
358
  }
359
360
  /* This is the minimum packet size. */
361
  if (con->packet_size < 34)
362
  {
363
    drizzle_set_error(con->drizzle, "drizzle_state_handshake_client_read",
364
                      "bad packet size:>=34:%zu", con->packet_size);
365
    return DRIZZLE_RETURN_BAD_HANDSHAKE_PACKET;
366
  }
367
368
  real_size= 34;
369
370
  con->capabilities= drizzle_get_byte4(con->buffer_ptr);
371
  con->buffer_ptr+= 4;
372
373
  if (con->options & DRIZZLE_CON_MYSQL &&
374
      !(con->capabilities & DRIZZLE_CAPABILITIES_PROTOCOL_41))
375
  {
376
    drizzle_set_error(con->drizzle, "drizzle_state_handshake_client_read",
377
                      "protocol version not supported, must be MySQL 4.1+");
378
    return DRIZZLE_RETURN_PROTOCOL_NOT_SUPPORTED;
379
  }
380
381
  con->max_packet_size= (uint32_t)drizzle_get_byte4(con->buffer_ptr);
382
  con->buffer_ptr+= 4;
383
384
  con->charset= con->buffer_ptr[0];
385
  con->buffer_ptr+= 1;
386
387
  /* Skip unused. */
388
  con->buffer_ptr+= 23;
389
390
  /* Look for null-terminated user string. */
2464.1.2 by Brian Aker
Fix compiling issues for 1.0, and cleanup header files.
391
  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.
392
  if (ptr == NULL)
393
  {
394
    drizzle_set_error(con->drizzle, "drizzle_state_handshake_client_read",
395
                      "user string not found");
396
    return DRIZZLE_RETURN_BAD_HANDSHAKE_PACKET;
397
  }
398
399
  if (con->buffer_ptr == ptr)
400
  {
401
    con->user[0]= 0;
402
    con->buffer_ptr++;
403
  }
404
  else
405
  {
406
    real_size+= (size_t)(ptr - con->buffer_ptr);
407
    if (con->packet_size < real_size)
408
    {
409
      drizzle_set_error(con->drizzle, "drizzle_state_handshake_client_read",
410
                        "bad packet size:>=%zu:%zu", real_size,
411
                        con->packet_size);
412
      return DRIZZLE_RETURN_BAD_HANDSHAKE_PACKET;
413
    }
414
415
    strncpy(con->user, (char *)con->buffer_ptr, DRIZZLE_MAX_USER_SIZE);
416
    con->user[DRIZZLE_MAX_USER_SIZE - 1]= 0;
417
    con->buffer_ptr+= ((ptr - con->buffer_ptr) + 1);
418
  }
419
420
  scramble_size= con->buffer_ptr[0];
421
  con->buffer_ptr+= 1;
422
423
  if (scramble_size == 0)
2464.1.2 by Brian Aker
Fix compiling issues for 1.0, and cleanup header files.
424
  {
1712.1.1 by Monty Taylor
Merged libdrizzle directly into tree.
425
    con->scramble= NULL;
2464.1.2 by Brian Aker
Fix compiling issues for 1.0, and cleanup header files.
426
  }
1712.1.1 by Monty Taylor
Merged libdrizzle directly into tree.
427
  else
428
  {
429
    if (scramble_size != DRIZZLE_MAX_SCRAMBLE_SIZE)
430
    {
431
      drizzle_set_error(con->drizzle, "drizzle_state_handshake_client_read",
432
                        "wrong scramble size");
433
      return DRIZZLE_RETURN_BAD_HANDSHAKE_PACKET;
434
    }
435
436
    real_size+= scramble_size;
437
    con->scramble= con->scramble_buffer;
438
    memcpy(con->scramble, con->buffer_ptr, DRIZZLE_MAX_SCRAMBLE_SIZE);
439
440
    con->buffer_ptr+= DRIZZLE_MAX_SCRAMBLE_SIZE;
441
  }
442
443
  /* Look for null-terminated db string. */
444
  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.
445
  {
1712.1.1 by Monty Taylor
Merged libdrizzle directly into tree.
446
    con->db[0]= 0;
2464.1.2 by Brian Aker
Fix compiling issues for 1.0, and cleanup header files.
447
  }
1712.1.1 by Monty Taylor
Merged libdrizzle directly into tree.
448
  else
449
  {
2464.1.2 by Brian Aker
Fix compiling issues for 1.0, and cleanup header files.
450
    ptr= (uint8_t*)memchr(con->buffer_ptr, 0, con->buffer_size -
1992.6.7 by Monty Taylor
Revert -Wc++-compat change.
451
                                    (34 + strlen(con->user) + scramble_size));
1712.1.1 by Monty Taylor
Merged libdrizzle directly into tree.
452
    if (ptr == NULL)
453
    {
454
      drizzle_set_error(con->drizzle, "drizzle_state_handshake_client_read",
455
                        "db string not found");
456
      return DRIZZLE_RETURN_BAD_HANDSHAKE_PACKET;
457
    }
458
459
    real_size+= ((size_t)(ptr - con->buffer_ptr) + 1);
460
    if (con->packet_size != real_size)
461
    {
462
      drizzle_set_error(con->drizzle, "drizzle_state_handshake_client_read",
463
                        "bad packet size:%zu:%zu", real_size, con->packet_size);
464
      return DRIZZLE_RETURN_BAD_HANDSHAKE_PACKET;
465
    }
466
467
    if (con->buffer_ptr == ptr)
468
    {
469
      con->db[0]= 0;
470
      con->buffer_ptr++;
471
    }
472
    else
473
    {
474
      strncpy(con->db, (char *)con->buffer_ptr, DRIZZLE_MAX_DB_SIZE);
475
      con->db[DRIZZLE_MAX_DB_SIZE - 1]= 0;
476
      con->buffer_ptr+= ((ptr - con->buffer_ptr) + 1);
477
    }
478
  }
479
480
  con->buffer_size-= con->packet_size;
481
  if (con->buffer_size != 0)
482
  {
483
    drizzle_set_error(con->drizzle, "drizzle_state_handshake_client_read",
484
                      "unexpected data after packet:%zu", con->buffer_size);
485
    return DRIZZLE_RETURN_UNEXPECTED_DATA;
486
  }
487
488
  con->buffer_ptr= con->buffer;
489
490
  drizzle_state_pop(con);
491
  return DRIZZLE_RETURN_OK;
492
}
493
494
drizzle_return_t drizzle_state_handshake_client_write(drizzle_con_st *con)
495
{
496
  uint8_t *ptr;
2464.1.2 by Brian Aker
Fix compiling issues for 1.0, and cleanup header files.
497
  int capabilities;
1712.1.1 by Monty Taylor
Merged libdrizzle directly into tree.
498
  drizzle_return_t ret;
499
2472.1.2 by Brian Aker
Null safety fix for libdrizzle
500
  if (con == NULL)
501
  {
502
    return DRIZZLE_RETURN_INVALID_ARGUMENT;
503
  }
1712.1.1 by Monty Taylor
Merged libdrizzle directly into tree.
504
  drizzle_log_debug(con->drizzle, "drizzle_state_handshake_client_write");
505
506
  /* Calculate max packet size. */
507
  con->packet_size= 4   /* Capabilities */
508
                  + 4   /* Max packet size */
509
                  + 1   /* Charset */
510
                  + 23  /* Unused */
511
                  + strlen(con->user) + 1
512
                  + 1   /* Scramble size */
513
                  + DRIZZLE_MAX_SCRAMBLE_SIZE
514
                  + strlen(con->db) + 1;
515
516
  /* Assume the entire handshake packet will fit in the buffer. */
517
  if ((con->packet_size + 4) > DRIZZLE_MAX_BUFFER_SIZE)
518
  {
519
    drizzle_set_error(con->drizzle, "drizzle_state_handshake_client_write",
520
                      "buffer too small:%zu", con->packet_size + 4);
521
    return DRIZZLE_RETURN_INTERNAL_ERROR;
522
  }
523
524
  ptr= con->buffer_ptr;
525
526
  /* Store packet size at the end since it may change. */
527
  ptr[3]= con->packet_number;
528
  con->packet_number++;
529
  ptr+= 4;
530
531
  if (con->options & DRIZZLE_CON_MYSQL)
532
    con->capabilities|= DRIZZLE_CAPABILITIES_PROTOCOL_41;
533
2464.1.2 by Brian Aker
Fix compiling issues for 1.0, and cleanup header files.
534
  capabilities= con->capabilities & int(DRIZZLE_CAPABILITIES_CLIENT);
1712.1.1 by Monty Taylor
Merged libdrizzle directly into tree.
535
  if (!(con->options & DRIZZLE_CON_FOUND_ROWS))
2464.1.2 by Brian Aker
Fix compiling issues for 1.0, and cleanup header files.
536
    capabilities&= ~int(DRIZZLE_CAPABILITIES_FOUND_ROWS);
1712.1.1 by Monty Taylor
Merged libdrizzle directly into tree.
537
2191.1.4 by Brian Aker
Add in interactive mode back to protocol.
538
  if (con->options & DRIZZLE_CON_INTERACTIVE)
539
  {
2464.1.2 by Brian Aker
Fix compiling issues for 1.0, and cleanup header files.
540
    capabilities|= int(DRIZZLE_CAPABILITIES_INTERACTIVE);
2191.1.4 by Brian Aker
Add in interactive mode back to protocol.
541
  }
542
2221.9.1 by Andrew Hutchings
Add DRIZZLE_CON_MULTI_STATEMENTS libdrizzle option to enable DRIZZLE_CAPABILITIES_MULTI_STATEMENTS
543
  if (con->options & DRIZZLE_CON_MULTI_STATEMENTS)
544
  {
2464.1.2 by Brian Aker
Fix compiling issues for 1.0, and cleanup header files.
545
    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
546
  }
547
2203.2.2 by Brian Aker
First pass through in going over work for MySQL AUTH PLUGIN style support.
548
  if (con->options & DRIZZLE_CON_AUTH_PLUGIN)
549
  {
2464.1.2 by Brian Aker
Fix compiling issues for 1.0, and cleanup header files.
550
    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.
551
  }
552
2464.1.2 by Brian Aker
Fix compiling issues for 1.0, and cleanup header files.
553
  capabilities&= ~(int(DRIZZLE_CAPABILITIES_COMPRESS) | int(DRIZZLE_CAPABILITIES_SSL));
1712.1.1 by Monty Taylor
Merged libdrizzle directly into tree.
554
  if (con->db[0] == 0)
2464.1.2 by Brian Aker
Fix compiling issues for 1.0, and cleanup header files.
555
    capabilities&= ~int(DRIZZLE_CAPABILITIES_CONNECT_WITH_DB);
1712.1.1 by Monty Taylor
Merged libdrizzle directly into tree.
556
557
  drizzle_set_byte4(ptr, capabilities);
558
  ptr+= 4;
559
560
  drizzle_set_byte4(ptr, con->max_packet_size);
561
  ptr+= 4;
562
563
  ptr[0]= con->charset;
564
  ptr++;
565
566
  memset(ptr, 0, 23);
567
  ptr+= 23;
568
569
  ptr= drizzle_pack_auth(con, ptr, &ret);
570
  if (ret != DRIZZLE_RETURN_OK)
571
    return ret;
572
573
  con->buffer_size+= (4 + con->packet_size);
574
575
  /* Make sure we packed it correctly. */
576
  if ((size_t)(ptr - con->buffer_ptr) != (4 + con->packet_size))
577
  {
578
    drizzle_set_error(con->drizzle, "drizzle_state_handshake_client_write",
579
                      "error packing client handshake:%zu:%zu",
580
                      (size_t)(ptr - con->buffer_ptr), 4 + con->packet_size);
581
    return DRIZZLE_RETURN_INTERNAL_ERROR;
582
  }
583
584
  /* Store packet size now. */
585
  drizzle_set_byte3(con->buffer_ptr, con->packet_size);
586
587
  drizzle_state_pop(con);
588
  return DRIZZLE_RETURN_OK;
589
}
590
591
drizzle_return_t drizzle_state_handshake_result_read(drizzle_con_st *con)
592
{
2472.1.2 by Brian Aker
Null safety fix for libdrizzle
593
  if (con == NULL)
594
  {
595
    return DRIZZLE_RETURN_INVALID_ARGUMENT;
596
  }
597
  drizzle_log_debug(con->drizzle, "drizzle_state_handshake_result_read");
598
1712.1.1 by Monty Taylor
Merged libdrizzle directly into tree.
599
  drizzle_result_st result;
600
  if (drizzle_result_create(con, &result) == NULL)
2472.1.2 by Brian Aker
Null safety fix for libdrizzle
601
  {
1712.1.1 by Monty Taylor
Merged libdrizzle directly into tree.
602
    return DRIZZLE_RETURN_MEMORY;
2472.1.2 by Brian Aker
Null safety fix for libdrizzle
603
  }
1712.1.1 by Monty Taylor
Merged libdrizzle directly into tree.
604
605
  con->result= &result;
606
2472.1.2 by Brian Aker
Null safety fix for libdrizzle
607
  drizzle_return_t ret= drizzle_state_result_read(con);
1712.1.1 by Monty Taylor
Merged libdrizzle directly into tree.
608
  if (drizzle_state_none(con))
609
  {
610
    if (ret == DRIZZLE_RETURN_OK)
611
    {
612
      if (drizzle_result_eof(&result))
613
      {
614
        drizzle_set_error(con->drizzle, "drizzle_state_handshake_result_read",
615
                         "old insecure authentication mechanism not supported");
616
        ret= DRIZZLE_RETURN_AUTH_FAILED;
617
      }
618
      else
2472.1.2 by Brian Aker
Null safety fix for libdrizzle
619
      {
1712.1.1 by Monty Taylor
Merged libdrizzle directly into tree.
620
        con->options|= DRIZZLE_CON_READY;
2472.1.2 by Brian Aker
Null safety fix for libdrizzle
621
      }
1712.1.1 by Monty Taylor
Merged libdrizzle directly into tree.
622
    }
623
  }
624
625
  drizzle_result_free(&result);
626
627
  if (ret == DRIZZLE_RETURN_ERROR_CODE)
2472.1.2 by Brian Aker
Null safety fix for libdrizzle
628
  {
1712.1.1 by Monty Taylor
Merged libdrizzle directly into tree.
629
    return DRIZZLE_RETURN_HANDSHAKE_FAILED;
2472.1.2 by Brian Aker
Null safety fix for libdrizzle
630
  }
1712.1.1 by Monty Taylor
Merged libdrizzle directly into tree.
631
632
  return ret;
633
}