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