00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00043 #include <libdrizzle/common.h>
00044
00045
00046
00047
00048
00058 static drizzle_return_t _pack_scramble_hash(drizzle_con_st *con,
00059 uint8_t *buffer);
00060
00063
00064
00065
00066
00067 uint8_t *drizzle_pack_length(uint64_t number, uint8_t *ptr)
00068 {
00069 if (number < 251)
00070 {
00071 ptr[0]= (uint8_t)number;
00072 ptr++;
00073 }
00074 else if (number < 65536)
00075 {
00076 ptr[0]= 252;
00077 ptr++;
00078 drizzle_set_byte2(ptr, number);
00079 ptr+= 2;
00080 }
00081 else if (number < 16777216)
00082 {
00083 ptr[0]= 253;
00084 ptr++;
00085 drizzle_set_byte3(ptr, number);
00086 ptr+= 3;
00087 }
00088 else
00089 {
00090 ptr[0]= 254;
00091 ptr++;
00092 drizzle_set_byte8(ptr, number);
00093 ptr+= 8;
00094 }
00095
00096 return ptr;
00097 }
00098
00099 uint64_t drizzle_unpack_length(drizzle_con_st *con, drizzle_return_t *ret_ptr)
00100 {
00101 uint64_t length;
00102 uint8_t bytes;
00103
00104 drizzle_return_t unused_ret;
00105 if (ret_ptr == NULL)
00106 {
00107 ret_ptr= &unused_ret;
00108 }
00109
00110 if (con == NULL)
00111 {
00112 *ret_ptr= DRIZZLE_RETURN_INVALID_ARGUMENT;
00113 return 0;
00114 }
00115
00116 if (con->buffer_ptr[0] < 251)
00117 {
00118 length= (uint64_t)(con->buffer_ptr[0]);
00119 bytes= 1;
00120 }
00121 else if (con->buffer_ptr[0] == 251)
00122 {
00123 con->buffer_ptr++;
00124 con->buffer_size--;
00125 con->packet_size--;
00126
00127 *ret_ptr= DRIZZLE_RETURN_NULL_SIZE;
00128 return 0;
00129 }
00130 else if (con->buffer_ptr[0] == 252 && con->buffer_size > 2)
00131 {
00132 length= drizzle_get_byte2(con->buffer_ptr + 1);
00133 bytes= 3;
00134 }
00135 else if (con->buffer_ptr[0] == 253 && con->buffer_size > 3)
00136 {
00137 length= drizzle_get_byte3(con->buffer_ptr + 1);
00138 bytes= 4;
00139 }
00140 else if (con->buffer_size > 8)
00141 {
00142 length= drizzle_get_byte8(con->buffer_ptr + 1);
00143 bytes= 9;
00144 }
00145 else
00146 {
00147 *ret_ptr= DRIZZLE_RETURN_IO_WAIT;
00148 return 0;
00149 }
00150
00151 con->buffer_ptr+= bytes;
00152 con->buffer_size-= bytes;
00153 con->packet_size-= bytes;
00154
00155 *ret_ptr= DRIZZLE_RETURN_OK;
00156 return length;
00157 }
00158
00159 uint8_t *drizzle_pack_string(char *string, uint8_t *ptr)
00160 {
00161 if (string == NULL)
00162 {
00163 return NULL;
00164 }
00165
00166 uint64_t size= strlen(string);
00167
00168 ptr= drizzle_pack_length(size, ptr);
00169 if (size > 0)
00170 {
00171 memcpy(ptr, string, (size_t)size);
00172 ptr+= size;
00173 }
00174
00175 return ptr;
00176 }
00177
00178 drizzle_return_t drizzle_unpack_string(drizzle_con_st *con, char *buffer,
00179 uint64_t max_length)
00180 {
00181 drizzle_return_t ret= DRIZZLE_RETURN_OK;
00182
00183 if (con == NULL)
00184 {
00185 return DRIZZLE_RETURN_INVALID_ARGUMENT;
00186 }
00187
00188 uint64_t length= drizzle_unpack_length(con, &ret);
00189 if (ret != DRIZZLE_RETURN_OK)
00190 {
00191 if (ret == DRIZZLE_RETURN_NULL_SIZE)
00192 {
00193 drizzle_set_error(con->drizzle, "drizzle_unpack_string",
00194 "unexpected NULL length");
00195 }
00196
00197 return ret;
00198 }
00199
00200 if (length < max_length)
00201 {
00202 if (length > 0)
00203 memcpy(buffer, con->buffer_ptr, (size_t)length);
00204
00205 buffer[length]= 0;
00206 }
00207 else
00208 {
00209 memcpy(buffer, con->buffer_ptr, (size_t)(max_length - 1));
00210 buffer[max_length - 1]= 0;
00211 }
00212
00213 con->buffer_ptr+= length;
00214 con->buffer_size-= (size_t)length;
00215 con->packet_size-= (size_t)length;
00216
00217 return DRIZZLE_RETURN_OK;
00218 }
00219
00220 uint8_t *drizzle_pack_auth(drizzle_con_st *con, uint8_t *ptr,
00221 drizzle_return_t *ret_ptr)
00222 {
00223 drizzle_return_t unused_ret;
00224 if (ret_ptr == NULL)
00225 {
00226 ret_ptr= &unused_ret;
00227 }
00228
00229 if (con == NULL)
00230 {
00231 *ret_ptr= DRIZZLE_RETURN_INVALID_ARGUMENT;
00232 return NULL;
00233 }
00234
00235 if (con->user[0] != 0)
00236 {
00237 memcpy(ptr, con->user, strlen(con->user));
00238 ptr+= strlen(con->user);
00239 }
00240
00241 ptr[0]= 0;
00242 ptr++;
00243
00244 if (con->options & DRIZZLE_CON_RAW_SCRAMBLE && con->scramble != NULL)
00245 {
00246 ptr[0]= DRIZZLE_MAX_SCRAMBLE_SIZE;
00247 ptr++;
00248
00249 memcpy(ptr, con->scramble, DRIZZLE_MAX_SCRAMBLE_SIZE);
00250 ptr+= DRIZZLE_MAX_SCRAMBLE_SIZE;
00251 }
00252 else if (con->password[0] == 0)
00253 {
00254 ptr[0]= 0;
00255 ptr++;
00256 con->packet_size-= DRIZZLE_MAX_SCRAMBLE_SIZE;
00257 }
00258 else
00259 {
00260 ptr[0]= DRIZZLE_MAX_SCRAMBLE_SIZE;
00261 ptr++;
00262
00263 if (con->options & DRIZZLE_CON_MYSQL && con->options & DRIZZLE_CON_AUTH_PLUGIN)
00264 {
00265 snprintf((char *)ptr, DRIZZLE_MAX_SCRAMBLE_SIZE, "%s", con->password);
00266 ptr[DRIZZLE_MAX_SCRAMBLE_SIZE-1]= 0;
00267 }
00268 else if (con->options & DRIZZLE_CON_MYSQL)
00269 {
00270 *ret_ptr= _pack_scramble_hash(con, ptr);
00271 if (*ret_ptr != DRIZZLE_RETURN_OK)
00272 return ptr;
00273 }
00274 else
00275 {
00276 snprintf((char *)ptr, DRIZZLE_MAX_SCRAMBLE_SIZE, "%s", con->password);
00277 ptr[DRIZZLE_MAX_SCRAMBLE_SIZE-1]= 0;
00278 }
00279
00280 ptr+= DRIZZLE_MAX_SCRAMBLE_SIZE;
00281 }
00282
00283 if (con->db[0] != 0)
00284 {
00285 memcpy(ptr, con->db, strlen(con->db));
00286 ptr+= strlen(con->db);
00287 }
00288
00289 ptr[0]= 0;
00290 ptr++;
00291
00292 *ret_ptr= DRIZZLE_RETURN_OK;
00293 return ptr;
00294 }
00295
00296
00297
00298
00299
00300 static drizzle_return_t _pack_scramble_hash(drizzle_con_st *con,
00301 uint8_t *buffer)
00302 {
00303 SHA1_CTX ctx;
00304 uint8_t hash_tmp1[SHA1_DIGEST_LENGTH];
00305 uint8_t hash_tmp2[SHA1_DIGEST_LENGTH];
00306
00307 if (SHA1_DIGEST_LENGTH != DRIZZLE_MAX_SCRAMBLE_SIZE)
00308 {
00309 drizzle_set_error(con->drizzle, "_pack_scramble_hash",
00310 "SHA1 hash size mismatch:%u:%u", SHA1_DIGEST_LENGTH,
00311 DRIZZLE_MAX_SCRAMBLE_SIZE);
00312 return DRIZZLE_RETURN_INTERNAL_ERROR;
00313 }
00314
00315 if (con->scramble == NULL)
00316 {
00317 drizzle_set_error(con->drizzle, "_pack_scramble_hash",
00318 "no scramble buffer");
00319 return DRIZZLE_RETURN_NO_SCRAMBLE;
00320 }
00321
00322
00323 SHA1Init(&ctx);
00324 SHA1Update(&ctx, (uint8_t *)(con->password), strlen(con->password));
00325 SHA1Final(hash_tmp1, &ctx);
00326
00327
00328 SHA1Init(&ctx);
00329 SHA1Update(&ctx, hash_tmp1, SHA1_DIGEST_LENGTH);
00330 SHA1Final(hash_tmp2, &ctx);
00331
00332
00333 SHA1Init(&ctx);
00334 SHA1Update(&ctx, con->scramble, SHA1_DIGEST_LENGTH);
00335 SHA1Update(&ctx, hash_tmp2, SHA1_DIGEST_LENGTH);
00336 SHA1Final(buffer, &ctx);
00337
00338
00339 uint32_t x;
00340 for (uint32_t x= 0; x < SHA1_DIGEST_LENGTH; x++)
00341 {
00342 buffer[x]= buffer[x] ^ hash_tmp1[x];
00343 }
00344
00345 return DRIZZLE_RETURN_OK;
00346 }