libdrizzle Developer Documentation

pack.c
Go to the documentation of this file.
1/*
2 * Drizzle Client & Protocol Library
3 *
4 * Copyright (C) 2008 Eric Day (eday@oddments.org)
5 * All rights reserved.
6 *
7 * Use and distribution licensed under the BSD license. See
8 * the COPYING file in this directory for full text.
9 */
10
16#include "common.h"
17
18/*
19 * Private declarations
20 */
21
32 uint8_t *buffer);
33
36/*
37 * Public definitions
38 */
39
40uint8_t *drizzle_pack_length(uint64_t number, uint8_t *ptr)
41{
42 if (number < 251)
43 {
44 ptr[0]= (uint8_t)number;
45 ptr++;
46 }
47 else if (number < 65536)
48 {
49 ptr[0]= 252;
50 ptr++;
51 drizzle_set_byte2(ptr, number);
52 ptr+= 2;
53 }
54 else if (number < 16777216)
55 {
56 ptr[0]= 253;
57 ptr++;
58 drizzle_set_byte3(ptr, number);
59 ptr+= 3;
60 }
61 else
62 {
63 ptr[0]= 254;
64 ptr++;
65 drizzle_set_byte8(ptr, number);
66 ptr+= 8;
67 }
68
69 return ptr;
70}
71
73{
74 uint64_t length;
75 uint8_t bytes;
76
77 if (con->buffer_ptr[0] < 251)
78 {
79 length= (uint64_t)(con->buffer_ptr[0]);
80 bytes= 1;
81 }
82 else if (con->buffer_ptr[0] == 251)
83 {
84 con->buffer_ptr++;
85 con->buffer_size--;
86 con->packet_size--;
87
89 return 0;
90 }
91 else if (con->buffer_ptr[0] == 252 && con->buffer_size > 2)
92 {
93 length= drizzle_get_byte2(con->buffer_ptr + 1);
94 bytes= 3;
95 }
96 else if (con->buffer_ptr[0] == 253 && con->buffer_size > 3)
97 {
98 length= drizzle_get_byte3(con->buffer_ptr + 1);
99 bytes= 4;
100 }
101 else if (con->buffer_size > 8)
102 {
103 length= drizzle_get_byte8(con->buffer_ptr + 1);
104 bytes= 9;
105 }
106 else
107 {
108 *ret_ptr= DRIZZLE_RETURN_IO_WAIT;
109 return 0;
110 }
111
112 con->buffer_ptr+= bytes;
113 con->buffer_size-= bytes;
114 con->packet_size-= bytes;
115
116 *ret_ptr= DRIZZLE_RETURN_OK;
117 return length;
118}
119
120uint8_t *drizzle_pack_string(char *string, uint8_t *ptr)
121{
122 uint64_t size= strlen(string);
123
124 ptr= drizzle_pack_length(size, ptr);
125 if (size > 0)
126 {
127 memcpy(ptr, string, (size_t)size);
128 ptr+= size;
129 }
130
131 return ptr;
132}
133
135 uint64_t max_length)
136{
138 uint64_t length;
139
140 length= drizzle_unpack_length(con, &ret);
141 if (ret != DRIZZLE_RETURN_OK)
142 {
143 if (ret == DRIZZLE_RETURN_NULL_SIZE)
144 {
145 drizzle_set_error(con->drizzle, "drizzle_unpack_string",
146 "unexpected NULL length");
147 }
148
149 return ret;
150 }
151
152 if (length < max_length)
153 {
154 if (length > 0)
155 memcpy(buffer, con->buffer_ptr, (size_t)length);
156
157 buffer[length]= 0;
158 }
159 else
160 {
161 memcpy(buffer, con->buffer_ptr, (size_t)(max_length - 1));
162 buffer[max_length - 1]= 0;
163 }
164
165 con->buffer_ptr+= length;
166 con->buffer_size-= (size_t)length;
167 con->packet_size-= (size_t)length;
168
169 return DRIZZLE_RETURN_OK;
170}
171
172uint8_t *drizzle_pack_auth(drizzle_con_st *con, uint8_t *ptr,
173 drizzle_return_t *ret_ptr)
174{
175 if (con->user[0] != 0)
176 {
177 memcpy(ptr, con->user, strlen(con->user));
178 ptr+= strlen(con->user);
179 }
180
181 ptr[0]= 0;
182 ptr++;
183
184 if (con->options & DRIZZLE_CON_RAW_SCRAMBLE && con->scramble != NULL)
185 {
187 ptr++;
188
189 memcpy(ptr, con->scramble, DRIZZLE_MAX_SCRAMBLE_SIZE);
191 }
192 else if (con->password[0] == 0)
193 {
194 ptr[0]= 0;
195 ptr++;
197 }
198 else
199 {
201 ptr++;
202
203 if (con->options & DRIZZLE_CON_MYSQL)
204 {
205 *ret_ptr= _pack_scramble_hash(con, ptr);
206 if (*ret_ptr != DRIZZLE_RETURN_OK)
207 return ptr;
208 }
209 else
210 snprintf((char *)ptr, DRIZZLE_MAX_SCRAMBLE_SIZE, "%s", con->password);
211
213 }
214
215 if (con->db[0] != 0)
216 {
217 memcpy(ptr, con->db, strlen(con->db));
218 ptr+= strlen(con->db);
219 }
220
221 ptr[0]= 0;
222 ptr++;
223
224 *ret_ptr= DRIZZLE_RETURN_OK;
225 return ptr;
226}
227
228/*
229 * Private definitions
230 */
231
233 uint8_t *buffer)
234{
235 SHA1_CTX ctx;
236 uint8_t hash_tmp1[SHA1_DIGEST_LENGTH];
237 uint8_t hash_tmp2[SHA1_DIGEST_LENGTH];
238 uint32_t x;
239
241 {
242 drizzle_set_error(con->drizzle, "_pack_scramble_hash",
243 "SHA1 hash size mismatch:%u:%u", SHA1_DIGEST_LENGTH,
246 }
247
248 if (con->scramble == NULL)
249 {
250 drizzle_set_error(con->drizzle, "_pack_scramble_hash",
251 "no scramble buffer");
253 }
254
255 /* First hash the password. */
256 SHA1Init(&ctx);
257 SHA1Update(&ctx, (uint8_t *)(con->password), strlen(con->password));
258 SHA1Final(hash_tmp1, &ctx);
259
260 /* Second, hash the password hash. */
261 SHA1Init(&ctx);
262 SHA1Update(&ctx, hash_tmp1, SHA1_DIGEST_LENGTH);
263 SHA1Final(hash_tmp2, &ctx);
264
265 /* Third, hash the scramble and the double password hash. */
266 SHA1Init(&ctx);
268 SHA1Update(&ctx, hash_tmp2, SHA1_DIGEST_LENGTH);
269 SHA1Final(buffer, &ctx);
270
271 /* Fourth, xor the last hash against the first password hash. */
272 for (x= 0; x < SHA1_DIGEST_LENGTH; x++)
273 buffer[x]= buffer[x] ^ hash_tmp1[x];
274
275 return DRIZZLE_RETURN_OK;
276}
System Include Files.
@ DRIZZLE_CON_MYSQL
Definition constants.h:135
@ DRIZZLE_CON_RAW_SCRAMBLE
Definition constants.h:137
#define DRIZZLE_MAX_SCRAMBLE_SIZE
Definition constants.h:58
drizzle_return_t
Definition constants.h:69
@ DRIZZLE_RETURN_OK
Definition constants.h:70
@ DRIZZLE_RETURN_INTERNAL_ERROR
Definition constants.h:76
@ DRIZZLE_RETURN_IO_WAIT
Definition constants.h:71
@ DRIZZLE_RETURN_NULL_SIZE
Definition constants.h:86
@ DRIZZLE_RETURN_NO_SCRAMBLE
Definition constants.h:84
void drizzle_set_error(drizzle_st *drizzle, const char *function, const char *format,...)
Definition drizzle.c:633
#define drizzle_set_byte3(__buffer, __int)
Definition constants.h:478
#define drizzle_get_byte3(__buffer)
Definition constants.h:455
#define drizzle_get_byte2(__buffer)
Definition constants.h:452
#define drizzle_set_byte8(__buffer, __int)
Definition constants.h:487
#define drizzle_get_byte8(__buffer)
Definition constants.h:464
#define drizzle_set_byte2(__buffer, __int)
Definition constants.h:475
static drizzle_return_t _pack_scramble_hash(drizzle_con_st *con, uint8_t *buffer)
Definition pack.c:232
uint8_t * drizzle_pack_length(uint64_t number, uint8_t *ptr)
Definition pack.c:40
uint8_t * drizzle_pack_auth(drizzle_con_st *con, uint8_t *ptr, drizzle_return_t *ret_ptr)
Definition pack.c:172
uint64_t drizzle_unpack_length(drizzle_con_st *con, drizzle_return_t *ret_ptr)
Definition pack.c:72
uint8_t * drizzle_pack_string(char *string, uint8_t *ptr)
Definition pack.c:120
drizzle_return_t drizzle_unpack_string(drizzle_con_st *con, char *buffer, uint64_t max_length)
Definition pack.c:134
#define SHA1_DIGEST_LENGTH
Definition sha1.h:21
void SHA1Init(SHA1_CTX *context)
Definition sha1.c:116
void SHA1Final(uint8_t digest[SHA1_DIGEST_LENGTH], SHA1_CTX *context)
Definition sha1.c:172
void SHA1Update(SHA1_CTX *context, const uint8_t *data, size_t len)
Definition sha1.c:133
drizzle_st * drizzle
Definition structs.h:103
drizzle_con_options_t options
Definition structs.h:84
uint8_t * scramble
Definition structs.h:109
size_t packet_size
Definition structs.h:96
uint8_t * buffer_ptr
Definition structs.h:98
char db[DRIZZLE_MAX_DB_SIZE]
Definition structs.h:116
size_t buffer_size
Definition structs.h:92
char password[DRIZZLE_MAX_PASSWORD_SIZE]
Definition structs.h:117
char user[DRIZZLE_MAX_USER_SIZE]
Definition structs.h:121