00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #ifdef HAVE_CONFIG_H
00024 # include "config.h"
00025 #endif
00026
00027
00028 #include "parser.h"
00029
00030
00031 #include <stdlib.h>
00032
00033
00034 #include <string.h>
00035
00036
00037 #include "validate.h"
00038
00039
00040 #include "c-ctype.h"
00041
00042 static char *
00043 unescape (const char *str, size_t len)
00044 {
00045 char *out = malloc (len + 1);
00046 char *p = out;
00047
00048 if (!out)
00049 return NULL;
00050
00051 while (len > 0 && *str)
00052 {
00053 if (len >= 3 && str[0] == '=' && str[1] == '2' && str[2] == 'C')
00054 {
00055 *p++ = ',';
00056 str += 3;
00057 len -= 3;
00058 }
00059 else if (len >= 3 && str[0] == '=' && str[1] == '3' && str[2] == 'D')
00060 {
00061 *p++ = '=';
00062 str += 3;
00063 len -= 3;
00064 }
00065 else
00066 {
00067 *p++ = *str;
00068 str++;
00069 len--;
00070 }
00071 }
00072 *p = '\0';
00073
00074 return out;
00075 }
00076
00077 int
00078 scram_parse_client_first (const char *str, size_t len,
00079 struct scram_client_first *cf)
00080 {
00081
00082 if (strnlen (str, len) < 10)
00083 return -1;
00084
00085 if (len == 0 || (*str != 'n' && *str != 'y'))
00086
00087 return -1;
00088 cf->cbflag = *str;
00089 str++, len--;
00090
00091 if (len == 0 || *str != ',')
00092 return -1;
00093 str++, len--;
00094
00095 if (len == 0)
00096 return -1;
00097 if (*str == 'a')
00098 {
00099 const char *p;
00100 size_t l;
00101
00102 str++, len--;
00103 if (len == 0 || *str != '=')
00104 return -1;
00105 str++, len--;
00106
00107 p = memchr (str, ',', len);
00108 if (!p)
00109 return -1;
00110
00111 l = p - str;
00112 if (len < l)
00113 return -1;
00114
00115 cf->authzid = unescape (str, l);
00116 if (!cf->authzid)
00117 return -1;
00118
00119 str = p;
00120 len -= l;
00121 }
00122
00123 if (len == 0 || *str != ',')
00124 return -1;
00125 str++, len--;
00126
00127 if (len == 0 || *str != 'n')
00128 return -1;
00129 str++, len--;
00130
00131 if (len == 0 || *str != '=')
00132 return -1;
00133 str++, len--;
00134
00135 {
00136 const char *p;
00137 size_t l;
00138
00139 p = memchr (str, ',', len);
00140 if (!p)
00141 return -1;
00142
00143 l = p - str;
00144 if (len < l)
00145 return -1;
00146
00147 cf->username = unescape (str, l);
00148 if (!cf->username)
00149 return -1;
00150
00151 str = p;
00152 len -= l;
00153 }
00154
00155 if (len == 0 || *str != ',')
00156 return -1;
00157 str++, len--;
00158
00159 if (len == 0 || *str != 'r')
00160 return -1;
00161 str++, len--;
00162
00163 if (len == 0 || *str != '=')
00164 return -1;
00165 str++, len--;
00166
00167 {
00168 const char *p;
00169 size_t l;
00170
00171 p = memchr (str, ',', len);
00172 if (!p)
00173 p = str + len;
00174 if (!p)
00175 return -1;
00176
00177 l = p - str;
00178 if (len < l)
00179 return -1;
00180
00181 cf->client_nonce = malloc (l + 1);
00182 if (!cf->client_nonce)
00183 return -1;
00184
00185 memcpy (cf->client_nonce, str, l);
00186 cf->client_nonce[l] = '\0';
00187
00188 str = p;
00189 len -= l;
00190 }
00191
00192
00193
00194 if (scram_valid_client_first (cf) < 0)
00195 return -1;
00196
00197 return 0;
00198 }
00199
00200 int
00201 scram_parse_server_first (const char *str, size_t len,
00202 struct scram_server_first *sf)
00203 {
00204
00205 if (strnlen (str, len) < 15)
00206 return -1;
00207
00208 if (len == 0 || *str != 'r')
00209 return -1;
00210 str++, len--;
00211
00212 if (len == 0 || *str != '=')
00213 return -1;
00214 str++, len--;
00215
00216 {
00217 const char *p;
00218 size_t l;
00219
00220 p = memchr (str, ',', len);
00221 if (!p)
00222 return -1;
00223
00224 l = p - str;
00225 if (len < l)
00226 return -1;
00227
00228 sf->nonce = malloc (l + 1);
00229 if (!sf->nonce)
00230 return -1;
00231
00232 memcpy (sf->nonce, str, l);
00233 sf->nonce[l] = '\0';
00234
00235 str = p;
00236 len -= l;
00237 }
00238
00239 if (len == 0 || *str != ',')
00240 return -1;
00241 str++, len--;
00242
00243 if (len == 0 || *str != 's')
00244 return -1;
00245 str++, len--;
00246
00247 if (len == 0 || *str != '=')
00248 return -1;
00249 str++, len--;
00250
00251 {
00252 const char *p;
00253 size_t l;
00254
00255 p = memchr (str, ',', len);
00256 if (!p)
00257 return -1;
00258
00259 l = p - str;
00260 if (len < l)
00261 return -1;
00262
00263 sf->salt = malloc (l + 1);
00264 if (!sf->salt)
00265 return -1;
00266
00267 memcpy (sf->salt, str, l);
00268 sf->salt[l] = '\0';
00269
00270 str = p;
00271 len -= l;
00272 }
00273
00274 if (len == 0 || *str != ',')
00275 return -1;
00276 str++, len--;
00277
00278 if (len == 0 || *str != 'i')
00279 return -1;
00280 str++, len--;
00281
00282 if (len == 0 || *str != '=')
00283 return -1;
00284 str++, len--;
00285
00286 sf->iter = 0;
00287 for (; len > 0 && *str >= '0' && *str <= '9'; str++, len--)
00288 {
00289 size_t last_iter = sf->iter;
00290
00291 sf->iter = sf->iter * 10 + (*str - '0');
00292
00293
00294 if (sf->iter < last_iter)
00295 return -1;
00296 }
00297
00298 if (len > 0 && *str != ',')
00299 return -1;
00300
00301
00302
00303 if (scram_valid_server_first (sf) < 0)
00304 return -1;
00305
00306 return 0;
00307 }
00308
00309 int
00310 scram_parse_client_final (const char *str, size_t len,
00311 struct scram_client_final *cl)
00312 {
00313
00314 if (strnlen (str, len) < 18)
00315 return -1;
00316
00317 if (len == 0 || *str != 'c')
00318 return -1;
00319 str++, len--;
00320
00321 if (len == 0 || *str != '=')
00322 return -1;
00323 str++, len--;
00324
00325 {
00326 const char *p;
00327 size_t l;
00328
00329 p = memchr (str, ',', len);
00330 if (!p)
00331 return -1;
00332
00333 l = p - str;
00334 if (len < l)
00335 return -1;
00336
00337 cl->cbind = malloc (l + 1);
00338 if (!cl->cbind)
00339 return -1;
00340
00341 memcpy (cl->cbind, str, l);
00342 cl->cbind[l] = '\0';
00343
00344 str = p;
00345 len -= l;
00346 }
00347
00348 if (len == 0 || *str != ',')
00349 return -1;
00350 str++, len--;
00351
00352 if (len == 0 || *str != 'r')
00353 return -1;
00354 str++, len--;
00355
00356 if (len == 0 || *str != '=')
00357 return -1;
00358 str++, len--;
00359
00360 {
00361 const char *p;
00362 size_t l;
00363
00364 p = memchr (str, ',', len);
00365 if (!p)
00366 return -1;
00367
00368 l = p - str;
00369 if (len < l)
00370 return -1;
00371
00372 cl->nonce = malloc (l + 1);
00373 if (!cl->nonce)
00374 return -1;
00375
00376 memcpy (cl->nonce, str, l);
00377 cl->nonce[l] = '\0';
00378
00379 str = p;
00380 len -= l;
00381 }
00382
00383 if (len == 0 || *str != ',')
00384 return -1;
00385 str++, len--;
00386
00387
00388 while (len > 0 && c_isalpha (*str) && *str != 'p')
00389 {
00390 const char *p;
00391 size_t l;
00392
00393 str++, len--;
00394
00395 if (len == 0 || *str != '=')
00396 return -1;
00397 str++, len--;
00398
00399 p = memchr (str, ',', len);
00400 if (!p)
00401 return -1;
00402 p++;
00403
00404 l = p - str;
00405 if (len < l)
00406 return -1;
00407
00408 str = p;
00409 len -= l;
00410 }
00411
00412 if (len == 0 || *str != 'p')
00413 return -1;
00414 str++, len--;
00415
00416 if (len == 0 || *str != '=')
00417 return -1;
00418 str++, len--;
00419
00420
00421 if (memchr (str, '\0', len))
00422 return -1;
00423
00424 cl->proof = malloc (len + 1);
00425 if (!cl->proof)
00426 return -1;
00427
00428 memcpy (cl->proof, str, len);
00429 cl->proof[len] = '\0';
00430
00431 if (scram_valid_client_final (cl) < 0)
00432 return -1;
00433
00434 return 0;
00435 }
00436
00437 int
00438 scram_parse_server_final (const char *str, size_t len,
00439 struct scram_server_final *sl)
00440 {
00441
00442 if (strnlen (str, len) < 6)
00443 return -1;
00444
00445 if (len == 0 || *str != 'v')
00446 return -1;
00447 str++, len--;
00448
00449 if (len == 0 || *str != '=')
00450 return -1;
00451 str++, len--;
00452
00453
00454 if (memchr (str, '\0', len))
00455 return -1;
00456
00457 sl->verifier = malloc (len + 1);
00458 if (!sl->verifier)
00459 return -1;
00460
00461 memcpy (sl->verifier, str, len);
00462 sl->verifier[len] = '\0';
00463
00464 if (scram_valid_server_final (sl) < 0)
00465 return -1;
00466
00467 return 0;
00468 }