s/qmail 4.2.29a
Next generation secure email transport
Loading...
Searching...
No Matches
srs2.c
Go to the documentation of this file.
1/* Copyright (c) 2004 Shevek (srs@anarres.org)
2 * All rights reserved.
3 *
4 * This file is a part of libsrs2 from http://www.libsrs2.org/
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, under the terms of either the GNU General Public
8 * License version 2 or the BSD license, at the discretion of the
9 * user. Copies of these licenses have been included in the libsrs2
10 * distribution. See the the file called LICENSE for more
11 * information.
12 */
13
14/* This is a minimal adapted s/qmail version; it requires complete
15 refactoring:
16
17 a) Use stralloc for addresses
18 b) Replace stdio, str*, and mem* functions
19 c) Use tai64 for timestamp function
20 d) Remove va args
21 e) Reduce code by 50%
22*/
23
24#include <stdio.h>
25#include <stdlib.h>
26#include <ctype.h>
27#include <stdarg.h>
28#include <time.h> /* time */
29#include <sys/types.h> /* tyepdefs */
30#include <sys/time.h> /* timeval / timezone struct */
31#include <string.h> /* memcpy, strcpy, memset */
32#include "srs2.h"
33#include "sha1.h"
34
35#ifndef HAVE_STRCASECMP
36# ifdef HAVE__STRICMP
37# define strcasecmp _stricmp
38# endif
39#endif
40
41#ifndef HAVE_STRNCASECMP
42# ifdef HAVE__STRNICMP
43# define strncasecmp _strnicmp
44# endif
45#endif
46
47 /* Use this */
48#define STRINGP(s) ((s != NULL) && (*(s) != '\0'))
49
50static const char *srs_separators = "=-+";
51
52static srs_malloc_t srs_f_malloc = malloc;
53static srs_realloc_t srs_f_realloc = realloc;
54static srs_free_t srs_f_free = free;
55
57{
58 srs_f_malloc = m;
59 srs_f_realloc = r;
60 srs_f_free = f;
61 return SRS_SUCCESS;
62}
63
64#define X(e,s) if (code == e) return s;
65
66const char *srs_strerror(int code)
67{
68 X(0,"")
69 /* Simple errors */
70 X(SRS_SUCCESS,"Success")
71 X(SRS_ENOTSRSADDRESS,"Not an SRS address.")
72
73 /* Config errors */
74 X(SRS_ENOSECRETS,"No secrets in SRS configuration.")
75 X(SRS_ESEPARATORINVALID,"Invalid separator suggested.")
76
77 /* Input errors */
78 X(SRS_ENOSENDERATSIGN,"No at sign in sender address")
79 X(SRS_EBUFTOOSMALL,"Buffer too small.")
80
81 /* Syntax errors */
82 X(SRS_ENOSRS0HOST,"No host in SRS0 address.")
83 X(SRS_ENOSRS0USER,"No user in SRS0 address.")
84 X(SRS_ENOSRS0HASH,"No hash in SRS0 address.")
85 X(SRS_ENOSRS0STAMP,"No timestamp in SRS0 address.")
86 X(SRS_ENOSRS1HOST,"No host in SRS1 address.")
87 X(SRS_ENOSRS1USER,"No user in SRS1 address.")
88 X(SRS_ENOSRS1HASH,"No hash in SRS1 address.")
89 X(SRS_EBADTIMESTAMPCHAR,"Bad base32 character in timestamp.")
90 X(SRS_EHASHTOOSHORT,"Hash too short in SRS address.")
91
92 /* SRS errors */
93 X(SRS_ETIMESTAMPOUTOFDATE,"Time stamp out of date.")
94 X(SRS_EHASHINVALID,"Hash invalid in SRS address.")
95
96 return "Unknown SRS error.";
97}
98
100{
101 srs_t *srs = (srs_t *)srs_f_malloc(sizeof(srs_t));
102 srs_init(srs);
103 return srs;
104}
105
106void srs_init(srs_t *srs)
107{
108 memset(srs, 0, sizeof(srs_t));
109 srs->secrets = NULL;
110 srs->numsecrets = 0;
111 srs->separator = '=';
112 srs->maxage = 21;
113 srs->hashlen = 4;
114 srs->hashmin = srs->hashlen;
115 srs->alwaysrewrite = FALSE;
116}
117
118void srs_free(srs_t *srs)
119{
120 int i;
121 for (i = 0; i < srs->numsecrets; i++) {
122 memset(srs->secrets[i], 0, strlen(srs->secrets[i]));
123 srs_f_free(srs->secrets[i]);
124 srs->secrets[i] = '\0';
125 }
126 srs_f_free(srs);
127}
128
129int srs_add_secret(srs_t *srs, const char *secret)
130{
131 int newlen = (srs->numsecrets + 1) * sizeof(char *);
132 srs->secrets = (char **)srs_f_realloc(srs->secrets, newlen);
133 srs->secrets[srs->numsecrets++] = strdup(secret);
134 return SRS_SUCCESS;
135}
136
137const char *srs_get_secret(srs_t *srs, int idx)
138{
139 if (idx < srs->numsecrets)
140 return srs->secrets[idx];
141 return NULL;
142}
143
144#define SRS_PARAM_DEFINE(n, t) \
145 int srs_set_ ## n (srs_t *srs, t value) { \
146 srs->n = value; \
147 return SRS_SUCCESS; \
148 } \
149 t srs_get_ ## n (srs_t *srs) { \
150 return srs->n; \
151 }
152
153int srs_set_separator(srs_t *srs, char value)
154{
155 if (strchr(srs_separators, value) == NULL)
157 srs->separator = value;
158 return SRS_SUCCESS;
159}
160
162{
163 return srs->separator;
164}
165
166SRS_PARAM_DEFINE(maxage, int)
167 /* XXX Check hashlen >= hashmin */
168SRS_PARAM_DEFINE(hashlen, int)
169SRS_PARAM_DEFINE(hashmin, int)
170SRS_PARAM_DEFINE(alwaysrewrite, srs_bool)
171SRS_PARAM_DEFINE(noforward, srs_bool)
172SRS_PARAM_DEFINE(noreverse, srs_bool)
173
174/* Don't mess with these unless you know what you're doing well
175 * enough to rewrite the timestamp functions. These are based on
176 * a 2 character timestamp. Changing these in the wild is probably
177 * a bad idea. */
178#define SRS_TIME_PRECISION (60 * 60 * 24) /* One day */
179#define SRS_TIME_BASEBITS 5 /* 2^5 = 32 = strlen(CHARS) */
180/* This had better be a real variable since we do arithmethic
181 * with it. */
182const char *SRS_TIME_BASECHARS = "ABCDEFGHIJKLMNOPQRSTUVWXYZ234567";
183#define SRS_TIME_SIZE 2
184#define SRS_TIME_SLOTS (1<<(SRS_TIME_BASEBITS<<(SRS_TIME_SIZE-1)))
185
186int srs_timestamp_create(srs_t *srs, char *buf, time_t now)
187{
189 buf[1] = SRS_TIME_BASECHARS[now & ((1 << SRS_TIME_BASEBITS) - 1)];
191 buf[0] = SRS_TIME_BASECHARS[now & ((1 << SRS_TIME_BASEBITS) - 1)];
192 buf[2] = '\0';
193 return SRS_SUCCESS;
194}
195
196int srs_timestamp_check(srs_t *srs, const char *stamp)
197{
198 const char *sp;
199 char *bp;
200 int off;
201 time_t now;
202 time_t then;
203
204 /* We had better go around this loop exactly twice! */
205 then = 0;
206 for (sp = stamp; *sp; sp++) {
207 bp = strchr(SRS_TIME_BASECHARS, toupper(*sp));
208 if (bp == NULL)
210 off = bp - SRS_TIME_BASECHARS;
211 then = (then << SRS_TIME_BASEBITS) | off;
212 }
213
214 time(&now);
216 while (now < then)
218
219 if (now <= then + srs->maxage)
220 return SRS_SUCCESS;
222}
223
224const char *SRS_HASH_BASECHARS = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
225 "abcdefghijklmnopqrstuvwxyz"
226 "0123456789+/";
227
228static void srs_hash_create_v(srs_t *srs, int idx, char *buf, int nargs, va_list ap)
229{
231 char srshash[SHA1_DIGESTSIZE + 1];
232 char *secret;
233 char *data;
234 int len;
235 char *lcdata;
236 unsigned char *hp;
237 char *bp;
238 int i;
239 int j;
240
241 secret = srs->secrets[idx];
242 sha1_init(&ctx);
243 sha1_update(&ctx, secret, strlen(secret));
244
245 for (i = 0; i < nargs; i++) {
246 data = va_arg(ap, char *);
247 len = strlen(data);
248 lcdata = alloca(len + 1);
249 for (j = 0; j < len; j++) {
250 if (isupper(data[j]))
251 lcdata[j] = tolower(data[j]);
252 else
253 lcdata[j] = data[j];
254 }
255 sha1_update(&ctx, lcdata, len);
256 }
257
258 sha1_final(srshash, &ctx); /* args inverted */
259 srshash[SHA1_DIGESTSIZE] = '\0';
260
261 /* A little base64 encoding. Just a little. */
262 hp = (unsigned char *)srshash;
263 bp = buf;
264 for (i = 0; i < srs->hashlen; i++) {
265 switch (i & 0x03) {
266 default: /* NOTREACHED */
267 case 0:
268 j = (*hp >> 2);
269 break;
270 case 1:
271 j = ((*hp & 0x03) << 4) |
272 ((*(hp + 1) & 0xF0) >> 4);
273 hp++;
274 break;
275 case 2:
276 j = ((*hp & 0x0F) << 2) |
277 ((*(hp + 1) & 0xC0) >> 6);
278 hp++;
279 break;
280 case 3:
281 j = (*hp++ & 0x3F);
282 break;
283 }
284 *bp++ = SRS_HASH_BASECHARS[j];
285 }
286
287 *bp = '\0';
288 buf[srs->hashlen] = '\0';
289}
290
291int srs_hash_create(srs_t *srs, char *buf, int nargs, ...)
292{
293 va_list ap;
294
295 if (srs->numsecrets == 0)
296 return SRS_ENOSECRETS;
297 if (srs->secrets == NULL)
298 return SRS_ENOSECRETS;
299 if (srs->secrets[0] == NULL)
300 return SRS_ENOSECRETS;
301
302 va_start(ap, nargs);
303 srs_hash_create_v(srs, 0, buf, nargs, ap);
304 va_end(ap);
305
306 return SRS_SUCCESS;
307}
308
309int srs_hash_check(srs_t *srs, char *hash, int nargs, ...)
310{
311 va_list ap;
312 char *srshash;
313 char *tmp;
314 int len;
315 int i;
316
317 len = strlen(hash);
318 if (len < srs->hashmin)
319 return SRS_EHASHTOOSHORT;
320 if (len < srs->hashlen) {
321 tmp = alloca(srs->hashlen + 1);
322 strncpy(tmp, hash, srs->hashlen);
323 tmp[srs->hashlen] = '\0';
324 hash = tmp;
325 len = srs->hashlen;
326 }
327
328 for (i = 0; i < srs->numsecrets; i++) {
329 va_start(ap, nargs);
330 srshash = alloca(srs->hashlen + 1);
331 srs_hash_create_v(srs, i, srshash, nargs, ap);
332 va_end(ap);
333 if (strncasecmp(hash, srshash, len) == 0)
334 return SRS_SUCCESS;
335 }
336
337 return SRS_EHASHINVALID;
338}
339
341 char *buf, int buflen,
342 char *sendhost, char *senduser,
343 const char *aliashost) {
344 char *srshash;
345 char srsstamp[SRS_TIME_SIZE + 1];
346 int len;
347 int ret;
348
349 /* This never happens if we get called from guarded() */
350 if ((strncasecmp(senduser, SRS0TAG, 4) == 0) &&
351 (strchr(srs_separators, senduser[4]) != NULL)) {
352 sendhost = senduser + 5;
353 if (*sendhost == '\0')
354 return SRS_ENOSRS0HOST;
355 senduser = strchr(sendhost, SRSSEP);
356 if ((senduser == NULL) || (*senduser == '\0'))
357 return SRS_ENOSRS0USER;
358 }
359
360 len = strlen(SRS0TAG) + 1 +
361 srs->hashlen + 1 +
362 SRS_TIME_SIZE + 1 +
363 strlen(sendhost) + 1 + strlen(senduser)
364 + 1 + strlen(aliashost);
365 if (len >= buflen)
366 return SRS_EBUFTOOSMALL;
367
368 ret = srs_timestamp_create(srs, srsstamp, time(NULL));
369 if (ret != SRS_SUCCESS)
370 return ret;
371 srshash = alloca(srs->hashlen + 1);
372 ret = srs_hash_create(srs, srshash,3, srsstamp, sendhost, senduser);
373 if (ret != SRS_SUCCESS)
374 return ret;
375
376 sprintf(buf, SRS0TAG "%c%s%c%s%c%s%c%s@%s", srs->separator,
377 srshash, SRSSEP, srsstamp, SRSSEP,
378 sendhost, SRSSEP, senduser,
379 aliashost);
380
381 return SRS_SUCCESS;
382}
383
385 char *buf, int buflen,
386 char *sendhost, char *senduser,
387 const char *aliashost) {
388 char *srshost;
389 char *srsuser;
390 char *srshash;
391 int len;
392 int ret;
393
394 if ((strncasecmp(senduser, SRS1TAG, 4) == 0) &&
395 (strchr(srs_separators, senduser[4]) != NULL)) {
396 /* Used as a temporary convenience var */
397 srshash = senduser + 5;
398 if (*srshash == '\0')
399 return SRS_ENOSRS1HASH;
400 /* Used as a temporary convenience var */
401 srshost = strchr(srshash, SRSSEP);
402 if (!STRINGP(srshost))
403 return SRS_ENOSRS1HOST;
404 *srshost++ = '\0';
405 srsuser = strchr(srshost, SRSSEP);
406 if (!STRINGP(srsuser))
407 return SRS_ENOSRS1USER;
408 *srsuser++ = '\0';
409 srshash = alloca(srs->hashlen + 1);
410 ret = srs_hash_create(srs, srshash, 2, srshost, srsuser);
411 if (ret != SRS_SUCCESS)
412 return ret;
413 len = strlen(SRS1TAG) + 1 +
414 srs->hashlen + 1 +
415 strlen(srshost) + 1 + strlen(srsuser)
416 + 1 + strlen(aliashost);
417 if (len >= buflen)
418 return SRS_EBUFTOOSMALL;
419 sprintf(buf, SRS1TAG "%c%s%c%s%c%s@%s", srs->separator,
420 srshash, SRSSEP,
421 srshost, SRSSEP, srsuser,
422 aliashost);
423 return SRS_SUCCESS;
424 }
425 else if ((strncasecmp(senduser, SRS0TAG, 4) == 0) &&
426 (strchr(srs_separators, senduser[4]) != NULL)) {
427 srsuser = senduser + 4;
428 srshost = sendhost;
429 srshash = alloca(srs->hashlen + 1);
430 ret = srs_hash_create(srs, srshash, 2, srshost, srsuser);
431 if (ret != SRS_SUCCESS)
432 return ret;
433 len = strlen(SRS1TAG) + 1 +
434 srs->hashlen + 1 +
435 strlen(srshost) + 1 + strlen(srsuser)
436 + 1 + strlen(aliashost);
437 if (len >= buflen)
438 return SRS_EBUFTOOSMALL;
439 sprintf(buf, SRS1TAG "%c%s%c%s%c%s@%s", srs->separator,
440 srshash, SRSSEP,
441 srshost, SRSSEP, srsuser,
442 aliashost);
443 }
444 else {
445 return srs_compile_shortcut(srs, buf, buflen,
446 sendhost, senduser, aliashost);
447 }
448
449 return SRS_SUCCESS;
450}
451
452int srs_parse_shortcut(srs_t *srs, char *buf, int buflen, char *senduser)
453{
454 char *srshash;
455 char *srsstamp;
456 char *srshost;
457 char *srsuser;
458 int ret;
459
460 if (strncasecmp(senduser, SRS0TAG, 4) == 0) {
461 srshash = senduser + 5;
462 if (!STRINGP(srshash))
463 return SRS_ENOSRS0HASH;
464 srsstamp = strchr(srshash, SRSSEP);
465 if (!STRINGP(srsstamp))
466 return SRS_ENOSRS0STAMP;
467 *srsstamp++ = '\0';
468 srshost = strchr(srsstamp, SRSSEP);
469 if (!STRINGP(srshost))
470 return SRS_ENOSRS0HOST;
471 *srshost++ = '\0';
472 srsuser = strchr(srshost, SRSSEP);
473 if (!STRINGP(srsuser))
474 return SRS_ENOSRS0USER;
475 *srsuser++ = '\0';
476 ret = srs_timestamp_check(srs, srsstamp);
477 if (ret != SRS_SUCCESS)
478 return ret;
479 ret = srs_hash_check(srs, srshash, 3, srsstamp,
480 srshost, srsuser);
481 if (ret != SRS_SUCCESS)
482 return ret;
483 sprintf(buf, "%s@%s", srsuser, srshost);
484 return SRS_SUCCESS;
485 }
486
487 return SRS_ENOTSRSADDRESS;
488}
489
490int srs_parse_guarded(srs_t *srs, char *buf, int buflen, char *senduser)
491{
492 char *srshash;
493 char *srshost;
494 char *srsuser;
495 int ret;
496
497 if (strncasecmp(senduser, SRS1TAG, 4) == 0) {
498 srshash = senduser + 5;
499 if (!STRINGP(srshash))
500 return SRS_ENOSRS1HASH;
501 srshost = strchr(srshash, SRSSEP);
502 if (!STRINGP(srshost))
503 return SRS_ENOSRS1HOST;
504 *srshost++ = '\0';
505 srsuser = strchr(srshost, SRSSEP);
506 if (!STRINGP(srsuser))
507 return SRS_ENOSRS1USER;
508 *srsuser++ = '\0';
509 ret = srs_hash_check(srs, srshash, 2, srshost, srsuser);
510 if (ret != SRS_SUCCESS)
511 return ret;
512 sprintf(buf, SRS0TAG "%s@%s", srsuser, srshost);
513 return SRS_SUCCESS;
514 }
515 else {
516 return srs_parse_shortcut(srs, buf, buflen, senduser);
517 }
518}
519
520int srs_forward(srs_t *srs, char *buf, int buflen,
521 const char *sender, const char *alias)
522{
523 char *senduser;
524 char *sendhost;
525 char *tmp;
526 int len;
527
528 if (srs->noforward)
529 return SRS_ENOTREWRITTEN;
530
531 /* This is allowed to be a plain domain */
532 while ((tmp = strchr(alias, '@')) != NULL)
533 alias = tmp + 1;
534
535 tmp = strchr(sender, '@');
536 if (tmp == NULL)
537 return SRS_ENOSENDERATSIGN;
538 sendhost = tmp + 1;
539
540 len = strlen(sender);
541
542 if (! srs->alwaysrewrite) {
543 if (strcasecmp(sendhost, alias) == 0) {
544 if (strlen(sender) >= buflen)
545 return SRS_EBUFTOOSMALL;
546 strcpy(buf, sender);
547 return SRS_SUCCESS;
548 }
549 }
550
551 /* Reconstruct the whole show into our alloca() buffer. */
552 senduser = alloca(len + 1);
553 strcpy(senduser, sender);
554 tmp = (senduser + (tmp - sender));
555 sendhost = tmp + 1;
556 *tmp = '\0';
557
558 return srs_compile_guarded(srs, buf, buflen,
559 sendhost, senduser, alias);
560}
561
562int srs_forward_alloc(srs_t *srs, char **sptr,
563 const char *sender, const char *alias)
564{
565 char *buf;
566 int slen;
567 int alen;
568 int len;
569 int ret;
570
571 if (srs->noforward)
572 return SRS_ENOTREWRITTEN;
573
574 slen = strlen(sender);
575 alen = strlen(alias);
576
577 /* strlen(SRSxTAG) + strlen("====+@") < 64 */
578 len = slen + alen + srs->hashlen + SRS_TIME_SIZE + 64;
579 buf = (char *)srs_f_malloc(len);
580
581 ret = srs_forward(srs, buf, len, sender, alias);
582
583 if (ret == SRS_SUCCESS)
584 *sptr = buf;
585 else
586 srs_f_free(buf);
587
588 return ret;
589}
590
591int srs_reverse(srs_t *srs, char *buf, int buflen, const char *sender)
592{
593 char *senduser;
594 char *tmp;
595 int len;
596
598 return SRS_ENOTSRSADDRESS;
599
600 if (srs->noreverse)
601 return SRS_ENOTREWRITTEN;
602
603 len = strlen(sender);
604 if (len >= buflen)
605 return SRS_EBUFTOOSMALL;
606 senduser = alloca(len + 1);
607 strcpy(senduser, sender);
608
609 /* We don't really care about the host for reversal. */
610 tmp = strchr(senduser, '@');
611 if (tmp != NULL)
612 *tmp = '\0';
613 return srs_parse_guarded(srs, buf, buflen, senduser);
614}
615
616int srs_reverse_alloc(srs_t *srs, char **sptr, const char *sender)
617{
618 char *buf;
619 int len;
620 int ret;
621
622 *sptr = NULL;
623
625 return SRS_ENOTSRSADDRESS;
626
627 if (srs->noreverse)
628 return SRS_ENOTREWRITTEN;
629
630 len = strlen(sender) + 1;
631 buf = (char *)srs_f_malloc(len);
632
633 ret = srs_reverse(srs, buf, len, sender);
634
635 if (ret == SRS_SUCCESS)
636 *sptr = buf;
637 else
638 srs_f_free(buf);
639
640 return ret;
641}
stralloc sender
Definition: fastforward.c:71
stralloc data
Definition: fastforward.c:118
char buf[100+FMT_ULONG]
Definition: hier.c:10
stralloc tmp
Definition: newinclude.c:35
datetime_sec now()
Definition: now.c:5
stralloc hash
Definition: qmail-dksign.c:243
struct message * m
unsigned long code
Definition: qmail-remote.c:576
SSL_CTX * ctx
Definition: qmail-remote.c:106
int j
Definition: qmail-send.c:920
void sha1_final(uint8_t hash[SHA1_DIGESTSIZE], sha1_ctx *context)
Definition: sha1.c:146
void sha1_init(sha1_ctx *context)
Definition: sha1.c:111
#define SHA1_DIGESTSIZE
Definition: sha1.h:16
void sha1_update(sha1_ctx *context, const uint8_t *data, uint32_t len)
Definition: sha1.c:124
char stamp[FMT_ULONG+FMT_ULONG+3]
Definition: splogger.c:16
const char * srs_strerror(int code)
Definition: srs2.c:66
void srs_init(srs_t *srs)
Definition: srs2.c:106
#define SRS_TIME_SLOTS
Definition: srs2.c:184
int srs_set_separator(srs_t *srs, char value)
Definition: srs2.c:153
#define SRS_TIME_PRECISION
Definition: srs2.c:178
#define X(e, s)
Definition: srs2.c:64
int srs_hash_create(srs_t *srs, char *buf, int nargs,...)
Definition: srs2.c:291
#define SRS_TIME_SIZE
Definition: srs2.c:183
srs_t * srs_new()
Definition: srs2.c:99
int srs_hash_check(srs_t *srs, char *hash, int nargs,...)
Definition: srs2.c:309
int srs_timestamp_check(srs_t *srs, const char *stamp)
Definition: srs2.c:196
int srs_reverse(srs_t *srs, char *buf, int buflen, const char *sender)
Definition: srs2.c:591
const char * srs_get_secret(srs_t *srs, int idx)
Definition: srs2.c:137
#define STRINGP(s)
Definition: srs2.c:48
char srs_get_separator(srs_t *srs)
Definition: srs2.c:161
int srs_parse_guarded(srs_t *srs, char *buf, int buflen, char *senduser)
Definition: srs2.c:490
const char * SRS_TIME_BASECHARS
Definition: srs2.c:182
void srs_free(srs_t *srs)
Definition: srs2.c:118
int srs_reverse_alloc(srs_t *srs, char **sptr, const char *sender)
Definition: srs2.c:616
int srs_forward_alloc(srs_t *srs, char **sptr, const char *sender, const char *alias)
Definition: srs2.c:562
int srs_add_secret(srs_t *srs, const char *secret)
Definition: srs2.c:129
int srs_compile_guarded(srs_t *srs, char *buf, int buflen, char *sendhost, char *senduser, const char *aliashost)
Definition: srs2.c:384
int srs_set_malloc(srs_malloc_t m, srs_realloc_t r, srs_free_t f)
Definition: srs2.c:56
int srs_forward(srs_t *srs, char *buf, int buflen, const char *sender, const char *alias)
Definition: srs2.c:520
#define SRS_PARAM_DEFINE(n, t)
Definition: srs2.c:144
int srs_parse_shortcut(srs_t *srs, char *buf, int buflen, char *senduser)
Definition: srs2.c:452
int srs_timestamp_create(srs_t *srs, char *buf, time_t now)
Definition: srs2.c:186
int srs_compile_shortcut(srs_t *srs, char *buf, int buflen, char *sendhost, char *senduser, const char *aliashost)
Definition: srs2.c:340
#define SRS_TIME_BASEBITS
Definition: srs2.c:179
const char * SRS_HASH_BASECHARS
Definition: srs2.c:224
#define SRS_ETIMESTAMPOUTOFDATE
Definition: srs2.h:60
void *(* srs_malloc_t)(size_t)
Definition: srs2.h:73
#define SRS_ENOSRS1USER
Definition: srs2.h:55
#define SRS_ENOSENDERATSIGN
Definition: srs2.h:47
#define SRS0TAG
Definition: srs2.h:28
#define SRS_ENOSRS1HASH
Definition: srs2.h:56
#define SRS_ENOSRS1HOST
Definition: srs2.h:54
#define SRSSEP
Definition: srs2.h:27
#define SRS_ENOSRS0USER
Definition: srs2.h:51
#define SRS_ENOSRS0HASH
Definition: srs2.h:52
#define SRS_EHASHINVALID
Definition: srs2.h:61
void(* srs_free_t)(void *)
Definition: srs2.h:75
void *(* srs_realloc_t)(void *, size_t)
Definition: srs2.h:74
#define SRS_EHASHTOOSHORT
Definition: srs2.h:58
#define SRS1TAG
Definition: srs2.h:29
int srs_bool
Definition: srs2.h:77
#define SRS_ENOSECRETS
Definition: srs2.h:44
#define SRS_ESEPARATORINVALID
Definition: srs2.h:45
#define SRS_ENOSRS0HOST
Definition: srs2.h:50
#define SRS_ENOTREWRITTEN
Definition: srs2.h:42
#define SRS_SUCCESS
Definition: srs2.h:40
#define SRS_EBUFTOOSMALL
Definition: srs2.h:48
#define FALSE
Definition: srs2.h:25
#define SRS_IS_SRS_ADDRESS(x)
Definition: srs2.h:67
#define SRS_EBADTIMESTAMPCHAR
Definition: srs2.h:57
#define SRS_ENOTSRSADDRESS
Definition: srs2.h:41
#define SRS_ENOSRS0STAMP
Definition: srs2.h:53
stralloc srshost
Definition: srsforward.c:27
Definition: srs2.h:79
char ** secrets
Definition: srs2.h:82
int hashlen
Definition: srs2.h:88
int hashmin
Definition: srs2.h:89
char separator
Definition: srs2.h:84
srs_bool noreverse
Definition: srs2.h:94
srs_bool alwaysrewrite
Definition: srs2.h:92
int maxage
Definition: srs2.h:87
srs_bool noforward
Definition: srs2.h:93
int numsecrets
Definition: srs2.h:83
Definition: sha1.h:19