int eximsrs_init() { uschar *list = srs_config; uschar secret_buf[SRS_MAX_SECRET_LENGTH]; uschar *secret = NULL; uschar sbuf[4]; uschar *sbufp; /* Check if this instance of Exim has not initialized SRS */ if(srs == NULL) { int co = 0; int hashlen, maxage; BOOL usetimestamp, usehash; /* Copy config vars */ hashlen = srs_hashlength; maxage = srs_maxage; usetimestamp = srs_usetimestamp; usehash = srs_usehash; /* Pass srs_config var (overrides new config vars) */ co = 0; if(srs_config != NULL) { secret = string_nextinlist(&list, &co, secret_buf, SRS_MAX_SECRET_LENGTH); if((sbufp = string_nextinlist(&list, &co, sbuf, sizeof(sbuf))) != NULL) maxage = atoi(sbuf); if((sbufp = string_nextinlist(&list, &co, sbuf, sizeof(sbuf))) != NULL) hashlen = atoi(sbuf); if((sbufp = string_nextinlist(&list, &co, sbuf, sizeof(sbuf))) != NULL) usetimestamp = atoi(sbuf); if((sbufp = string_nextinlist(&list, &co, sbuf, sizeof(sbuf))) != NULL) usehash = atoi(sbuf); } if(srs_hashmin == -1) srs_hashmin = hashlen; /* First secret specified in secrets? */ co = 0; list = srs_secrets; if(secret == NULL || *secret == '\0') { if((secret = string_nextinlist(&list, &co, secret_buf, SRS_MAX_SECRET_LENGTH)) == NULL) { log_write(0, LOG_MAIN | LOG_PANIC, "SRS Configuration Error: No secret specified"); return DEFER; } } /* Check config */ if(maxage < 0 || maxage > 365) { log_write(0, LOG_MAIN | LOG_PANIC, "SRS Configuration Error: Invalid maximum timestamp age"); return DEFER; } if(hashlen < 1 || hashlen > 20 || srs_hashmin < 1 || srs_hashmin > 20) { log_write(0, LOG_MAIN | LOG_PANIC, "SRS Configuration Error: Invalid hash length"); return DEFER; } if((srs = srs_open(secret, Ustrlen(secret), maxage, hashlen, srs_hashmin)) == NULL) { log_write(0, LOG_MAIN | LOG_PANIC, "Failed to allocate SRS memory"); return DEFER; } srs_set_option(srs, SRS_OPTION_USETIMESTAMP, usetimestamp); srs_set_option(srs, SRS_OPTION_USEHASH, usehash); /* Extra secrets? */ while((secret = string_nextinlist(&list, &co, secret_buf, SRS_MAX_SECRET_LENGTH)) != NULL) srs_add_secret(srs, secret, (Ustrlen(secret) > SRS_MAX_SECRET_LENGTH) ? SRS_MAX_SECRET_LENGTH : Ustrlen(secret)); DEBUG(D_any) debug_printf("SRS initialized\n"); } return OK; }
int main(int argc, char **argv) { char c; FILE *fp; char line[BUFSIZ]; srs_t *srs; int direction = SRS_DIR_FORWARD; int daemonflags = 0; int secrets = 0; char *socketpath = "/tmp/srsd"; char *alias = NULL; char **addrs = alloca(argc * sizeof(char *)); char **addre = addrs; char **addrp; int i; srs = srs_new(); while ((c = #ifdef HAVE_GETOPT_LONG getopt_long(argc, argv, shortopts, longopts, &idx) #else getopt(argc, argv, shortopts) #endif ) != -1) { switch (c) { case 'd': daemonflags |= DF_DAEMON; break; case 'x': daemonflags |= DF_NOFORK; break; case 's': socketpath = optarg; break; case 'e': SRS_DIE_UNLESS(srs_set_separator(srs, optarg[0])); break; case 'a': *addre++ = optarg; break; case 'k': SRS_DIE_UNLESS(srs_add_secret(srs, optarg)); secrets++; break; case 'f': fp = fopen(optarg, "r"); if (fp == NULL) { fprintf(stderr, "Failed to open %s: %s\n", optarg, strerror(errno)); SRS_DIE(); } while (fgets(line, BUFSIZ, fp) != NULL) { line[strcspn(line, "\r\n")] = '\0'; if (line[0] == '#') continue; if (line[0] == '\0') continue; SRS_DIE_UNLESS(srs_add_secret(srs, line)); secrets++; } fclose(fp); break; case 'o': direction = SRS_DIR_FORWARD; break; case 'v': direction = SRS_DIR_REVERSE; break; case 'i': alias = optarg; break; case 'l': SRS_DIE_UNLESS(srs_set_hashlength(srs, atol(optarg))); break; case 'h': case '?': usage(argv[0]); SRS_DIE(); default: fprintf(stderr, "Unrecognised option %c\n", c); SRS_DIE(); } } argv += optind; argc -= optind; if (secrets == 0) { fprintf(stderr, "No secrets!\n"); SRS_DIE(); } if (daemonflags & DF_DAEMON) { rundaemon(srs, socketpath, daemonflags); SRS_DIE(); } for (i = 0; i < argc; i++) *addre++ = argv[i]; if ((direction == SRS_DIR_FORWARD) && (alias == NULL)) { fprintf(stderr, "No alias given for forwards translation. " "Please use --alias or -i.\n"); SRS_DIE(); } if (addre == addrs) { fprintf(stderr, "No alias given to translate.\n"); SRS_DIE(); } for (addrp = addrs; addrp < addre; addrp++) { if (direction == SRS_DIR_FORWARD) SRS_DIE_UNLESS(srs_forward(srs, line, BUFSIZ, *addrp, alias)); else SRS_DIE_UNLESS(srs_reverse(srs, line, BUFSIZ, *addrp)); printf("%s\n", line); } return 0; }