Drizzled Public API Documentation

handshake.c
Go to the documentation of this file.
00001 /*
00002  * Drizzle Client & Protocol Library
00003  *
00004  * Copyright (C) 2008 Eric Day (eday@oddments.org)
00005  * All rights reserved.
00006  *
00007  * Redistribution and use in source and binary forms, with or without
00008  * modification, are permitted provided that the following conditions are
00009  * met:
00010  *
00011  *     * Redistributions of source code must retain the above copyright
00012  * notice, this list of conditions and the following disclaimer.
00013  *
00014  *     * Redistributions in binary form must reproduce the above
00015  * copyright notice, this list of conditions and the following disclaimer
00016  * in the documentation and/or other materials provided with the
00017  * distribution.
00018  *
00019  *     * The names of its contributors may not be used to endorse or
00020  * promote products derived from this software without specific prior
00021  * written permission.
00022  *
00023  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
00024  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
00025  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
00026  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
00027  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
00028  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
00029  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
00030  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
00031  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
00032  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
00033  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00034  *
00035  */
00036 
00042 #include "common.h"
00043 
00044 /*
00045  * Client Definitions
00046  */
00047 
00048 drizzle_return_t drizzle_handshake_server_read(drizzle_con_st *con)
00049 {
00050   if (drizzle_state_none(con))
00051   {
00052     drizzle_state_push(con, drizzle_state_handshake_server_read);
00053     drizzle_state_push(con, drizzle_state_packet_read);
00054   }
00055 
00056   return drizzle_state_loop(con);
00057 }
00058 
00059 drizzle_return_t drizzle_handshake_client_write(drizzle_con_st *con)
00060 {
00061   if (drizzle_state_none(con))
00062   {
00063     drizzle_state_push(con, drizzle_state_write);
00064     drizzle_state_push(con, drizzle_state_handshake_client_write);
00065   }
00066 
00067   return drizzle_state_loop(con);
00068 }
00069 
00070 /*
00071  * Server Definitions
00072  */
00073 
00074 drizzle_return_t drizzle_handshake_server_write(drizzle_con_st *con)
00075 {
00076   if (drizzle_state_none(con))
00077   {
00078     drizzle_state_push(con, drizzle_state_write);
00079     drizzle_state_push(con, drizzle_state_handshake_server_write);
00080   }
00081 
00082   return drizzle_state_loop(con);
00083 }
00084 
00085 drizzle_return_t drizzle_handshake_client_read(drizzle_con_st *con)
00086 {
00087   if (drizzle_state_none(con))
00088   {
00089     drizzle_state_push(con, drizzle_state_handshake_client_read);
00090     drizzle_state_push(con, drizzle_state_packet_read);
00091   }
00092 
00093   return drizzle_state_loop(con);
00094 }
00095 
00096 /*
00097  * State Definitions
00098  */
00099 
00100 drizzle_return_t drizzle_state_handshake_server_read(drizzle_con_st *con)
00101 {
00102   uint8_t *ptr;
00103   int extra_length;
00104   unsigned char* packet_end;
00105 
00106   drizzle_log_debug(con->drizzle, "drizzle_state_handshake_server_read");
00107 
00108   /* Assume the entire handshake packet will fit in the buffer. */
00109   if (con->buffer_size < con->packet_size)
00110   {
00111     drizzle_state_push(con, drizzle_state_read);
00112     return DRIZZLE_RETURN_OK;
00113   }
00114 
00115   if (con->packet_size < 46)
00116   {
00117     drizzle_set_error(con->drizzle, "drizzle_state_handshake_server_read",
00118                       "bad packet size:>=46:%zu", con->packet_size);
00119     return DRIZZLE_RETURN_BAD_HANDSHAKE_PACKET;
00120   }
00121 
00122   packet_end= con->buffer_ptr + con->packet_size;
00123   con->protocol_version= con->buffer_ptr[0];
00124   con->buffer_ptr++;
00125 
00126   if (con->protocol_version != 10)
00127   {
00128     /* This is a special case where the server determines that authentication
00129        will be impossible and denies any attempt right away. */
00130     if (con->protocol_version == 255)
00131     {
00132       drizzle_set_error(con->drizzle, "drizzle_state_handshake_server_read",
00133                         "%.*s", (int32_t)con->packet_size - 3,
00134                         con->buffer_ptr + 2);
00135       return DRIZZLE_RETURN_AUTH_FAILED;
00136     }
00137 
00138     drizzle_set_error(con->drizzle, "drizzle_state_handshake_server_read",
00139                       "protocol version not supported:%d",
00140                       con->protocol_version);
00141     return DRIZZLE_RETURN_PROTOCOL_NOT_SUPPORTED;
00142   }
00143 
00144   /* Look for null-terminated server version string. */
00145   ptr= memchr(con->buffer_ptr, 0, con->buffer_size - 1);
00146   if (ptr == NULL)
00147   {
00148     drizzle_set_error(con->drizzle, "drizzle_state_handshake_server_read",
00149                       "server version string not found");
00150     return DRIZZLE_RETURN_BAD_HANDSHAKE_PACKET;
00151   }
00152 
00153   if (con->packet_size < (46 + (size_t)(ptr - con->buffer_ptr)))
00154   {
00155     drizzle_set_error(con->drizzle, "drizzle_state_handshake_server_read",
00156                       "bad packet size:%zu:%zu",
00157                       (46 + (size_t)(ptr - con->buffer_ptr)), con->packet_size);
00158     return DRIZZLE_RETURN_BAD_HANDSHAKE_PACKET;
00159   }
00160 
00161   strncpy(con->server_version, (char *)con->buffer_ptr,
00162           DRIZZLE_MAX_SERVER_VERSION_SIZE);
00163   con->server_version[DRIZZLE_MAX_SERVER_VERSION_SIZE - 1]= 0;
00164   con->buffer_ptr+= ((ptr - con->buffer_ptr) + 1);
00165 
00166   con->thread_id= (uint32_t)drizzle_get_byte4(con->buffer_ptr);
00167   con->buffer_ptr+= 4;
00168 
00169   con->scramble= con->scramble_buffer;
00170   memcpy(con->scramble, con->buffer_ptr, 8);
00171   /* Skip scramble and filler. */
00172   con->buffer_ptr+= 9;
00173 
00174   /* Even though drizzle_capabilities is more than 2 bytes, the protocol only
00175      allows for 2. This means some capabilities are not possible during this
00176      handshake step. The options beyond 2 bytes are for client response only. */
00177   con->capabilities= (drizzle_capabilities_t)drizzle_get_byte2(con->buffer_ptr);
00178   con->buffer_ptr+= 2;
00179 
00180   if (con->options & DRIZZLE_CON_MYSQL &&
00181       !(con->capabilities & DRIZZLE_CAPABILITIES_PROTOCOL_41))
00182   {
00183     drizzle_set_error(con->drizzle, "drizzle_state_handshake_server_read",
00184                       "protocol version not supported, must be MySQL 4.1+");
00185     return DRIZZLE_RETURN_PROTOCOL_NOT_SUPPORTED;
00186   }
00187 
00188   con->charset= con->buffer_ptr[0];
00189   con->buffer_ptr+= 1;
00190 
00191   con->status= drizzle_get_byte2(con->buffer_ptr);
00192   /* Skip status and filler. */
00193   con->buffer_ptr+= 15;
00194 
00195   memcpy(con->scramble + 8, con->buffer_ptr, 12);
00196   con->buffer_ptr+= 13;
00197 
00198   /* MySQL 5.5 adds "mysql_native_password" after the server greeting. */
00199   extra_length= packet_end - con->buffer_ptr;
00200   assert(extra_length >= 0);
00201   if (extra_length > DRIZZLE_MAX_SERVER_EXTRA_SIZE - 1)
00202     extra_length= DRIZZLE_MAX_SERVER_EXTRA_SIZE - 1;
00203   memcpy(con->server_extra, (char *)con->buffer_ptr, extra_length);
00204   con->server_extra[extra_length]= 0;
00205 
00206   con->buffer_size-= con->packet_size;
00207   if (con->buffer_size != 0)
00208   {
00209     drizzle_set_error(con->drizzle, "drizzle_state_handshake_server_read",
00210                       "unexpected data after packet:%zu", con->buffer_size);
00211     return DRIZZLE_RETURN_UNEXPECTED_DATA;
00212   }
00213 
00214   con->buffer_ptr= con->buffer;
00215 
00216   drizzle_state_pop(con);
00217 
00218   if (!(con->options & DRIZZLE_CON_RAW_PACKET))
00219   {
00220     drizzle_state_push(con, drizzle_state_handshake_result_read);
00221     drizzle_state_push(con, drizzle_state_packet_read);
00222     drizzle_state_push(con, drizzle_state_write);
00223     drizzle_state_push(con, drizzle_state_handshake_client_write);
00224   }
00225 
00226   return DRIZZLE_RETURN_OK;
00227 }
00228 
00229 drizzle_return_t drizzle_state_handshake_server_write(drizzle_con_st *con)
00230 {
00231   uint8_t *ptr;
00232 
00233   drizzle_log_debug(con->drizzle, "drizzle_state_handshake_server_write");
00234 
00235   /* Calculate max packet size. */
00236   con->packet_size= 1   /* Protocol version */
00237                   + strlen(con->server_version) + 1
00238                   + 4   /* Thread ID */
00239                   + 8   /* Scramble */
00240                   + 1   /* NULL */
00241                   + 2   /* Capabilities */
00242                   + 1   /* Language */
00243                   + 2   /* Status */
00244                   + 13  /* Unused */
00245                   + 12  /* Scramble */
00246                   + 1;  /* NULL */
00247 
00248   /* Assume the entire handshake packet will fit in the buffer. */
00249   if ((con->packet_size + 4) > DRIZZLE_MAX_BUFFER_SIZE)
00250   {
00251     drizzle_set_error(con->drizzle, "drizzle_state_handshake_server_write",
00252                       "buffer too small:%zu", con->packet_size + 4);
00253     return DRIZZLE_RETURN_INTERNAL_ERROR;
00254   }
00255 
00256   ptr= con->buffer_ptr;
00257 
00258   /* Store packet size and packet number first. */
00259   drizzle_set_byte3(ptr, con->packet_size);
00260   ptr[3]= 0;
00261   con->packet_number= 1;
00262   ptr+= 4;
00263 
00264   ptr[0]= con->protocol_version;
00265   ptr++;
00266 
00267   memcpy(ptr, con->server_version, strlen(con->server_version));
00268   ptr+= strlen(con->server_version);
00269 
00270   ptr[0]= 0;
00271   ptr++;
00272 
00273   drizzle_set_byte4(ptr, con->thread_id);
00274   ptr+= 4;
00275 
00276   if (con->scramble == NULL)
00277     memset(ptr, 0, 8);
00278   else
00279     memcpy(ptr, con->scramble, 8);
00280   ptr+= 8;
00281 
00282   ptr[0]= 0;
00283   ptr++;
00284 
00285   if (con->options & DRIZZLE_CON_MYSQL)
00286     con->capabilities|= DRIZZLE_CAPABILITIES_PROTOCOL_41;
00287 
00288   /* We can only send two bytes worth, this is a protocol limitation. */
00289   drizzle_set_byte2(ptr, con->capabilities);
00290   ptr+= 2;
00291 
00292   ptr[0]= con->charset;
00293   ptr++;
00294 
00295   drizzle_set_byte2(ptr, con->status);
00296   ptr+= 2;
00297 
00298   memset(ptr, 0, 13);
00299   ptr+= 13;
00300 
00301   if (con->scramble == NULL)
00302     memset(ptr, 0, 12);
00303   else
00304     memcpy(ptr, con->scramble + 8, 12);
00305   ptr+= 12;
00306 
00307   ptr[0]= 0;
00308   ptr++;
00309 
00310   con->buffer_size+= (4 + con->packet_size);
00311 
00312   /* Make sure we packed it correctly. */
00313   if ((size_t)(ptr - con->buffer_ptr) != (4 + con->packet_size))
00314   {
00315     drizzle_set_error(con->drizzle, "drizzle_state_handshake_server_write",
00316                       "error packing server handshake:%zu:%zu",
00317                       (size_t)(ptr - con->buffer_ptr), 4 + con->packet_size);
00318     return DRIZZLE_RETURN_INTERNAL_ERROR;
00319   }
00320 
00321   drizzle_state_pop(con);
00322   return DRIZZLE_RETURN_OK;
00323 }
00324 
00325 drizzle_return_t drizzle_state_handshake_client_read(drizzle_con_st *con)
00326 {
00327   size_t real_size;
00328   uint8_t *ptr;
00329   uint8_t scramble_size;
00330 
00331   drizzle_log_debug(con->drizzle, "drizzle_state_handshake_client_read");
00332 
00333   /* Assume the entire handshake packet will fit in the buffer. */
00334   if (con->buffer_size < con->packet_size)
00335   {
00336     drizzle_state_push(con, drizzle_state_read);
00337     return DRIZZLE_RETURN_OK;
00338   }
00339 
00340   /* This is the minimum packet size. */
00341   if (con->packet_size < 34)
00342   {
00343     drizzle_set_error(con->drizzle, "drizzle_state_handshake_client_read",
00344                       "bad packet size:>=34:%zu", con->packet_size);
00345     return DRIZZLE_RETURN_BAD_HANDSHAKE_PACKET;
00346   }
00347 
00348   real_size= 34;
00349 
00350   con->capabilities= drizzle_get_byte4(con->buffer_ptr);
00351   con->buffer_ptr+= 4;
00352 
00353   if (con->options & DRIZZLE_CON_MYSQL &&
00354       !(con->capabilities & DRIZZLE_CAPABILITIES_PROTOCOL_41))
00355   {
00356     drizzle_set_error(con->drizzle, "drizzle_state_handshake_client_read",
00357                       "protocol version not supported, must be MySQL 4.1+");
00358     return DRIZZLE_RETURN_PROTOCOL_NOT_SUPPORTED;
00359   }
00360 
00361   con->max_packet_size= (uint32_t)drizzle_get_byte4(con->buffer_ptr);
00362   con->buffer_ptr+= 4;
00363 
00364   con->charset= con->buffer_ptr[0];
00365   con->buffer_ptr+= 1;
00366 
00367   /* Skip unused. */
00368   con->buffer_ptr+= 23;
00369 
00370   /* Look for null-terminated user string. */
00371   ptr= memchr(con->buffer_ptr, 0, con->buffer_size - 32);
00372   if (ptr == NULL)
00373   {
00374     drizzle_set_error(con->drizzle, "drizzle_state_handshake_client_read",
00375                       "user string not found");
00376     return DRIZZLE_RETURN_BAD_HANDSHAKE_PACKET;
00377   }
00378 
00379   if (con->buffer_ptr == ptr)
00380   {
00381     con->user[0]= 0;
00382     con->buffer_ptr++;
00383   }
00384   else
00385   {
00386     real_size+= (size_t)(ptr - con->buffer_ptr);
00387     if (con->packet_size < real_size)
00388     {
00389       drizzle_set_error(con->drizzle, "drizzle_state_handshake_client_read",
00390                         "bad packet size:>=%zu:%zu", real_size,
00391                         con->packet_size);
00392       return DRIZZLE_RETURN_BAD_HANDSHAKE_PACKET;
00393     }
00394 
00395     strncpy(con->user, (char *)con->buffer_ptr, DRIZZLE_MAX_USER_SIZE);
00396     con->user[DRIZZLE_MAX_USER_SIZE - 1]= 0;
00397     con->buffer_ptr+= ((ptr - con->buffer_ptr) + 1);
00398   }
00399 
00400   scramble_size= con->buffer_ptr[0];
00401   con->buffer_ptr+= 1;
00402 
00403   if (scramble_size == 0)
00404     con->scramble= NULL;
00405   else
00406   {
00407     if (scramble_size != DRIZZLE_MAX_SCRAMBLE_SIZE)
00408     {
00409       drizzle_set_error(con->drizzle, "drizzle_state_handshake_client_read",
00410                         "wrong scramble size");
00411       return DRIZZLE_RETURN_BAD_HANDSHAKE_PACKET;
00412     }
00413 
00414     real_size+= scramble_size;
00415     con->scramble= con->scramble_buffer;
00416     memcpy(con->scramble, con->buffer_ptr, DRIZZLE_MAX_SCRAMBLE_SIZE);
00417 
00418     con->buffer_ptr+= DRIZZLE_MAX_SCRAMBLE_SIZE;
00419   }
00420 
00421   /* Look for null-terminated db string. */
00422   if ((34 + strlen(con->user) + scramble_size) == con->packet_size)
00423     con->db[0]= 0;
00424   else
00425   {
00426     ptr= memchr(con->buffer_ptr, 0, con->buffer_size -
00427                                     (34 + strlen(con->user) + scramble_size));
00428     if (ptr == NULL)
00429     {
00430       drizzle_set_error(con->drizzle, "drizzle_state_handshake_client_read",
00431                         "db string not found");
00432       return DRIZZLE_RETURN_BAD_HANDSHAKE_PACKET;
00433     }
00434 
00435     real_size+= ((size_t)(ptr - con->buffer_ptr) + 1);
00436     if (con->packet_size != real_size)
00437     {
00438       drizzle_set_error(con->drizzle, "drizzle_state_handshake_client_read",
00439                         "bad packet size:%zu:%zu", real_size, con->packet_size);
00440       return DRIZZLE_RETURN_BAD_HANDSHAKE_PACKET;
00441     }
00442 
00443     if (con->buffer_ptr == ptr)
00444     {
00445       con->db[0]= 0;
00446       con->buffer_ptr++;
00447     }
00448     else
00449     {
00450       strncpy(con->db, (char *)con->buffer_ptr, DRIZZLE_MAX_DB_SIZE);
00451       con->db[DRIZZLE_MAX_DB_SIZE - 1]= 0;
00452       con->buffer_ptr+= ((ptr - con->buffer_ptr) + 1);
00453     }
00454   }
00455 
00456   con->buffer_size-= con->packet_size;
00457   if (con->buffer_size != 0)
00458   {
00459     drizzle_set_error(con->drizzle, "drizzle_state_handshake_client_read",
00460                       "unexpected data after packet:%zu", con->buffer_size);
00461     return DRIZZLE_RETURN_UNEXPECTED_DATA;
00462   }
00463 
00464   con->buffer_ptr= con->buffer;
00465 
00466   drizzle_state_pop(con);
00467   return DRIZZLE_RETURN_OK;
00468 }
00469 
00470 drizzle_return_t drizzle_state_handshake_client_write(drizzle_con_st *con)
00471 {
00472   uint8_t *ptr;
00473   drizzle_capabilities_t capabilities;
00474   drizzle_return_t ret;
00475 
00476   drizzle_log_debug(con->drizzle, "drizzle_state_handshake_client_write");
00477 
00478   /* Calculate max packet size. */
00479   con->packet_size= 4   /* Capabilities */
00480                   + 4   /* Max packet size */
00481                   + 1   /* Charset */
00482                   + 23  /* Unused */
00483                   + strlen(con->user) + 1
00484                   + 1   /* Scramble size */
00485                   + DRIZZLE_MAX_SCRAMBLE_SIZE
00486                   + strlen(con->db) + 1;
00487 
00488   /* Assume the entire handshake packet will fit in the buffer. */
00489   if ((con->packet_size + 4) > DRIZZLE_MAX_BUFFER_SIZE)
00490   {
00491     drizzle_set_error(con->drizzle, "drizzle_state_handshake_client_write",
00492                       "buffer too small:%zu", con->packet_size + 4);
00493     return DRIZZLE_RETURN_INTERNAL_ERROR;
00494   }
00495 
00496   ptr= con->buffer_ptr;
00497 
00498   /* Store packet size at the end since it may change. */
00499   ptr[3]= con->packet_number;
00500   con->packet_number++;
00501   ptr+= 4;
00502 
00503   if (con->options & DRIZZLE_CON_MYSQL)
00504     con->capabilities|= DRIZZLE_CAPABILITIES_PROTOCOL_41;
00505 
00506   capabilities= con->capabilities & DRIZZLE_CAPABILITIES_CLIENT;
00507   if (!(con->options & DRIZZLE_CON_FOUND_ROWS))
00508     capabilities&= ~DRIZZLE_CAPABILITIES_FOUND_ROWS;
00509 
00510   if (con->options & DRIZZLE_CON_ADMIN)
00511     capabilities|= DRIZZLE_CAPABILITIES_ADMIN;
00512 
00513   if (con->options & DRIZZLE_CON_INTERACTIVE)
00514   {
00515     capabilities|= DRIZZLE_CAPABILITIES_INTERACTIVE;
00516   }
00517 
00518   if (con->options & DRIZZLE_CON_MULTI_STATEMENTS)
00519   {
00520     capabilities|= DRIZZLE_CAPABILITIES_MULTI_STATEMENTS;
00521   }
00522 
00523   if (con->options & DRIZZLE_CON_AUTH_PLUGIN)
00524   {
00525     capabilities|= DRIZZLE_CAPABILITIES_PLUGIN_AUTH;
00526   }
00527 
00528   capabilities&= ~(DRIZZLE_CAPABILITIES_COMPRESS | DRIZZLE_CAPABILITIES_SSL);
00529   if (con->db[0] == 0)
00530     capabilities&= ~DRIZZLE_CAPABILITIES_CONNECT_WITH_DB;
00531 
00532   drizzle_set_byte4(ptr, capabilities);
00533   ptr+= 4;
00534 
00535   drizzle_set_byte4(ptr, con->max_packet_size);
00536   ptr+= 4;
00537 
00538   ptr[0]= con->charset;
00539   ptr++;
00540 
00541   memset(ptr, 0, 23);
00542   ptr+= 23;
00543 
00544   ptr= drizzle_pack_auth(con, ptr, &ret);
00545   if (ret != DRIZZLE_RETURN_OK)
00546     return ret;
00547 
00548   con->buffer_size+= (4 + con->packet_size);
00549 
00550   /* Make sure we packed it correctly. */
00551   if ((size_t)(ptr - con->buffer_ptr) != (4 + con->packet_size))
00552   {
00553     drizzle_set_error(con->drizzle, "drizzle_state_handshake_client_write",
00554                       "error packing client handshake:%zu:%zu",
00555                       (size_t)(ptr - con->buffer_ptr), 4 + con->packet_size);
00556     return DRIZZLE_RETURN_INTERNAL_ERROR;
00557   }
00558 
00559   /* Store packet size now. */
00560   drizzle_set_byte3(con->buffer_ptr, con->packet_size);
00561 
00562   drizzle_state_pop(con);
00563   return DRIZZLE_RETURN_OK;
00564 }
00565 
00566 drizzle_return_t drizzle_state_handshake_result_read(drizzle_con_st *con)
00567 {
00568   drizzle_return_t ret;
00569   drizzle_result_st result;
00570 
00571   drizzle_log_debug(con->drizzle, "drizzle_state_handshake_result_read");
00572 
00573   if (drizzle_result_create(con, &result) == NULL)
00574     return DRIZZLE_RETURN_MEMORY;
00575 
00576   con->result= &result;
00577 
00578   ret= drizzle_state_result_read(con);
00579   if (drizzle_state_none(con))
00580   {
00581     if (ret == DRIZZLE_RETURN_OK)
00582     {
00583       if (drizzle_result_eof(&result))
00584       {
00585         drizzle_set_error(con->drizzle, "drizzle_state_handshake_result_read",
00586                          "old insecure authentication mechanism not supported");
00587         ret= DRIZZLE_RETURN_AUTH_FAILED;
00588       }
00589       else
00590         con->options|= DRIZZLE_CON_READY;
00591     }
00592   }
00593 
00594   drizzle_result_free(&result);
00595 
00596   if (ret == DRIZZLE_RETURN_ERROR_CODE)
00597     return DRIZZLE_RETURN_HANDSHAKE_FAILED;
00598 
00599   return ret;
00600 }