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