/* GNU Mailutils -- a suite of utilities for electronic mail Copyright (C) 2009-2019 Free Software Foundation, Inc. GNU Mailutils 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, or (at your option) any later version. GNU Mailutils is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with GNU Mailutils. If not, see . */ #include "pop3d.h" struct mu_tls_config global_tls_conf; int global_tls_mode; int global_conf_status = -1; static struct pop3d_command command_table[] = { { "STLS", pop3d_stls }, { "RETR", pop3d_retr }, { "DELE", pop3d_dele }, { "USER", pop3d_user }, { "QUIT", pop3d_quit }, { "APOP", pop3d_apop }, { "AUTH", pop3d_auth }, { "STAT", pop3d_stat }, { "LIST", pop3d_list }, { "NOOP", pop3d_noop }, { "RSET", pop3d_rset }, { "TOP", pop3d_top }, { "UIDL", pop3d_uidl }, { "CAPA", pop3d_capa }, { NULL } }; pop3d_command_handler_t pop3d_find_command (const char *name) { struct pop3d_command *p; for (p = command_table; p->name; p++) { if (mu_c_strcasecmp (name, p->name) == 0) return p->handler; } return p->handler; } int stls_server_check (struct pop3d_srv_config *cfg, char const *srvid) { int result; switch (cfg->tls_mode) { case tls_unspecified: if (global_tls_mode != tls_unspecified) cfg->tls_mode = global_tls_mode; else if (cfg->tls_conf.cert_file) cfg->tls_mode = tls_ondemand; else { cfg->tls_mode = tls_no; return MU_TLS_CONFIG_NULL; } break; case tls_no: return MU_TLS_CONFIG_NULL; default: break; } result = mu_tls_config_check (&cfg->tls_conf, 1); switch (result) { case MU_TLS_CONFIG_OK: if (!cfg->tls_conf.cert_file) { mu_error (_("server %s: no certificate set"), srvid); result = MU_TLS_CONFIG_FAIL; } break; case MU_TLS_CONFIG_NULL: if (global_conf_status == -1) { if (global_tls_conf.cert_file) global_conf_status = mu_tls_config_check (&global_tls_conf, 1); else global_conf_status = MU_TLS_CONFIG_NULL; } if (global_conf_status != MU_TLS_CONFIG_NULL) { cfg->tls_conf = global_tls_conf; result = MU_TLS_CONFIG_OK; } else { mu_error (_("server %s: no certificate set"), srvid); result = MU_TLS_CONFIG_FAIL; } break; default: mu_error (_("server %s: TLS configuration failed"), srvid); } return result; } int stls_preflight (mu_m_server_t msrv) { mu_list_t srvlist; mu_iterator_t itr; int errors = 0; int tls_ok = mu_init_tls_libs (); int tls_requested = 0; mu_m_server_get_srvlist (msrv, &srvlist); mu_list_get_iterator (srvlist, &itr); for (mu_iterator_first (itr); !mu_iterator_is_done (itr); mu_iterator_next (itr)) { mu_ip_server_t ipsrv; struct pop3d_srv_config *cfg; mu_iterator_current (itr, (void**) &ipsrv); cfg = mu_ip_server_get_data (ipsrv); switch (stls_server_check (cfg, mu_ip_server_addrstr (ipsrv))) { case MU_TLS_CONFIG_NULL: continue; case MU_TLS_CONFIG_OK: break; default: errors = 1; } tls_requested = 1; } mu_iterator_destroy (&itr); if (global_tls_mode == tls_unspecified) global_tls_mode = tls_no; if (tls_requested && !tls_ok) { mu_error (_("TLS is not configured, but requested in the " "configuration")); errors = 1; } if (errors) return 1; return 0; } static char *error_table[] = { [ERR_WRONG_STATE] = "Incorrect state", [ERR_BAD_ARGS] = "Invalid arguments", [ERR_BAD_LOGIN] = "[AUTH] Bad login", [ERR_NO_MESG] = "No such message", [ERR_MESG_DELE] = "Message has been deleted", [ERR_NOT_IMPL] = "Not implemented", [ERR_BAD_CMD] = "Invalid command", [ERR_MBOX_LOCK] = "[IN-USE] Mailbox in use", [ERR_TOO_LONG] = "Argument too long", [ERR_NO_MEM] = "Out of memory] =quitting", [ERR_SIGNAL] = "Quitting on signal", [ERR_FILE] = "Some deleted messages not removed", [ERR_NO_IFILE] = "No input stream", [ERR_NO_OFILE] = "No output stream", [ERR_IO] = "I/O error", [ERR_PROTO] = "Remote protocol error", [ERR_TIMEOUT] = "Session timed out", [ERR_UNKNOWN] = "Unknown error", [ERR_MBOX_SYNC] = "Mailbox was updated by other process", [ERR_TLS_IO] = "TLS I/O error", [ERR_LOGIN_DELAY] = "[LOGIN-DELAY] Attempt to log in within the minimum login delay interval", [ERR_TERMINATE] = "Terminating on request", [ERR_SYS_LOGIN] = "[SYS/PERM] Cannot authenticate", }; const char * pop3d_error_string (int code) { if (code >= 0 && code < MU_ARRAY_SIZE (error_table) && error_table[code]) return error_table[code]; return "unknown error"; }