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