int main(int argc, char **argv) { VSTRING *inbuf = vstring_alloc(100); VSTRING *result = vstring_alloc(100); char *bufp; char *cmd; char *target; char *junk; mail_conf_read(); while (vstring_get_nonl(inbuf, VSTREAM_IN) != VSTREAM_EOF) { bufp = STR(inbuf); if (!isatty(0)) { vstream_printf("> %s\n", bufp); vstream_fflush(VSTREAM_OUT); } if (*bufp == '#') continue; if ((cmd = mystrtok(&bufp, " \t")) == 0) { vstream_printf("usage: file path|map maptype:mapname\n"); vstream_fflush(VSTREAM_OUT); continue; } target = mystrtok(&bufp, " \t"); junk = mystrtok(&bufp, " \t"); if (strcmp(cmd, "file") == 0 && target && !junk) { data_redirect_file(result, target); vstream_printf("%s -> %s\n", target, STR(result)); } else if (strcmp(cmd, "map") == 0 && target && !junk) { data_redirect_map(result, target); vstream_printf("%s -> %s\n", target, STR(result)); } else { vstream_printf("usage: file path|map maptype:mapname\n"); } vstream_fflush(VSTREAM_OUT); } vstring_free(inbuf); return (0); }
static void tlsmgr_pre_init(char *unused_name, char **unused_argv) { char *path; struct timeval tv; TLSMGR_SCACHE *ent; VSTRING *redirect; HTABLE *dup_filter; const char *dup_label; /* * If nothing else works then at least this will get us a few bits of * entropy. * * XXX This is our first call into the OpenSSL library. We should find out * if this can be moved to the post-jail initialization phase, without * breaking compatibility with existing installations. */ GETTIMEOFDAY(&tv); tv.tv_sec ^= getpid(); RAND_seed(&tv, sizeof(struct timeval)); /* * Open the external entropy source. We will not be able to open it again * after we are sent to chroot jail, so we keep it open. Errors are not * fatal. The exchange file (see below) is the only entropy source that * really matters in the long run. * * Security note: we open the entropy source while privileged, but we don't * access the source until after we release privileges. This way, none of * the OpenSSL code gets to execute while we are privileged. */ if (*var_tls_rand_source) { /* * Source is a random device. */ if (!strncmp(var_tls_rand_source, DEV_PREF, DEV_PREF_LEN)) { path = DEV_PATH(var_tls_rand_source); rand_source_dev = tls_prng_dev_open(path, TLS_MGR_TIMEOUT); if (rand_source_dev == 0) msg_warn("cannot open entropy device %s: %m", path); } /* * Source is an EGD compatible socket. */ else if (!strncmp(var_tls_rand_source, EGD_PREF, EGD_PREF_LEN)) { path = EGD_PATH(var_tls_rand_source); rand_source_egd = tls_prng_egd_open(path, TLS_MGR_TIMEOUT); if (rand_source_egd == 0) msg_warn("cannot connect to EGD server %s: %m", path); } /* * Source is regular file. We read this only once. */ else { rand_source_file = tls_prng_file_open(var_tls_rand_source, TLS_MGR_TIMEOUT); } } else { msg_warn("no entropy source specified with parameter %s", VAR_TLS_RAND_SOURCE); msg_warn("encryption keys etc. may be predictable"); } /* * Security: don't create root-owned files that contain untrusted data. * And don't create Postfix-owned files in root-owned directories, * either. We want a correct relationship between (file/directory) * ownership and (file/directory) content. */ SAVE_AND_SET_EUGID(var_owner_uid, var_owner_gid); redirect = vstring_alloc(100); /* * Open the PRNG exchange file before going to jail, but don't use root * privileges. Start the exchange file read/update pseudo thread after * dropping privileges. */ if (*var_tls_rand_exch_name) { rand_exch = tls_prng_exch_open(data_redirect_file(redirect, var_tls_rand_exch_name)); if (rand_exch == 0) msg_fatal("cannot open PRNG exchange file %s: %m", var_tls_rand_exch_name); } /* * Open the session cache files and discard old information before going * to jail, but don't use root privilege. Start the cache maintenance * pseudo threads after dropping privileges. */ dup_filter = htable_create(sizeof(cache_table) / sizeof(cache_table[0])); for (ent = cache_table; ent->cache_label; ++ent) { /* Sanitize session timeout */ if (*ent->cache_timeout > 0) { if (*ent->cache_timeout < TLS_SESSION_LIFEMIN) *ent->cache_timeout = TLS_SESSION_LIFEMIN; } else { *ent->cache_timeout = 0; } /* External cache database disabled if timeout is non-positive */ if (*ent->cache_timeout > 0 && **ent->cache_db) { if ((dup_label = htable_find(dup_filter, *ent->cache_db)) != 0) msg_fatal("do not use the same TLS cache file %s for %s and %s", *ent->cache_db, dup_label, ent->cache_label); htable_enter(dup_filter, *ent->cache_db, ent->cache_label); ent->cache_info = tls_scache_open(data_redirect_map(redirect, *ent->cache_db), ent->cache_label, tls_log_mask(ent->log_param, *ent->log_level) & TLS_LOG_CACHE, *ent->cache_timeout); } } htable_free(dup_filter, (void (*) (char *)) 0); /* * Clean up and restore privilege. */ vstring_free(redirect); RESTORE_SAVED_EUGID(); }