diff options
Diffstat (limited to 'src/srs2.c')
-rw-r--r-- | src/srs2.c | 916 |
1 files changed, 437 insertions, 479 deletions
@@ -21,150 +21,154 @@ e) Reduce code by 50% */ -#include <stdio.h> -#include <stdlib.h> +#include "srs2.h" + +#include <sys/time.h> /* timeval / timezone struct */ +#include <sys/types.h> /* tyepdefs */ + #include <ctype.h> #include <stdarg.h> -#include <time.h> /* time */ -#include <sys/types.h> /* tyepdefs */ -#include <sys/time.h> /* timeval / timezone struct */ -#include <string.h> /* memcpy, strcpy, memset */ -#include "srs2.h" +#include <stdio.h> +#include <stdlib.h> +#include <string.h> /* memcpy, strcpy, memset */ +#include <time.h> /* time */ + #include "sha1.h" #ifndef HAVE_STRCASECMP -# ifdef HAVE__STRICMP -# define strcasecmp _stricmp -# endif + #ifdef HAVE__STRICMP + #define strcasecmp _stricmp + #endif #endif #ifndef HAVE_STRNCASECMP -# ifdef HAVE__STRNICMP -# define strncasecmp _strnicmp -# endif + #ifdef HAVE__STRNICMP + #define strncasecmp _strnicmp + #endif #endif - /* Use this */ +/* Use this */ #define STRINGP(s) ((s != NULL) && (*(s) != '\0')) static const char *srs_separators = "=-+"; -static srs_malloc_t srs_f_malloc = malloc; -static srs_realloc_t srs_f_realloc = realloc; -static srs_free_t srs_f_free = free; +static srs_malloc_t srs_f_malloc = malloc; +static srs_realloc_t srs_f_realloc = realloc; +static srs_free_t srs_f_free = free; -int srs_set_malloc(srs_malloc_t m, srs_realloc_t r, srs_free_t f) +int srs_set_malloc(srs_malloc_t m, srs_realloc_t r, srs_free_t f) { - srs_f_malloc = m; - srs_f_realloc = r; - srs_f_free = f; - return SRS_SUCCESS; + srs_f_malloc = m; + srs_f_realloc = r; + srs_f_free = f; + return SRS_SUCCESS; } -#define X(e,s) if (code == e) return s; +#define X(e, s) \ + if (code == e) return s; const char *srs_strerror(int code) { - X(0,"") + X(0, "") /* Simple errors */ - X(SRS_SUCCESS,"Success") - X(SRS_ENOTSRSADDRESS,"Not an SRS address.") + X(SRS_SUCCESS, "Success") + X(SRS_ENOTSRSADDRESS, "Not an SRS address.") /* Config errors */ - X(SRS_ENOSECRETS,"No secrets in SRS configuration.") - X(SRS_ESEPARATORINVALID,"Invalid separator suggested.") + X(SRS_ENOSECRETS, "No secrets in SRS configuration.") + X(SRS_ESEPARATORINVALID, "Invalid separator suggested.") /* Input errors */ - X(SRS_ENOSENDERATSIGN,"No at sign in sender address") - X(SRS_EBUFTOOSMALL,"Buffer too small.") + X(SRS_ENOSENDERATSIGN, "No at sign in sender address") + X(SRS_EBUFTOOSMALL, "Buffer too small.") /* Syntax errors */ - X(SRS_ENOSRS0HOST,"No host in SRS0 address.") - X(SRS_ENOSRS0USER,"No user in SRS0 address.") - X(SRS_ENOSRS0HASH,"No hash in SRS0 address.") - X(SRS_ENOSRS0STAMP,"No timestamp in SRS0 address.") - X(SRS_ENOSRS1HOST,"No host in SRS1 address.") - X(SRS_ENOSRS1USER,"No user in SRS1 address.") - X(SRS_ENOSRS1HASH,"No hash in SRS1 address.") - X(SRS_EBADTIMESTAMPCHAR,"Bad base32 character in timestamp.") - X(SRS_EHASHTOOSHORT,"Hash too short in SRS address.") + X(SRS_ENOSRS0HOST, "No host in SRS0 address.") + X(SRS_ENOSRS0USER, "No user in SRS0 address.") + X(SRS_ENOSRS0HASH, "No hash in SRS0 address.") + X(SRS_ENOSRS0STAMP, "No timestamp in SRS0 address.") + X(SRS_ENOSRS1HOST, "No host in SRS1 address.") + X(SRS_ENOSRS1USER, "No user in SRS1 address.") + X(SRS_ENOSRS1HASH, "No hash in SRS1 address.") + X(SRS_EBADTIMESTAMPCHAR, "Bad base32 character in timestamp.") + X(SRS_EHASHTOOSHORT, "Hash too short in SRS address.") /* SRS errors */ - X(SRS_ETIMESTAMPOUTOFDATE,"Time stamp out of date.") - X(SRS_EHASHINVALID,"Hash invalid in SRS address.") + X(SRS_ETIMESTAMPOUTOFDATE, "Time stamp out of date.") + X(SRS_EHASHINVALID, "Hash invalid in SRS address.") - return "Unknown SRS error."; + return "Unknown SRS error."; } srs_t *srs_new() { - srs_t *srs = (srs_t *)srs_f_malloc(sizeof(srs_t)); - srs_init(srs); - return srs; + srs_t *srs = (srs_t *)srs_f_malloc(sizeof(srs_t)); + srs_init(srs); + return srs; } void srs_init(srs_t *srs) { - memset(srs, 0, sizeof(srs_t)); - srs->secrets = NULL; - srs->numsecrets = 0; - srs->separator = '='; - srs->maxage = 21; - srs->hashlen = 4; - srs->hashmin = srs->hashlen; - srs->alwaysrewrite = FALSE; + memset(srs, 0, sizeof(srs_t)); + srs->secrets = NULL; + srs->numsecrets = 0; + srs->separator = '='; + srs->maxage = 21; + srs->hashlen = 4; + srs->hashmin = srs->hashlen; + srs->alwaysrewrite = FALSE; } void srs_free(srs_t *srs) { - int i; - for (i = 0; i < srs->numsecrets; i++) { - memset(srs->secrets[i], 0, strlen(srs->secrets[i])); - srs_f_free(srs->secrets[i]); - srs->secrets[i] = '\0'; - } - srs_f_free(srs); + int i; + for (i = 0; i < srs->numsecrets; i++) { + memset(srs->secrets[i], 0, strlen(srs->secrets[i])); + srs_f_free(srs->secrets[i]); + srs->secrets[i] = '\0'; + } + srs_f_free(srs); } int srs_add_secret(srs_t *srs, const char *secret) { - int newlen = (srs->numsecrets + 1) * sizeof(char *); - srs->secrets = (char **)srs_f_realloc(srs->secrets, newlen); - srs->secrets[srs->numsecrets++] = strdup(secret); - return SRS_SUCCESS; + int newlen = (srs->numsecrets + 1) * sizeof(char *); + srs->secrets = (char **)srs_f_realloc(srs->secrets, newlen); + srs->secrets[srs->numsecrets++] = strdup(secret); + return SRS_SUCCESS; } const char *srs_get_secret(srs_t *srs, int idx) { - if (idx < srs->numsecrets) - return srs->secrets[idx]; - return NULL; + if (idx < srs->numsecrets) return srs->secrets[idx]; + return NULL; } -#define SRS_PARAM_DEFINE(n, t) \ - int srs_set_ ## n (srs_t *srs, t value) { \ - srs->n = value; \ - return SRS_SUCCESS; \ - } \ - t srs_get_ ## n (srs_t *srs) { \ - return srs->n; \ - } +#define SRS_PARAM_DEFINE(n, t) \ + int srs_set_##n(srs_t *srs, t value) \ + { \ + srs->n = value; \ + return SRS_SUCCESS; \ + } \ + t srs_get_##n(srs_t *srs) \ + { \ + return srs->n; \ + } int srs_set_separator(srs_t *srs, char value) { - if (strchr(srs_separators, value) == NULL) - return SRS_ESEPARATORINVALID; - srs->separator = value; - return SRS_SUCCESS; + if (strchr(srs_separators, value) == NULL) return SRS_ESEPARATORINVALID; + srs->separator = value; + return SRS_SUCCESS; } char srs_get_separator(srs_t *srs) { - return srs->separator; + return srs->separator; } SRS_PARAM_DEFINE(maxage, int) - /* XXX Check hashlen >= hashmin */ +/* XXX Check hashlen >= hashmin */ SRS_PARAM_DEFINE(hashlen, int) SRS_PARAM_DEFINE(hashmin, int) SRS_PARAM_DEFINE(alwaysrewrite, srs_bool) @@ -175,467 +179,421 @@ SRS_PARAM_DEFINE(noreverse, srs_bool) * enough to rewrite the timestamp functions. These are based on * a 2 character timestamp. Changing these in the wild is probably * a bad idea. */ -#define SRS_TIME_PRECISION (60 * 60 * 24) /* One day */ -#define SRS_TIME_BASEBITS 5 /* 2^5 = 32 = strlen(CHARS) */ +#define SRS_TIME_PRECISION (60 * 60 * 24) /* One day */ +#define SRS_TIME_BASEBITS 5 /* 2^5 = 32 = strlen(CHARS) */ /* This had better be a real variable since we do arithmethic * with it. */ const char *SRS_TIME_BASECHARS = "ABCDEFGHIJKLMNOPQRSTUVWXYZ234567"; -#define SRS_TIME_SIZE 2 -#define SRS_TIME_SLOTS (1<<(SRS_TIME_BASEBITS<<(SRS_TIME_SIZE-1))) +#define SRS_TIME_SIZE 2 +#define SRS_TIME_SLOTS (1 << (SRS_TIME_BASEBITS << (SRS_TIME_SIZE - 1))) int srs_timestamp_create(srs_t *srs, char *buf, time_t now) { - now = now / SRS_TIME_PRECISION; - buf[1] = SRS_TIME_BASECHARS[now & ((1 << SRS_TIME_BASEBITS) - 1)]; - now = now >> SRS_TIME_BASEBITS; - buf[0] = SRS_TIME_BASECHARS[now & ((1 << SRS_TIME_BASEBITS) - 1)]; - buf[2] = '\0'; - return SRS_SUCCESS; + now = now / SRS_TIME_PRECISION; + buf[1] = SRS_TIME_BASECHARS[now & ((1 << SRS_TIME_BASEBITS) - 1)]; + now = now >> SRS_TIME_BASEBITS; + buf[0] = SRS_TIME_BASECHARS[now & ((1 << SRS_TIME_BASEBITS) - 1)]; + buf[2] = '\0'; + return SRS_SUCCESS; } int srs_timestamp_check(srs_t *srs, const char *stamp) { - const char *sp; - char *bp; - int off; - time_t now; - time_t then; - - /* We had better go around this loop exactly twice! */ - then = 0; - for (sp = stamp; *sp; sp++) { - bp = strchr(SRS_TIME_BASECHARS, toupper(*sp)); - if (bp == NULL) - return SRS_EBADTIMESTAMPCHAR; - off = bp - SRS_TIME_BASECHARS; - then = (then << SRS_TIME_BASEBITS) | off; - } - - time(&now); - now = (now / SRS_TIME_PRECISION) % SRS_TIME_SLOTS; - while (now < then) - now = now + SRS_TIME_SLOTS; - - if (now <= then + srs->maxage) - return SRS_SUCCESS; - return SRS_ETIMESTAMPOUTOFDATE; + const char *sp; + char *bp; + int off; + time_t now; + time_t then; + + /* We had better go around this loop exactly twice! */ + then = 0; + for (sp = stamp; *sp; sp++) { + bp = strchr(SRS_TIME_BASECHARS, toupper(*sp)); + if (bp == NULL) return SRS_EBADTIMESTAMPCHAR; + off = bp - SRS_TIME_BASECHARS; + then = (then << SRS_TIME_BASEBITS) | off; + } + + time(&now); + now = (now / SRS_TIME_PRECISION) % SRS_TIME_SLOTS; + while (now < then) now = now + SRS_TIME_SLOTS; + + if (now <= then + srs->maxage) return SRS_SUCCESS; + return SRS_ETIMESTAMPOUTOFDATE; } -const char *SRS_HASH_BASECHARS = "ABCDEFGHIJKLMNOPQRSTUVWXYZ" - "abcdefghijklmnopqrstuvwxyz" - "0123456789+/"; +const char *SRS_HASH_BASECHARS = + "ABCDEFGHIJKLMNOPQRSTUVWXYZ" + "abcdefghijklmnopqrstuvwxyz" + "0123456789+/"; static void srs_hash_create_v(srs_t *srs, int idx, char *buf, int nargs, va_list ap) { - sha1_ctx ctx; - char srshash[SHA1_DIGESTSIZE + 1]; - char *secret; - char *data; - int len; - char *lcdata; - unsigned char *hp; - char *bp; - int i; - int j; - - secret = srs->secrets[idx]; - sha1_init(&ctx); - sha1_update(&ctx, secret, strlen(secret)); - - for (i = 0; i < nargs; i++) { - data = va_arg(ap, char *); - len = strlen(data); - lcdata = alloca(len + 1); - for (j = 0; j < len; j++) { - if (isupper(data[j])) - lcdata[j] = tolower(data[j]); - else - lcdata[j] = data[j]; - } - sha1_update(&ctx, lcdata, len); - } - - sha1_final(srshash, &ctx); /* args inverted */ - srshash[SHA1_DIGESTSIZE] = '\0'; - - /* A little base64 encoding. Just a little. */ - hp = (unsigned char *)srshash; - bp = buf; - for (i = 0; i < srs->hashlen; i++) { - switch (i & 0x03) { - default: /* NOTREACHED */ - case 0: - j = (*hp >> 2); - break; - case 1: - j = ((*hp & 0x03) << 4) | - ((*(hp + 1) & 0xF0) >> 4); - hp++; - break; - case 2: - j = ((*hp & 0x0F) << 2) | - ((*(hp + 1) & 0xC0) >> 6); - hp++; - break; - case 3: - j = (*hp++ & 0x3F); - break; - } - *bp++ = SRS_HASH_BASECHARS[j]; - } - - *bp = '\0'; - buf[srs->hashlen] = '\0'; + sha1_ctx ctx; + char srshash[SHA1_DIGESTSIZE + 1]; + char *secret; + char *data; + int len; + char *lcdata; + unsigned char *hp; + char *bp; + int i; + int j; + + secret = srs->secrets[idx]; + sha1_init(&ctx); + sha1_update(&ctx, secret, strlen(secret)); + + for (i = 0; i < nargs; i++) { + data = va_arg(ap, char *); + len = strlen(data); + lcdata = alloca(len + 1); + for (j = 0; j < len; j++) { + if (isupper(data[j])) + lcdata[j] = tolower(data[j]); + else + lcdata[j] = data[j]; + } + sha1_update(&ctx, lcdata, len); + } + + sha1_final(srshash, &ctx); /* args inverted */ + srshash[SHA1_DIGESTSIZE] = '\0'; + + /* A little base64 encoding. Just a little. */ + hp = (unsigned char *)srshash; + bp = buf; + for (i = 0; i < srs->hashlen; i++) { + switch (i & 0x03) { + default: /* NOTREACHED */ + case 0: j = (*hp >> 2); break; + case 1: + j = ((*hp & 0x03) << 4) | ((*(hp + 1) & 0xF0) >> 4); + hp++; + break; + case 2: + j = ((*hp & 0x0F) << 2) | ((*(hp + 1) & 0xC0) >> 6); + hp++; + break; + case 3: j = (*hp++ & 0x3F); break; + } + *bp++ = SRS_HASH_BASECHARS[j]; + } + + *bp = '\0'; + buf[srs->hashlen] = '\0'; } int srs_hash_create(srs_t *srs, char *buf, int nargs, ...) { - va_list ap; + va_list ap; - if (srs->numsecrets == 0) - return SRS_ENOSECRETS; - if (srs->secrets == NULL) - return SRS_ENOSECRETS; - if (srs->secrets[0] == NULL) - return SRS_ENOSECRETS; + if (srs->numsecrets == 0) return SRS_ENOSECRETS; + if (srs->secrets == NULL) return SRS_ENOSECRETS; + if (srs->secrets[0] == NULL) return SRS_ENOSECRETS; - va_start(ap, nargs); - srs_hash_create_v(srs, 0, buf, nargs, ap); - va_end(ap); + va_start(ap, nargs); + srs_hash_create_v(srs, 0, buf, nargs, ap); + va_end(ap); - return SRS_SUCCESS; + return SRS_SUCCESS; } int srs_hash_check(srs_t *srs, char *hash, int nargs, ...) { - va_list ap; - char *srshash; - char *tmp; - int len; - int i; - - len = strlen(hash); - if (len < srs->hashmin) - return SRS_EHASHTOOSHORT; - if (len < srs->hashlen) { - tmp = alloca(srs->hashlen + 1); - strncpy(tmp, hash, srs->hashlen); - tmp[srs->hashlen] = '\0'; - hash = tmp; - len = srs->hashlen; - } - - for (i = 0; i < srs->numsecrets; i++) { - va_start(ap, nargs); - srshash = alloca(srs->hashlen + 1); - srs_hash_create_v(srs, i, srshash, nargs, ap); - va_end(ap); - if (strncasecmp(hash, srshash, len) == 0) - return SRS_SUCCESS; - } - - return SRS_EHASHINVALID; + va_list ap; + char *srshash; + char *tmp; + int len; + int i; + + len = strlen(hash); + if (len < srs->hashmin) return SRS_EHASHTOOSHORT; + if (len < srs->hashlen) { + tmp = alloca(srs->hashlen + 1); + strncpy(tmp, hash, srs->hashlen); + tmp[srs->hashlen] = '\0'; + hash = tmp; + len = srs->hashlen; + } + + for (i = 0; i < srs->numsecrets; i++) { + va_start(ap, nargs); + srshash = alloca(srs->hashlen + 1); + srs_hash_create_v(srs, i, srshash, nargs, ap); + va_end(ap); + if (strncasecmp(hash, srshash, len) == 0) return SRS_SUCCESS; + } + + return SRS_EHASHINVALID; } -int srs_compile_shortcut(srs_t *srs, - char *buf, int buflen, - char *sendhost, char *senduser, - const char *aliashost) { - char *srshash; - char srsstamp[SRS_TIME_SIZE + 1]; - int len; - int ret; - - /* This never happens if we get called from guarded() */ - if ((strncasecmp(senduser, SRS0TAG, 4) == 0) && - (strchr(srs_separators, senduser[4]) != NULL)) { - sendhost = senduser + 5; - if (*sendhost == '\0') - return SRS_ENOSRS0HOST; - senduser = strchr(sendhost, SRSSEP); - if ((senduser == NULL) || (*senduser == '\0')) - return SRS_ENOSRS0USER; - } - - len = strlen(SRS0TAG) + 1 + - srs->hashlen + 1 + - SRS_TIME_SIZE + 1 + - strlen(sendhost) + 1 + strlen(senduser) - + 1 + strlen(aliashost); - if (len >= buflen) - return SRS_EBUFTOOSMALL; - - ret = srs_timestamp_create(srs, srsstamp, time(NULL)); - if (ret != SRS_SUCCESS) - return ret; - srshash = alloca(srs->hashlen + 1); - ret = srs_hash_create(srs, srshash,3, srsstamp, sendhost, senduser); - if (ret != SRS_SUCCESS) - return ret; - - sprintf(buf, SRS0TAG "%c%s%c%s%c%s%c%s@%s", srs->separator, - srshash, SRSSEP, srsstamp, SRSSEP, - sendhost, SRSSEP, senduser, - aliashost); - - return SRS_SUCCESS; +int srs_compile_shortcut( + srs_t *srs, char *buf, int buflen, char *sendhost, char *senduser, const char *aliashost) +{ + char *srshash; + char srsstamp[SRS_TIME_SIZE + 1]; + int len; + int ret; + + /* This never happens if we get called from guarded() */ + if ((strncasecmp(senduser, SRS0TAG, 4) == 0) && (strchr(srs_separators, senduser[4]) != NULL)) { + sendhost = senduser + 5; + if (*sendhost == '\0') return SRS_ENOSRS0HOST; + senduser = strchr(sendhost, SRSSEP); + if ((senduser == NULL) || (*senduser == '\0')) return SRS_ENOSRS0USER; + } + + len = strlen(SRS0TAG) + 1 + srs->hashlen + 1 + SRS_TIME_SIZE + 1 + strlen(sendhost) + 1 + + strlen(senduser) + 1 + strlen(aliashost); + if (len >= buflen) return SRS_EBUFTOOSMALL; + + ret = srs_timestamp_create(srs, srsstamp, time(NULL)); + if (ret != SRS_SUCCESS) return ret; + srshash = alloca(srs->hashlen + 1); + ret = srs_hash_create(srs, srshash, 3, srsstamp, sendhost, senduser); + if (ret != SRS_SUCCESS) return ret; + + sprintf( + buf, + SRS0TAG "%c%s%c%s%c%s%c%s@%s", + srs->separator, + srshash, + SRSSEP, + srsstamp, + SRSSEP, + sendhost, + SRSSEP, + senduser, + aliashost); + + return SRS_SUCCESS; } -int srs_compile_guarded(srs_t *srs, - char *buf, int buflen, - char *sendhost, char *senduser, - const char *aliashost) { - char *srshost; - char *srsuser; - char *srshash; - int len; - int ret; - - if ((strncasecmp(senduser, SRS1TAG, 4) == 0) && - (strchr(srs_separators, senduser[4]) != NULL)) { - /* Used as a temporary convenience var */ - srshash = senduser + 5; - if (*srshash == '\0') - return SRS_ENOSRS1HASH; - /* Used as a temporary convenience var */ - srshost = strchr(srshash, SRSSEP); - if (!STRINGP(srshost)) - return SRS_ENOSRS1HOST; - *srshost++ = '\0'; - srsuser = strchr(srshost, SRSSEP); - if (!STRINGP(srsuser)) - return SRS_ENOSRS1USER; - *srsuser++ = '\0'; - srshash = alloca(srs->hashlen + 1); - ret = srs_hash_create(srs, srshash, 2, srshost, srsuser); - if (ret != SRS_SUCCESS) - return ret; - len = strlen(SRS1TAG) + 1 + - srs->hashlen + 1 + - strlen(srshost) + 1 + strlen(srsuser) - + 1 + strlen(aliashost); - if (len >= buflen) - return SRS_EBUFTOOSMALL; - sprintf(buf, SRS1TAG "%c%s%c%s%c%s@%s", srs->separator, - srshash, SRSSEP, - srshost, SRSSEP, srsuser, - aliashost); - return SRS_SUCCESS; - } - else if ((strncasecmp(senduser, SRS0TAG, 4) == 0) && - (strchr(srs_separators, senduser[4]) != NULL)) { - srsuser = senduser + 4; - srshost = sendhost; - srshash = alloca(srs->hashlen + 1); - ret = srs_hash_create(srs, srshash, 2, srshost, srsuser); - if (ret != SRS_SUCCESS) - return ret; - len = strlen(SRS1TAG) + 1 + - srs->hashlen + 1 + - strlen(srshost) + 1 + strlen(srsuser) - + 1 + strlen(aliashost); - if (len >= buflen) - return SRS_EBUFTOOSMALL; - sprintf(buf, SRS1TAG "%c%s%c%s%c%s@%s", srs->separator, - srshash, SRSSEP, - srshost, SRSSEP, srsuser, - aliashost); - } - else { - return srs_compile_shortcut(srs, buf, buflen, - sendhost, senduser, aliashost); - } - - return SRS_SUCCESS; +int srs_compile_guarded( + srs_t *srs, char *buf, int buflen, char *sendhost, char *senduser, const char *aliashost) +{ + char *srshost; + char *srsuser; + char *srshash; + int len; + int ret; + + if ((strncasecmp(senduser, SRS1TAG, 4) == 0) && (strchr(srs_separators, senduser[4]) != NULL)) { + /* Used as a temporary convenience var */ + srshash = senduser + 5; + if (*srshash == '\0') return SRS_ENOSRS1HASH; + /* Used as a temporary convenience var */ + srshost = strchr(srshash, SRSSEP); + if (!STRINGP(srshost)) return SRS_ENOSRS1HOST; + *srshost++ = '\0'; + srsuser = strchr(srshost, SRSSEP); + if (!STRINGP(srsuser)) return SRS_ENOSRS1USER; + *srsuser++ = '\0'; + srshash = alloca(srs->hashlen + 1); + ret = srs_hash_create(srs, srshash, 2, srshost, srsuser); + if (ret != SRS_SUCCESS) return ret; + len = strlen(SRS1TAG) + 1 + srs->hashlen + 1 + strlen(srshost) + 1 + strlen(srsuser) + 1 + + strlen(aliashost); + if (len >= buflen) return SRS_EBUFTOOSMALL; + sprintf( + buf, + SRS1TAG "%c%s%c%s%c%s@%s", + srs->separator, + srshash, + SRSSEP, + srshost, + SRSSEP, + srsuser, + aliashost); + return SRS_SUCCESS; + } else if ((strncasecmp(senduser, SRS0TAG, 4) == 0) && (strchr(srs_separators, senduser[4]) != NULL)) { + srsuser = senduser + 4; + srshost = sendhost; + srshash = alloca(srs->hashlen + 1); + ret = srs_hash_create(srs, srshash, 2, srshost, srsuser); + if (ret != SRS_SUCCESS) return ret; + len = strlen(SRS1TAG) + 1 + srs->hashlen + 1 + strlen(srshost) + 1 + strlen(srsuser) + 1 + + strlen(aliashost); + if (len >= buflen) return SRS_EBUFTOOSMALL; + sprintf( + buf, + SRS1TAG "%c%s%c%s%c%s@%s", + srs->separator, + srshash, + SRSSEP, + srshost, + SRSSEP, + srsuser, + aliashost); + } else { + return srs_compile_shortcut(srs, buf, buflen, sendhost, senduser, aliashost); + } + + return SRS_SUCCESS; } int srs_parse_shortcut(srs_t *srs, char *buf, int buflen, char *senduser) { - char *srshash; - char *srsstamp; - char *srshost; - char *srsuser; - int ret; - - if (strncasecmp(senduser, SRS0TAG, 4) == 0) { - srshash = senduser + 5; - if (!STRINGP(srshash)) - return SRS_ENOSRS0HASH; - srsstamp = strchr(srshash, SRSSEP); - if (!STRINGP(srsstamp)) - return SRS_ENOSRS0STAMP; - *srsstamp++ = '\0'; - srshost = strchr(srsstamp, SRSSEP); - if (!STRINGP(srshost)) - return SRS_ENOSRS0HOST; - *srshost++ = '\0'; - srsuser = strchr(srshost, SRSSEP); - if (!STRINGP(srsuser)) - return SRS_ENOSRS0USER; - *srsuser++ = '\0'; - ret = srs_timestamp_check(srs, srsstamp); - if (ret != SRS_SUCCESS) - return ret; - ret = srs_hash_check(srs, srshash, 3, srsstamp, - srshost, srsuser); - if (ret != SRS_SUCCESS) - return ret; - sprintf(buf, "%s@%s", srsuser, srshost); - return SRS_SUCCESS; - } - - return SRS_ENOTSRSADDRESS; + char *srshash; + char *srsstamp; + char *srshost; + char *srsuser; + int ret; + + if (strncasecmp(senduser, SRS0TAG, 4) == 0) { + srshash = senduser + 5; + if (!STRINGP(srshash)) return SRS_ENOSRS0HASH; + srsstamp = strchr(srshash, SRSSEP); + if (!STRINGP(srsstamp)) return SRS_ENOSRS0STAMP; + *srsstamp++ = '\0'; + srshost = strchr(srsstamp, SRSSEP); + if (!STRINGP(srshost)) return SRS_ENOSRS0HOST; + *srshost++ = '\0'; + srsuser = strchr(srshost, SRSSEP); + if (!STRINGP(srsuser)) return SRS_ENOSRS0USER; + *srsuser++ = '\0'; + ret = srs_timestamp_check(srs, srsstamp); + if (ret != SRS_SUCCESS) return ret; + ret = srs_hash_check(srs, srshash, 3, srsstamp, srshost, srsuser); + if (ret != SRS_SUCCESS) return ret; + sprintf(buf, "%s@%s", srsuser, srshost); + return SRS_SUCCESS; + } + + return SRS_ENOTSRSADDRESS; } int srs_parse_guarded(srs_t *srs, char *buf, int buflen, char *senduser) { - char *srshash; - char *srshost; - char *srsuser; - int ret; - - if (strncasecmp(senduser, SRS1TAG, 4) == 0) { - srshash = senduser + 5; - if (!STRINGP(srshash)) - return SRS_ENOSRS1HASH; - srshost = strchr(srshash, SRSSEP); - if (!STRINGP(srshost)) - return SRS_ENOSRS1HOST; - *srshost++ = '\0'; - srsuser = strchr(srshost, SRSSEP); - if (!STRINGP(srsuser)) - return SRS_ENOSRS1USER; - *srsuser++ = '\0'; - ret = srs_hash_check(srs, srshash, 2, srshost, srsuser); - if (ret != SRS_SUCCESS) - return ret; - sprintf(buf, SRS0TAG "%s@%s", srsuser, srshost); - return SRS_SUCCESS; - } - else { - return srs_parse_shortcut(srs, buf, buflen, senduser); - } + char *srshash; + char *srshost; + char *srsuser; + int ret; + + if (strncasecmp(senduser, SRS1TAG, 4) == 0) { + srshash = senduser + 5; + if (!STRINGP(srshash)) return SRS_ENOSRS1HASH; + srshost = strchr(srshash, SRSSEP); + if (!STRINGP(srshost)) return SRS_ENOSRS1HOST; + *srshost++ = '\0'; + srsuser = strchr(srshost, SRSSEP); + if (!STRINGP(srsuser)) return SRS_ENOSRS1USER; + *srsuser++ = '\0'; + ret = srs_hash_check(srs, srshash, 2, srshost, srsuser); + if (ret != SRS_SUCCESS) return ret; + sprintf(buf, SRS0TAG "%s@%s", srsuser, srshost); + return SRS_SUCCESS; + } else { + return srs_parse_shortcut(srs, buf, buflen, senduser); + } } -int srs_forward(srs_t *srs, char *buf, int buflen, - const char *sender, const char *alias) +int srs_forward(srs_t *srs, char *buf, int buflen, const char *sender, const char *alias) { - char *senduser; - char *sendhost; - char *tmp; - int len; - - if (srs->noforward) - return SRS_ENOTREWRITTEN; - - /* This is allowed to be a plain domain */ - while ((tmp = strchr(alias, '@')) != NULL) - alias = tmp + 1; - - tmp = strchr(sender, '@'); - if (tmp == NULL) - return SRS_ENOSENDERATSIGN; - sendhost = tmp + 1; - - len = strlen(sender); - - if (! srs->alwaysrewrite) { - if (strcasecmp(sendhost, alias) == 0) { - if (strlen(sender) >= buflen) - return SRS_EBUFTOOSMALL; - strcpy(buf, sender); - return SRS_SUCCESS; - } - } - - /* Reconstruct the whole show into our alloca() buffer. */ - senduser = alloca(len + 1); - strcpy(senduser, sender); - tmp = (senduser + (tmp - sender)); - sendhost = tmp + 1; - *tmp = '\0'; - - return srs_compile_guarded(srs, buf, buflen, - sendhost, senduser, alias); + char *senduser; + char *sendhost; + char *tmp; + int len; + + if (srs->noforward) return SRS_ENOTREWRITTEN; + + /* This is allowed to be a plain domain */ + while ((tmp = strchr(alias, '@')) != NULL) alias = tmp + 1; + + tmp = strchr(sender, '@'); + if (tmp == NULL) return SRS_ENOSENDERATSIGN; + sendhost = tmp + 1; + + len = strlen(sender); + + if (!srs->alwaysrewrite) { + if (strcasecmp(sendhost, alias) == 0) { + if (strlen(sender) >= buflen) return SRS_EBUFTOOSMALL; + strcpy(buf, sender); + return SRS_SUCCESS; + } + } + + /* Reconstruct the whole show into our alloca() buffer. */ + senduser = alloca(len + 1); + strcpy(senduser, sender); + tmp = (senduser + (tmp - sender)); + sendhost = tmp + 1; + *tmp = '\0'; + + return srs_compile_guarded(srs, buf, buflen, sendhost, senduser, alias); } -int srs_forward_alloc(srs_t *srs, char **sptr, - const char *sender, const char *alias) +int srs_forward_alloc(srs_t *srs, char **sptr, const char *sender, const char *alias) { - char *buf; - int slen; - int alen; - int len; - int ret; + char *buf; + int slen; + int alen; + int len; + int ret; - if (srs->noforward) - return SRS_ENOTREWRITTEN; + if (srs->noforward) return SRS_ENOTREWRITTEN; - slen = strlen(sender); - alen = strlen(alias); + slen = strlen(sender); + alen = strlen(alias); - /* strlen(SRSxTAG) + strlen("====+@") < 64 */ - len = slen + alen + srs->hashlen + SRS_TIME_SIZE + 64; - buf = (char *)srs_f_malloc(len); + /* strlen(SRSxTAG) + strlen("====+@") < 64 */ + len = slen + alen + srs->hashlen + SRS_TIME_SIZE + 64; + buf = (char *)srs_f_malloc(len); - ret = srs_forward(srs, buf, len, sender, alias); + ret = srs_forward(srs, buf, len, sender, alias); - if (ret == SRS_SUCCESS) - *sptr = buf; - else - srs_f_free(buf); + if (ret == SRS_SUCCESS) + *sptr = buf; + else + srs_f_free(buf); - return ret; + return ret; } int srs_reverse(srs_t *srs, char *buf, int buflen, const char *sender) { - char *senduser; - char *tmp; - int len; - - if (!SRS_IS_SRS_ADDRESS(sender)) - return SRS_ENOTSRSADDRESS; - - if (srs->noreverse) - return SRS_ENOTREWRITTEN; - - len = strlen(sender); - if (len >= buflen) - return SRS_EBUFTOOSMALL; - senduser = alloca(len + 1); - strcpy(senduser, sender); - - /* We don't really care about the host for reversal. */ - tmp = strchr(senduser, '@'); - if (tmp != NULL) - *tmp = '\0'; - return srs_parse_guarded(srs, buf, buflen, senduser); + char *senduser; + char *tmp; + int len; + + if (!SRS_IS_SRS_ADDRESS(sender)) return SRS_ENOTSRSADDRESS; + + if (srs->noreverse) return SRS_ENOTREWRITTEN; + + len = strlen(sender); + if (len >= buflen) return SRS_EBUFTOOSMALL; + senduser = alloca(len + 1); + strcpy(senduser, sender); + + /* We don't really care about the host for reversal. */ + tmp = strchr(senduser, '@'); + if (tmp != NULL) *tmp = '\0'; + return srs_parse_guarded(srs, buf, buflen, senduser); } int srs_reverse_alloc(srs_t *srs, char **sptr, const char *sender) { - char *buf; - int len; - int ret; + char *buf; + int len; + int ret; - *sptr = NULL; + *sptr = NULL; - if (!SRS_IS_SRS_ADDRESS(sender)) - return SRS_ENOTSRSADDRESS; + if (!SRS_IS_SRS_ADDRESS(sender)) return SRS_ENOTSRSADDRESS; - if (srs->noreverse) - return SRS_ENOTREWRITTEN; + if (srs->noreverse) return SRS_ENOTREWRITTEN; - len = strlen(sender) + 1; - buf = (char *)srs_f_malloc(len); + len = strlen(sender) + 1; + buf = (char *)srs_f_malloc(len); - ret = srs_reverse(srs, buf, len, sender); + ret = srs_reverse(srs, buf, len, sender); - if (ret == SRS_SUCCESS) - *sptr = buf; - else - srs_f_free(buf); + if (ret == SRS_SUCCESS) + *sptr = buf; + else + srs_f_free(buf); - return ret; + return ret; } |