typedef struct srs_config_t {
srs_t* srs;
const char* domain;
+ int domainlen;
+ int ignore_ext;
} srs_config_t;
/* Processing {{{1
*/
-void urldecode(char *s, char *end)
+char *urldecode(char *s, char *end)
{
char *p = s;
*s++ = *p++;
}
- *s++ = '\0';
+ *s = '\0';
+ return s;
}
int process_srs(client_t *srsd, void* vconfig)
goto skip;
}
- urldecode(p, q);
+ q = urldecode(p, q);
if (decoder) {
+ if (config->ignore_ext) {
+ int dlen = config->domainlen;
+
+ if (q - p <= dlen || q[-1 - dlen] != '@' ||
+ memcmp(q - dlen, config->domain, dlen))
+ {
+ buffer_addstr(obuf, "200 ");
+ buffer_add(obuf, p, q - p);
+ buffer_addch(obuf, '\n');
+ goto skip;
+ }
+ }
err = srs_reverse(config->srs, buf, ssizeof(buf), p);
} else {
err = srs_forward(config->srs, buf, ssizeof(buf), p, config->domain);
" (default: "STR(DEFAULT_DECODER_PORT)")\n"
" -p <pidfile> file to write our pid to\n"
" -u unsafe mode: don't drop privilegies\n"
+ " -I do not touch mails outside of \"domain\" in decoding mode\n"
" -f stay in foreground\n"
, stderr);
}
int port_dec = DEFAULT_DECODER_PORT;
const char *pidfile = NULL;
- for (int c = 0; (c = getopt(argc, argv, "hfu" "e:d:p:")) >= 0; ) {
+ for (int c = 0; (c = getopt(argc, argv, "hfuI" "e:d:p:")) >= 0; ) {
switch (c) {
case 'e':
port_enc = atoi(optarg);
case 'u':
unsafe = true;
break;
+ case 'I':
+ config.ignore_ext = true;
+ break;
default:
usage();
return EXIT_FAILURE;
info("%s v%s...", DAEMON_NAME, DAEMON_VERSION);
config.domain = argv[optind];
+ config.domainlen = strlen(config.domain);
config.srs = srs_read_secrets(argv[optind + 1]);
if (!config.srs
|| common_setup(pidfile, unsafe, RUNAS_USER, RUNAS_GROUP,