diff options
Diffstat (limited to 'src/rcfile.c')
-rw-r--r-- | src/rcfile.c | 242 |
1 files changed, 125 insertions, 117 deletions
diff --git a/src/rcfile.c b/src/rcfile.c index 27033c3..9590e5b 100644 --- a/src/rcfile.c +++ b/src/rcfile.c @@ -1,11 +1,11 @@ /* rcfile.c This file is part of GNU Anubis. - Copyright (C) 2001-2014 The Anubis Team. + Copyright (C) 2001-2024 The Anubis Team. GNU Anubis is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. @@ -168,35 +168,35 @@ open_rcfile (int method) { get_homedir (session.supervisor, homedir, sizeof (homedir)); rcfile = xmalloc (strlen (homedir) + strlen (DEFAULT_LOCAL_RCFILE) + 2); sprintf (rcfile, "%s/%s", homedir, DEFAULT_LOCAL_RCFILE); } - + if (check_filename (rcfile, &global_mtime) == 0) { free (rcfile); return; } rc_section_list_destroy (&parse_tree); file_id_destroy (); info (VERBOSE, _("Reading system configuration file %s..."), rcfile); break; - + case CF_CLIENT: if ((topt & (T_ALTRC | T_NORC)) == (T_ALTRC | T_NORC)) { rcfile = strdup (options.altrc); } else { rcfile = user_rcfile_name (); } info (VERBOSE, _("Reading user configuration file %s..."), rcfile); } - + if ((topt & T_RELAX_PERM_CHECK) == 0 && check_filemode (rcfile) == 0) { /* Wrong permissions... */ free (rcfile); return; } @@ -220,49 +220,54 @@ process_rcfile (int method) rcfile_process_section (method, "AUTH", NULL, NULL); #endif } /* ************************** The CONTROL Section ************************* */ -#define KW_BIND 0 -#define KW_TERMLEVEL 1 -#define KW_LOGLEVEL 2 -#define KW_LOGFILE 3 -#define KW_TRACEFILE 4 -#define KW_REMOTE_MTA 5 -#define KW_LOCAL_MTA 6 -#define KW_RULE_PRIORITY 7 -#define KW_CONTROL_PRIORITY 8 -#define KW_ESMTP_AUTH 9 -#define KW_DROP_UNKNOWN_USER 10 -#define KW_USER_NOTPRIVILEGED 11 -#define KW_SOCKS_PROXY 13 -#define KW_SOCKS_V4 14 -#define KW_SOCKS_AUTH 15 -#define KW_READ_ENTIRE_BODY 16 -#define KW_LOCAL_DOMAIN 17 -#define KW_MODE 18 -#define KW_ESMTP_ANONYMOUS_TOKEN 19 -#define KW_ESMTP_AUTH_ID 20 -#define KW_ESMTP_AUTHZ_ID 21 -#define KW_ESMTP_PASSWORD 22 -#define KW_ESMTP_SERVICE 23 -#define KW_ESMTP_HOSTNAME 24 -#define KW_ESMTP_GENERIC_SERVICE 25 -#define KW_ESMTP_PASSCODE 26 -#define KW_ESMTP_REALM 27 -#define KW_ESMTP_ALLOWED_MECH 28 -#define KW_ESMTP_REQUIRE_ENCRYPTION 29 -#define KW_INCOMING_MAIL_RULE 30 -#define KW_OUTGOING_MAIL_RULE 31 -#define KW_SMTP_COMMAND_RULE 32 -#define KW_HANG 33 -#define KW_ALLOW_HANG 34 -#define KW_LOG_FACILITY 35 -#define KW_LOG_TAG 36 -#define KW_ESMTP_AUTH_DELAYED 37 +enum + { + KW_BIND, + KW_TERMLEVEL, + KW_LOGLEVEL, + KW_LOGFILE, + KW_TRACEFILE, + KW_REMOTE_MTA, + KW_LOCAL_MTA, + KW_RULE_PRIORITY, + KW_CONTROL_PRIORITY, + KW_ESMTP_AUTH, + KW_DROP_UNKNOWN_USER, + KW_USER_NOTPRIVILEGED, + KW_SOCKS_PROXY, + KW_SOCKS_V4, + KW_SOCKS_AUTH, + KW_READ_ENTIRE_BODY, + KW_LOCAL_DOMAIN, + KW_MODE, + KW_ESMTP_ANONYMOUS_TOKEN, + KW_ESMTP_AUTH_ID, + KW_ESMTP_AUTHZ_ID, + KW_ESMTP_PASSWORD, + KW_ESMTP_SERVICE, + KW_ESMTP_HOSTNAME, + KW_ESMTP_GENERIC_SERVICE, + KW_ESMTP_PASSCODE, + KW_ESMTP_REALM, + KW_ESMTP_ALLOWED_MECH, + KW_ESMTP_REQUIRE_ENCRYPTION, + KW_INCOMING_MAIL_RULE, + KW_OUTGOING_MAIL_RULE, + KW_SMTP_COMMAND_RULE, + KW_HANG, + KW_ALLOW_HANG, + KW_LOG_FACILITY, + KW_LOG_TAG, + KW_ESMTP_AUTH_DELAYED, + KW_USE_PAM, + KW_IDENTD_KEYFILE, + }; char ** list_to_argv (ANUBIS_LIST list) { int i, argc; char **argv, *p; @@ -285,13 +290,13 @@ list_to_argv (ANUBIS_LIST list) static void parse_log_facility (const char *arg) { unsigned long n; char *endp; struct anubis_keyword kw[] = { - { "USER", LOG_USER }, + { "USER", LOG_USER }, { "DAEMON", LOG_DAEMON }, { "AUTH", LOG_AUTH }, { "AUTHPRIV",LOG_AUTHPRIV }, { "MAIL", LOG_MAIL }, { "CRON", LOG_CRON }, { "LOCAL0", LOG_LOCAL0 }, @@ -302,50 +307,34 @@ parse_log_facility (const char *arg) { "LOCAL5", LOG_LOCAL5 }, { "LOCAL6", LOG_LOCAL6 }, { "LOCAL7", LOG_LOCAL7 }, { NULL } }; struct anubis_keyword *p; - + if (strlen (arg) > 4 && strncasecmp (arg, "LOG_", 4) == 0) arg += 4; p = anubis_keyword_lookup_ci (kw, arg); if (p) log_facility = p->tok; else if (((n = strtoul (arg, &endp, 0)), *endp == 0) && (log_facility = n) == n) /* nothing */; else anubis_warning (0, _("%s: invalid syslog facility"), arg); } - + /* When HANG=NUMBER is set in CONTROL section, `_anubis_hang' is set and Anubis will sleep for one second intervals, decrementing `_anubis_hang' until it's zero. Thus you can force the program to continue by attaching a debugger and setting it to 0 yourself. */ static volatile unsigned long _anubis_hang; /* List of users who are allowed to use HANG in their profiles */ -ANUBIS_LIST allow_hang_users; - -static struct rc_kwdef esmtp_kw[] = { - { "esmtp-auth", KW_ESMTP_AUTH, KWF_HIDDEN }, - { "esmtp-anonymous-token", KW_ESMTP_ANONYMOUS_TOKEN, KWF_HIDDEN }, - { "esmtp-auth-id", KW_ESMTP_AUTH_ID, KWF_HIDDEN }, - { "esmtp-authz-id", KW_ESMTP_AUTHZ_ID, KWF_HIDDEN }, - { "esmtp-password", KW_ESMTP_PASSWORD, KWF_HIDDEN }, - { "esmtp-service", KW_ESMTP_SERVICE, KWF_HIDDEN }, - { "esmtp-hostname", KW_ESMTP_HOSTNAME, KWF_HIDDEN }, - { "esmtp-generic-service", KW_ESMTP_SERVICE, KWF_HIDDEN }, - { "esmtp-passcode", KW_ESMTP_PASSCODE, KWF_HIDDEN }, - { "esmtp-realm", KW_ESMTP_REALM, KWF_HIDDEN }, - { "esmtp-allowed-mech", KW_ESMTP_ALLOWED_MECH }, - { "esmtp-require-encryption", KW_ESMTP_REQUIRE_ENCRYPTION }, - { NULL } -}; +ANUBIS_LIST allow_hang_users; static int parse_esmtp_kv (int key, ANUBIS_LIST arglist) { char *arg = list_item (arglist, 0); switch (key) @@ -363,128 +352,128 @@ parse_esmtp_kv (int key, ANUBIS_LIST arglist) topt |= T_ESMTP_AUTH; } else topt &= ~T_ESMTP_AUTH; } break; - + case KW_ESMTP_ANONYMOUS_TOKEN: anon_token = strdup (arg); topt |= T_ESMTP_AUTH; break; - + case KW_ESMTP_AUTH_ID: authentication_id = strdup (arg); topt |= T_ESMTP_AUTH; break; - + case KW_ESMTP_AUTHZ_ID: authorization_id = strdup (arg); topt |= T_ESMTP_AUTH; break; - + case KW_ESMTP_PASSWORD: auth_password = strdup (arg); topt |= T_ESMTP_AUTH; break; - + case KW_ESMTP_SERVICE: auth_service = strdup (arg); topt |= T_ESMTP_AUTH; break; - + case KW_ESMTP_HOSTNAME: auth_hostname = strdup (arg); topt |= T_ESMTP_AUTH; break; - + case KW_ESMTP_GENERIC_SERVICE: generic_service_name = strdup (arg); topt |= T_ESMTP_AUTH; break; - + case KW_ESMTP_PASSCODE: auth_passcode = strdup (arg); topt |= T_ESMTP_AUTH; break; - + case KW_ESMTP_REALM: auth_realm = strdup (arg); topt |= T_ESMTP_AUTH; break; - + case KW_ESMTP_ALLOWED_MECH: anubis_set_client_mech_list (arglist); topt |= T_ESMTP_AUTH; break; - + case KW_ESMTP_REQUIRE_ENCRYPTION: anubis_set_encryption_mech_list (arglist); break; default: return 1; -#endif +#endif } return 0; } void control_parser (EVAL_ENV env, int key, ANUBIS_LIST arglist, void *inv_data) { char *arg = list_item (arglist, 0); int method = eval_env_method (env); - + switch (key) { case KW_BIND: parse_mtahost (arg, &session.anubis, &session.anubis_port); if (session.anubis && strlen (session.anubis) != 0) topt |= T_NAMES; break; - + case KW_RULE_PRIORITY: if (strcasecmp (arg, "user") == 0) anubis_section_set_prio ("RULE", prio_user); else if (strcasecmp (arg, "user-only") == 0) anubis_section_set_prio ("RULE", prio_user_only); else if (strcasecmp (arg, "system") == 0) anubis_section_set_prio ("RULE", prio_system); else if (strcasecmp (arg, "system-only") == 0) anubis_section_set_prio ("RULE", prio_system_only); else eval_error (0, env, _("invalid rule priority")); break; - + case KW_CONTROL_PRIORITY: if (strcasecmp (arg, "user") == 0) anubis_section_set_prio ("CONTROL", prio_user); else if (strcasecmp (arg, "system") == 0) anubis_section_set_prio ("CONTROL", prio_system); else eval_error (0, env, _("invalid control priority")); break; - + case KW_TERMLEVEL: if (strcasecmp ("silent", arg) == 0) options.termlevel = SILENT; else if (strcasecmp ("normal", arg) == 0) options.termlevel = NORMAL; else if (strcasecmp ("verbose", arg) == 0) options.termlevel = VERBOSE; else if (strcasecmp ("debug", arg) == 0) options.termlevel = DEBUG; else eval_error (0, env, _("invalid termlevel")); break; - + case KW_USER_NOTPRIVILEGED: assign_string (&session.notprivileged, arg); topt |= T_USER_NOTPRIVIL; break; - + case KW_LOGFILE: if (method == CF_CLIENT) { xfree (options.ulogfile); options.ulogfile = xstrdup (arg); } @@ -495,24 +484,24 @@ control_parser (EVAL_ENV env, int key, ANUBIS_LIST arglist, void *inv_data) { topt |= T_DISABLE_SYSLOG; xfree (options.ulogfile); options.ulogfile = xstrdup (arg); } break; - + case KW_LOGLEVEL: if (strcasecmp ("none", arg) == 0) options.uloglevel = NONE; else if (strcasecmp ("all", arg) == 0) options.uloglevel = ALL; else if (strcasecmp ("fails", arg) == 0) options.uloglevel = FAILS; else eval_error (0, env, _("invalid loglevel")); break; - + case KW_TRACEFILE: if (method & (CF_SUPERVISOR | CF_INIT)) setbool (env, arg, topt, T_TRACEFILE_SYS); else if (method == CF_CLIENT) { if (strcasecmp ("no", arg) == 0) @@ -535,39 +524,39 @@ control_parser (EVAL_ENV env, int key, ANUBIS_LIST arglist, void *inv_data) options.tracefile = xstrdup (arg); topt |= T_TRACEFILE_USR; } } } break; - + case KW_REMOTE_MTA: parse_mtaport (arg, &session.mta, &session.mta_port); break; - + case KW_LOCAL_MTA: xfree (session.execpath); - argcv_free (-1, session.execargs); + argv_free (session.execargs); session.execpath = strdup (arg); session.execargs = list_to_argv (arglist); topt |= T_LOCAL_MTA; break; - + case KW_LOCAL_DOMAIN: anubis_domain = strdup (arg); break; #ifdef USE_SOCKS_PROXY case KW_SOCKS_PROXY: parse_mtaport (arg, &session.socks, &session.socks_port); if_empty_set (session.socks, topt, T_SOCKS); break; - + case KW_SOCKS_V4: setbool (env, arg, topt, T_SOCKS_V4); break; - + case KW_SOCKS_AUTH: { char *p = 0; p = strchr (arg, ':'); if (p) { @@ -580,73 +569,72 @@ control_parser (EVAL_ENV env, int key, ANUBIS_LIST arglist, void *inv_data) } #endif /* USE_SOCKS_PROXY */ case KW_READ_ENTIRE_BODY: setbool (env, arg, topt, T_ENTIRE_BODY); break; - + case KW_DROP_UNKNOWN_USER: setbool (env, arg, topt, T_DROP_UNKNOWN_USER); break; - + case KW_MODE: - if (anubis_mode != anubis_mda) /* Special case. See comment to - KW_LOCAL_MAILER directive, though */ + if (anubis_mode != anubis_mda) { if (list_count (arglist) != 1) eval_error (1, env, _("not enough arguments")); else if (anubis_set_mode (arg)) eval_error (0, env, _("invalid mode: %s"), arg); } break; - + case KW_INCOMING_MAIL_RULE: incoming_mail_rule = strdup (arg); break; - + case KW_OUTGOING_MAIL_RULE: outgoing_mail_rule = strdup (arg); break; case KW_SMTP_COMMAND_RULE: smtp_command_rule = strdup (arg); break; - + case KW_LOG_FACILITY: parse_log_facility (arg); break; - + case KW_LOG_TAG: log_tag = strdup (arg); break; - + case KW_ALLOW_HANG: { char *p; ITERATOR itr = iterator_create (arglist); - + allow_hang_users = list_create (); for (p = iterator_first (itr); p; p = iterator_next (itr)) list_append (allow_hang_users, strdup (p)); } break; - + case KW_HANG: if (list_locate (allow_hang_users, session.clientname, anubis_name_cmp)) { int keep_termlevel = options.termlevel; - + _anubis_hang = atoi (arg ? arg : "3600"); options.termlevel = DEBUG; eval_warning (env, ngettext ("Child process suspended for %lu second", "Child process suspended for %lu seconds", _anubis_hang), _anubis_hang); options.termlevel = keep_termlevel; - + while (_anubis_hang-- > 0) sleep (1); } else anubis_warning (0, _("Command HANG is not allowed for user `%s'"), @@ -655,12 +643,30 @@ control_parser (EVAL_ENV env, int key, ANUBIS_LIST arglist, void *inv_data) #if defined (WITH_GSASL) case KW_ESMTP_AUTH_DELAYED: topt |= T_ESMTP_AUTH; setbool (env, arg, topt, T_ESMTP_AUTH_DELAYED); break; #endif + + case KW_USE_PAM: + setbool (env, arg, use_pam, 1); +#if !defined(HAVE_PAM) + if (use_pam) + eval_error (0, env, + _("statement ignored: anubis compiled without PAM support")); +#endif + break; + + case KW_IDENTD_KEYFILE: + identd_keyfile_name = strdup (arg); +#if !defined(USE_GCRYPT) + eval_error (0, env, + _("statement ignored: anubis compiled without libgcrypt")); +#endif + break; + default: if (parse_esmtp_kv (key, arglist)) eval_error (2, env, _("INTERNAL ERROR at %s:%d: unhandled key %d; " "please report"), __FILE__, __LINE__, @@ -675,12 +681,14 @@ static struct rc_kwdef init_kw[] = { { "incoming-mail-rule", KW_INCOMING_MAIL_RULE }, { "outgoing-mail-rule", KW_OUTGOING_MAIL_RULE }, { "smtp-command-rule", KW_SMTP_COMMAND_RULE }, { "log-facility", KW_LOG_FACILITY }, { "log-tag", KW_LOG_TAG }, { "ALLOW-HANG", KW_ALLOW_HANG }, + { "use-pam", KW_USE_PAM }, + { "identd-keyfile", KW_IDENTD_KEYFILE }, { NULL }, }; static struct rc_secdef_child init_sect_child = { NULL, CF_INIT, @@ -772,39 +780,39 @@ tls_parser (EVAL_ENV env, int key, ANUBIS_LIST arglist, void *inv_data) char *arg = list_item (arglist, 0); switch (key) { case KW_SSL: setbool (env, arg, topt, T_SSL); break; - + case KW_SSL_ONEWAY: setbool (env, arg, topt, T_SSL_ONEWAY); break; - + case KW_SSL_CERT: xfree (secure.cert); secure.cert = xstrdup (arg); break; - + case KW_SSL_KEY: xfree (secure.key); secure.key = xstrdup (arg); if (eval_env_method (env) == CF_CLIENT) topt |= T_SSL_CKCLIENT; break; - + case KW_SSL_CAFILE: xfree (secure.cafile); secure.cafile = xstrdup (arg); break; case KW_SSL_PRIORITIES: xfree (secure.prio); secure.prio = xstrdup (arg); break; - + default: eval_error (2, env, _("INTERNAL ERROR at %s:%d: unhandled key %d; " "please report"), __FILE__, __LINE__, key); @@ -861,32 +869,32 @@ rule_parser (EVAL_ENV env, int key, ANUBIS_LIST arglist, void *inv_data) switch (key) { case KW_SIGNATURE_FILE_APPEND: if (strcasecmp ("no", arg)) message_append_signature_file (msg); break; - + case KW_BODY_APPEND: message_append_text_file (msg, arg, NULL); break; - + case KW_BODY_CLEAR: message_replace_body (msg, xstrdup ("")); break; - + case KW_BODY_CLEAR_APPEND: message_replace_body (msg, xstrdup ("")); message_append_text_file (msg, arg, NULL); break; - + case KW_EXTERNAL_BODY_PROCESSOR: argv = list_to_argv (arglist); message_external_proc (msg, argv); - argcv_free (-1, argv); + argv_free (argv); break; - + default: eval_error (2, env, _("INTERNAL ERROR at %s:%d: unhandled key %d; " "please report"), __FILE__, __LINE__, key); @@ -930,32 +938,32 @@ smtp_rule_parser (EVAL_ENV env, int key, ANUBIS_LIST arglist, void *inv_data) switch (key) { case KW_SIGNATURE_FILE_APPEND: if (strcasecmp ("no", arg)) message_append_signature_file (msg); break; - + case KW_BODY_APPEND: message_append_text_file (msg, arg, NULL); break; - + case KW_BODY_CLEAR: message_replace_body (msg, xstrdup ("")); break; - + case KW_BODY_CLEAR_APPEND: message_replace_body (msg, xstrdup ("")); message_append_text_file (msg, arg, NULL); break; - + case KW_EXTERNAL_BODY_PROCESSOR: argv = list_to_argv (arglist); message_external_proc (msg, argv); - argcv_free (-1, argv); + argv_free (argv); break; - + default: if (parse_esmtp_kv (key, arglist)) eval_error (2, env, _("INTERNAL ERROR at %s:%d: unhandled key %d; " "please report"), __FILE__, __LINE__, |