int eximsrs_forward(uschar **result, uschar *orig_sender, uschar *domain) { char res[512]; int n; if((n = srs_forward(srs, orig_sender, domain, res, sizeof(res))) & SRS_RESULT_FAIL) { DEBUG(D_any) debug_printf("srs_forward failed (%s, %s): %s\n", orig_sender, domain, srs_geterrormsg(n)); return DEFER; } *result = string_copy(res); return OK; }
static void rundaemon(srs_t *srs, char *path, int daemonflags) { fd_set readfds_sv; fd_set readfds; struct sockaddr_un addr; socklen_t addrlen; int sock; int maxfd; int fd; char line[BUFSIZ]; int len; char buf[BUFSIZ]; char *cp; char *address; char *alias; int ret; sock = listen_socket(path); /* daemon() */ FD_ZERO(&readfds_sv); FD_SET(sock, &readfds_sv); maxfd = sock + 1; #define FINISH(fd) \ do { close(fd); FD_CLR(fd, &readfds_sv); continue; } while(0) #define SKIPWHITE(cp) while (isspace(*cp)) cp++; if (!(daemonflags & DF_NOFORK)) { if (daemon(0, 0) < 0) perror("daemon"); } for (;;) { memcpy(&readfds, &readfds_sv, sizeof(fd_set)); select(maxfd, &readfds, NULL, NULL, NULL); for (fd = 0; fd < maxfd; fd++) { if (FD_ISSET(fd, &readfds)) { if (fd == sock) { fd = accept(sock, (struct sockaddr*)&addr,&addrlen); if (fd < 0) { perror("accept"); continue; } FD_SET(fd, &readfds_sv); if (fd >= maxfd) maxfd = fd + 1; fprintf(stderr, "Accept %d\n", fd); continue; } else { len = read(fd, line, BUFSIZ); if (len <= 0) { if (len < 0) perror("read"); fprintf(stderr, "Close %d\n", fd); FINISH(fd); } line[strcspn(line, "\r\n")] = '\0'; fprintf(stderr, "%d: %s\n", fd, line); if (strncasecmp(line, "forward ", 8) == 0) { cp = line + 8; while (isspace(*cp)) cp++; address = cp; cp = strchr(address, ' '); if (cp == NULL) { fprintf(stderr, "No alias in %s on %d\n", line, fd); FINISH(fd); } *cp++ = '\0'; while (isspace(*cp)) cp++; alias = cp; ret = srs_forward(srs, buf, BUFSIZ, address, alias); if (ret != SRS_SUCCESS) { fprintf(stderr, "SRS error: %s\n", srs_strerror(ret)); FINISH(fd); } fprintf(stderr, "Forward %s, %s -> %s\n", address, alias, buf); write(fd, buf, strlen(buf)); write(fd, "\n", 1); FINISH(fd); } else if (strncasecmp(line, "reverse ", 8) == 0) { cp = line + 8; while (isspace(*cp)) cp++; address = cp; ret = srs_reverse(srs, buf, BUFSIZ, address); if (ret != SRS_SUCCESS) { fprintf(stderr, "SRS error: %s\n", srs_strerror(ret)); FINISH(fd); } fprintf(stderr, "Reverse %s -> %s\n", address, buf); write(fd, buf, strlen(buf)); write(fd, "\n", 1); FINISH(fd); } else { fprintf(stderr, "Unknown command %s on %d\n", line, fd); FINISH(fd); } } } } } }
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; }
int main(int argc, char **argv) { char buf[1024]; char res[1024]; char starbuf[1204]; int n, m, errs = 0, star; srs_t *srs; struct timeb start, finish; printf("\nlibsrs_alt test program\n(C)2004 Miles Wilton <*****@*****.**>\n\n"); if(argc < 3 && !(argc == 2 && argv[1][0] == '~')) { printf("FORWARD Syntax: test <sender address> [*]<return/local domain>+\n\n"); printf("REVERSE Syntax: test ~<SRS address>\n\nOptional * in front of domain causes a 10000 repeat loop\non that domain. It is recommended to redirect to a file\nas output affects speed report.\n\nPrefixing ~ to first parameter performs reverse SRS on that\naddress (and no further parameters are processed)\n\n"); printf("The test utility uses a set of default values and will only successfully reverse hashes made by itself.\n\n"); exit(0); } printf("Encoding test on '%s':\n", argv[1]); n = srs__base64enc(argv[1], strlen(argv[1]), buf, 256); if(n == SRS_RESULT_OK) printf(" - base64enc: %s\n", buf); else { printf(" - base64enc: Error %d - %s\n", n, srs_geterrormsg(n)); errs++; } n = srs__base32enc(argv[1], strlen(argv[1]), buf, 256); if(n == SRS_RESULT_OK) printf(" - base32enc: %s\n", buf); else { printf(" - base32enc: Error %d - %s\n", n, srs_geterrormsg(n)); errs++; } printf("\nStarting SRS test:\n\n"); ftime(&start); if((srs = srs_open("mysecret", 8, 0, 0, 0)) == NULL) { printf("srs_open: Failed (returned NULL)\n"); errs++; } else { // srs_set_separator(srs, '+'); // srs_set_option(srs, SRS_OPTION_USETIMESTAMP, 0); // srs_set_option(srs, SRS_OPTION_USEHASH, 0); // srs_set_db_functions(srs, do_db_insert, do_db_lookup); if(argv[1][0] == '~') { strcpy(buf, &argv[1][1]); while(strncasecmp(buf, "SRS", 3) == 0) { printf("Resolving SRS address <%s>\n", buf); n = srs_reverse(srs, buf, res, 1024); if(n & SRS_RESULT_FAIL) { printf("srs_forward: Error %d - %s\n", n, srs_geterrormsg(n)); errs++; break; } else if(n != SRS_RESULT_OK) printf("srs_forward: Warning %d - %s\n", n, srs_geterrormsg(n)); printf(" - SRS forward to: <%s>\n", res); strcpy(buf, res); } } else { strcpy(buf, argv[1]); star = 0; for(m = 2; m < argc; m++) { if(argv[m][0] == '*') { sprintf(starbuf, "%d-%s", star, &argv[m][1]); star++; if(star < 10000) m--; else star = 0; } else strcpy(starbuf, argv[m]); printf("Fowarding MAIL FROM:<%s> on DOMAIN %s\n", buf, argv[m]); n = srs_forward(srs, buf, starbuf, res, 1024); if(n == SRS_RESULT_OK) printf(" - SRS return path: <%s>\n", res); else { printf("srs_forward: Error %d - %s\n", n, srs_geterrormsg(n)); errs++; break; } strcpy(buf, res); } } srs_close(srs); } ftime(&finish); if(errs) printf("\n\nThere were errors: %d\n\n", errs); else printf("\n\nTests completed successfully (%.3f seconds).\n\n", (float)(finish.time - start.time) + (float)(finish.millitm - start.millitm) / 1000); exit(errs); }