static int smtp_open (CONNECTION* conn) { int rc; if (mutt_socket_open (conn)) return -1; /* get greeting string */ if ((rc = smtp_get_resp (conn))) return rc; if ((rc = smtp_helo (conn))) return rc; #ifdef USE_SSL if (conn->ssf) rc = M_NO; else if (option (OPTSSLFORCETLS)) rc = M_YES; else if (mutt_bit_isset (Capabilities, STARTTLS) && (rc = query_quadoption (OPT_SSLSTARTTLS, _("Secure connection with TLS?"))) == -1) return rc; if (rc == M_YES) { if (mutt_socket_write (conn, "STARTTLS\r\n") < 0) return smtp_err_write; if ((rc = smtp_get_resp (conn))) return rc; if (mutt_ssl_starttls (conn)) { mutt_error (_("Could not negotiate TLS connection")); mutt_sleep (1); return -1; } /* re-EHLO to get authentication mechanisms */ if ((rc = smtp_helo (conn))) return rc; } #endif if (conn->account.flags & M_ACCT_USER) { if (!mutt_bit_isset (Capabilities, AUTH)) { mutt_error (_("SMTP server does not support authentication")); mutt_sleep (1); return -1; } #ifdef USE_SASL return smtp_auth (conn); #else mutt_error (_("SMTP authentication requires SASL")); mutt_sleep (1); return -1; #endif /* USE_SASL */ } return 0; }
static int tls_socket_write (CONNECTION* conn, const char* buf, size_t len) { tlssockdata *data = conn->sockdata; int ret; size_t sent = 0; if (!data) { mutt_error (_("Error: no TLS socket open")); mutt_sleep (2); return -1; } do { ret = gnutls_record_send (data->state, buf + sent, len - sent); if (ret < 0) { if (gnutls_error_is_fatal(ret) == 1) { mutt_error ("tls_socket_write (%s)", gnutls_strerror (ret)); mutt_sleep (4); return -1; } return ret; } sent += ret; } while (sent < len); return sent; }
static int tls_socket_read (CONNECTION* conn, char* buf, size_t len) { tlssockdata *data = conn->sockdata; int ret; if (!data) { mutt_error (_("Error: no TLS socket open")); mutt_sleep (2); return -1; } do { ret = gnutls_record_recv (data->state, buf, len); if (ret < 0 && gnutls_error_is_fatal(ret) == 1) { mutt_error ("tls_socket_read (%s)", gnutls_strerror (ret)); mutt_sleep (4); return -1; } } while (ret == GNUTLS_E_AGAIN || ret == GNUTLS_E_INTERRUPTED); return ret; }
/* sanity-checking wrapper for gnutls_certificate_verify_peers */ static gnutls_certificate_status tls_verify_peers (gnutls_session tlsstate) { int verify_ret; unsigned int status; verify_ret = gnutls_certificate_verify_peers2 (tlsstate, &status); if (!verify_ret) return status; if (status == GNUTLS_E_NO_CERTIFICATE_FOUND) { mutt_error (_("Unable to get certificate from peer")); mutt_sleep (2); return 0; } if (verify_ret < 0) { mutt_error (_("Certificate verification error (%s)"), gnutls_strerror (status)); mutt_sleep (2); return 0; } /* We only support X.509 certificates (not OpenPGP) at the moment */ if (gnutls_certificate_type_get (tlsstate) != GNUTLS_CRT_X509) { mutt_error (_("Certificate is not X.509")); mutt_sleep (2); return 0; } return status; }
static int check_certificate_by_digest (X509 *peercert) { unsigned char peermd[EVP_MAX_MD_SIZE]; unsigned int peermdlen; X509 *cert = NULL; int pass = 0; FILE *fp; /* expiration check */ if (option (OPTSSLVERIFYDATES) != M_NO) { if (X509_cmp_current_time (X509_get_notBefore (peercert)) >= 0) { dprint (2, (debugfile, "Server certificate is not yet valid\n")); mutt_error (_("Server certificate is not yet valid")); mutt_sleep (2); return 0; } if (X509_cmp_current_time (X509_get_notAfter (peercert)) <= 0) { dprint (2, (debugfile, "Server certificate has expired")); mutt_error (_("Server certificate has expired")); mutt_sleep (2); return 0; } } if ((fp = fopen (SslCertFile, "rt")) == NULL) return 0; if (!X509_digest (peercert, EVP_sha1(), peermd, &peermdlen)) { safe_fclose (&fp); return 0; } while ((cert = READ_X509_KEY (fp, &cert)) != NULL) { pass = compare_certificates (cert, peercert, peermd, peermdlen) ? 0 : 1; if (pass) break; } X509_free (cert); safe_fclose (&fp); return pass; }
/* ssl_negotiate: After SSL state has been initialized, attempt to negotiate * SSL over the wire, including certificate checks. */ static int ssl_negotiate (CONNECTION *conn, sslsockdata* ssldata) { int err; const char* errmsg; SSL_set_mode (ssldata->ssl, SSL_MODE_AUTO_RETRY); if ((err = SSL_connect (ssldata->ssl)) != 1) { switch (SSL_get_error (ssldata->ssl, err)) { case SSL_ERROR_SYSCALL: errmsg = _("I/O error"); break; case SSL_ERROR_SSL: errmsg = ERR_error_string (ERR_get_error (), NULL); break; default: errmsg = _("unknown error"); } mutt_error (_("SSL failed: %s"), errmsg); mutt_sleep (1); return -1; } ssldata->cert = SSL_get_peer_certificate (ssldata->ssl); if (!ssldata->cert) { mutt_error (_("Unable to get certificate from peer")); mutt_sleep (1); return -1; } if (!ssl_check_certificate (conn, ssldata)) return -1; /* L10N: %1$s is version (e.g. "TLSv1.2") %2$s is cipher_version (e.g. "TLSv1/SSLv3") %3$s is cipher_name (e.g. "ECDHE-RSA-AES128-GCM-SHA256") */ mutt_message (_("%s connection using %s (%s)"), SSL_get_version(ssldata->ssl), SSL_get_cipher_version (ssldata->ssl), SSL_get_cipher_name (ssldata->ssl)); mutt_sleep (0); return 0; }
/* ssl_negotiate: After SSL state has been initialised, attempt to negotiate * SSL over the wire, including certificate checks. */ static int ssl_negotiate (CONNECTION *conn, sslsockdata* ssldata) { int err; const char* errmsg; #if OPENSSL_VERSION_NUMBER >= 0x00906000L /* This only exists in 0.9.6 and above. Without it we may get interrupted * reads or writes. Bummer. */ SSL_set_mode (ssldata->ssl, SSL_MODE_AUTO_RETRY); #endif if ((err = SSL_connect (ssldata->ssl)) != 1) { switch (SSL_get_error (ssldata->ssl, err)) { case SSL_ERROR_SYSCALL: errmsg = _("I/O error"); break; case SSL_ERROR_SSL: errmsg = ERR_error_string (ERR_get_error (), NULL); break; default: errmsg = _("unknown error"); } mutt_error (_("SSL failed: %s"), errmsg); mutt_sleep (1); return -1; } ssldata->cert = SSL_get_peer_certificate (ssldata->ssl); if (!ssldata->cert) { mutt_error (_("Unable to get certificate from peer")); mutt_sleep (1); return -1; } if (!ssl_check_certificate (conn, ssldata)) return -1; mutt_message (_("%s connection using %s (%s)"), SSL_get_version(ssldata->ssl), SSL_get_cipher_version (ssldata->ssl), SSL_get_cipher_name (ssldata->ssl)); mutt_sleep (0); return 0; }
static int add_entropy (const char *file) { struct stat st; int n = -1; if (!file) return 0; if (stat (file, &st) == -1) return errno == ENOENT ? 0 : -1; mutt_message (_("Filling entropy pool: %s...\n"), file); /* check that the file permissions are secure */ if (st.st_uid != getuid () || ((st.st_mode & (S_IWGRP | S_IRGRP)) != 0) || ((st.st_mode & (S_IWOTH | S_IROTH)) != 0)) { mutt_error (_("%s has insecure permissions!"), file); mutt_sleep (2); return -1; } #ifdef HAVE_RAND_EGD n = RAND_egd (file); #endif if (n <= 0) n = RAND_load_file (file, -1); #ifndef HAVE_RAND_STATUS if (n > 0) entropy_byte_count += n; #endif return n; }
void mutt_message_hook (CONTEXT *ctx, HEADER *hdr, int type) { BUFFER err, token; HOOK *hook; current_hook_type = type; mutt_buffer_init (&err); err.dsize = STRING; err.data = safe_malloc (err.dsize); mutt_buffer_init (&token); for (hook = Hooks; hook; hook = hook->next) { if(!hook->command) continue; if (hook->type & type) if ((mutt_pattern_exec (hook->pattern, 0, ctx, hdr) > 0) ^ hook->rx.not) if (mutt_parse_rc_line (hook->command, &token, &err) != 0) { FREE (&token.data); mutt_error ("%s", err.data); mutt_sleep (1); current_hook_type = 0; FREE (&err.data); return; } } FREE (&token.data); FREE (&err.data); current_hook_type = 0; }
static int edit_address (ADDRESS **a, /* const */ char *field) { char buf[HUGE_STRING]; char *err = NULL; int idna_ok = 0; do { buf[0] = 0; mutt_addrlist_to_local (*a); rfc822_write_address (buf, sizeof (buf), *a, 0); if (mutt_get_field (field, buf, sizeof (buf), M_ALIAS) != 0) return (-1); rfc822_free_address (a); *a = mutt_expand_aliases (mutt_parse_adrlist (NULL, buf)); if ((idna_ok = mutt_addrlist_to_idna (*a, &err)) != 0) { mutt_error (_("Error: '%s' is a bad IDN."), err); mutt_refresh (); mutt_sleep (2); FREE (&err); } } while (idna_ok != 0); return 0; }
void mutt_message_hook (CONTEXT *ctx, HEADER *hdr, int type) { BUFFER err, token; HOOK *hook; char buf[STRING]; current_hook_type = type; err.data = buf; err.dsize = sizeof (buf); memset (&token, 0, sizeof (token)); for (hook = Hooks; hook; hook = hook->next) { if(!hook->command) continue; if (hook->type & type) if ((mutt_pattern_exec (hook->pattern, 0, ctx, hdr) > 0) ^ hook->rx.not) if (mutt_parse_rc_line (hook->command, &token, &err) != 0) { FREE (&token.data); mutt_error ("%s", err.data); mutt_sleep (1); current_hook_type = 0; return; } } FREE (&token.data); current_hook_type = 0; }
void mutt_folder_hook (char *path) { HOOK *tmp = Hooks; BUFFER err, token; char buf[STRING]; current_hook_type = M_FOLDERHOOK; err.data = buf; err.dsize = sizeof (buf); memset (&token, 0, sizeof (token)); for (; tmp; tmp = tmp->next) { if(!tmp->command) continue; if (tmp->type & M_FOLDERHOOK) { if ((regexec (tmp->rx.rx, path, 0, NULL, 0) == 0) ^ tmp->rx.not) { if (mutt_parse_rc_line (tmp->command, &token, &err) == -1) { mutt_error ("%s", err.data); FREE (&token.data); mutt_sleep (1); /* pause a moment to let the user see the error */ current_hook_type = 0; return; } } } } FREE (&token.data); current_hook_type = 0; }
/* simple read buffering to speed things up. */ int mutt_socket_readchar (CONNECTION *conn, char *c) { if (conn->bufpos >= conn->available) { if (conn->fd >= 0) conn->available = conn->read (conn, conn->inbuf, sizeof (conn->inbuf)); else { dprint (1, (debugfile, "mutt_socket_readchar: attempt to read from closed connection.\n")); return -1; } conn->bufpos = 0; if (conn->available == 0) { mutt_error (_("Connection to %s closed"), conn->account.host); mutt_sleep (2); } if (conn->available <= 0) { mutt_socket_close (conn); return -1; } } *c = conn->inbuf[conn->bufpos]; conn->bufpos++; return 1; }
/* check whether cert is preauthorized. If host is not null, verify that * it matches the certificate. * Return > 0: authorized, < 0: problems, 0: unknown validity */ static int ssl_check_preauth (X509 *cert, const char* host) { char buf[SHORT_STRING]; /* check session cache first */ if (check_certificate_cache (cert)) { dprint (2, (debugfile, "ssl_check_preauth: using cached certificate\n")); return 1; } buf[0] = 0; if (host && option (OPTSSLVERIFYHOST) != M_NO) { if (!check_host (cert, host, buf, sizeof (buf))) { mutt_error (_("Certificate host check failed: %s"), buf); mutt_sleep (2); return -1; } dprint (2, (debugfile, "ssl_check_preauth: hostname check passed\n")); } if (check_certificate_by_signer (cert)) { dprint (2, (debugfile, "ssl_check_preauth: signer check passed\n")); return 1; } /* automatic check from user's database */ if (SslCertFile && check_certificate_by_digest (cert)) { dprint (2, (debugfile, "ssl_check_preauth: digest check passed\n")); return 1; } return 0; }
/* given an POP mailbox name, return host, port, username and password */ int pop_parse_path (const char* path, ACCOUNT* acct) { ciss_url_t url; char *c; struct servent *service; /* Defaults */ acct->flags = 0; acct->type = M_ACCT_TYPE_POP; c = safe_strdup (path); url_parse_ciss (&url, c); if ((url.scheme != U_POP && url.scheme != U_POPS) || mutt_account_fromurl (acct, &url) < 0) { FREE(&c); mutt_error(_("Invalid POP URL: %s\n"), path); mutt_sleep(1); return -1; } if (url.scheme == U_POPS) acct->flags |= M_ACCT_SSL; service = getservbyname (url.scheme == U_POP ? "pop3" : "pop3s", "tcp"); if (service) acct->port = ntohs (service->s_port); else acct->port = url.scheme == U_POP ? POP_PORT : POP_SSL_PORT;; FREE (&c); return 0; }
/* imap_auth_login: Plain LOGIN support */ imap_auth_res_t imap_auth_login (IMAP_DATA* idata, const char* method) { char q_user[SHORT_STRING], q_pass[SHORT_STRING]; char buf[STRING]; int rc; if (bit_val(idata->capabilities, LOGINDISABLED)) { mutt_message("LOGIN disabled on this server."); return IMAP_AUTH_UNAVAIL; } if (mutt_account_getuser (&idata->conn->account)) return IMAP_AUTH_FAILURE; if (mutt_account_getpass (&idata->conn->account)) return IMAP_AUTH_FAILURE; mutt_message("Logging in..."); imap_quote_string (q_user, sizeof (q_user), idata->conn->account.user); imap_quote_string (q_pass, sizeof (q_pass), idata->conn->account.pass); snprintf (buf, sizeof (buf), "LOGIN %s %s", q_user, q_pass); rc = imap_exec (idata, buf, IMAP_CMD_FAIL_OK | IMAP_CMD_PASS); if (!rc) { mutt_clear_error(); /* clear "Logging in...". fixes #3524 */ return IMAP_AUTH_SUCCESS; } mutt_error("Login failed."); mutt_sleep (2); return IMAP_AUTH_FAILURE; }
static int smtp_auth (CONNECTION* conn) { int r = SMTP_AUTH_UNAVAIL; if (SmtpAuthenticators && *SmtpAuthenticators) { char* methods = safe_strdup (SmtpAuthenticators); char* method; char* delim; for (method = methods; method; method = delim) { delim = strchr (method, ':'); if (delim) *delim++ = '\0'; if (! method[0]) continue; dprint (2, (debugfile, "smtp_authenticate: Trying method %s\n", method)); r = smtp_auth_sasl (conn, method); if (r == SMTP_AUTH_FAIL && delim) { mutt_error (_("%s authentication failed, trying next method"), method); mutt_sleep (1); } else if (r != SMTP_AUTH_UNAVAIL) break; } FREE (&methods); } else r = smtp_auth_sasl (conn, AuthMechs); if (r != SMTP_AUTH_SUCCESS) mutt_account_unsetpass (&conn->account); if (r == SMTP_AUTH_FAIL) { mutt_error (_("SASL authentication failed")); mutt_sleep (1); } else if (r == SMTP_AUTH_UNAVAIL) { mutt_error (_("No authenticators available")); mutt_sleep (1); } return r == SMTP_AUTH_SUCCESS ? 0 : -1; }
int raw_socket_read (CONNECTION* conn, char* buf, size_t len) { int rc; if ((rc = read (conn->fd, buf, len)) == -1) { mutt_error (_("Error talking to %s (%s)"), conn->account.host, strerror (errno)); mutt_sleep (2); } return rc; }
int raw_socket_write (CONNECTION* conn, const char* buf, size_t count) { int rc; if ((rc = write (conn->fd, buf, count)) == -1) { mutt_error (_("Error talking to %s (%s)"), conn->account.host, strerror (errno)); mutt_sleep (2); } return rc; }
/* update POP mailbox - delete messages from server */ int pop_sync_mailbox(CONTEXT *ctx, int *index_hint) { int i, j, ret = 0; char buf[LONG_STRING]; POP_DATA *pop_data = (POP_DATA *)ctx->data; progress_t progress; pop_data->check_time = 0; FOREVER { if (pop_reconnect(ctx) < 0) return -1; mutt_progress_init(&progress, _("Marking messages deleted..."), M_PROGRESS_MSG, WriteInc, ctx->deleted); for (i = 0, j = 0, ret = 0; ret == 0 && i < ctx->msgcount; i++) { if (ctx->hdrs[i]->deleted && (ctx->hdrs[i]->refno != -1)) { j++; if (!ctx->quiet) mutt_progress_update(&progress, j, -1); snprintf(buf, sizeof(buf), "DELE %d\r\n", ctx->hdrs[i]->refno); if ((ret = pop_query(pop_data, buf, sizeof(buf))) == 0) { mutt_bcache_del(pop_data->bcache, ctx->hdrs[i]->data); } } } if (ret == 0) { strfcpy(buf, "QUIT\r\n", sizeof(buf)); ret = pop_query(pop_data, buf, sizeof(buf)); } if (ret == 0) { pop_data->clear_cache = 1; pop_clear_cache(pop_data); pop_data->status = POP_DISCONNECTED; return 0; } if (ret == -2) { mutt_error("%s", pop_data->err_msg); mutt_sleep(2); return -1; } } }
/* mutt_conn_find: find a connection off the list of connections whose * account matches account. If start is not null, only search for * connections after the given connection (allows higher level socket code * to make more fine-grained searches than account info - eg in IMAP we may * wish to find a connection which is not in IMAP_SELECTED state) */ CONNECTION* mutt_conn_find (const CONNECTION* start, const ACCOUNT* account) { CONNECTION* conn; ciss_url_t url; char hook[LONG_STRING]; /* account isn't actually modified, since url isn't either */ mutt_account_tourl ((ACCOUNT*) account, &url); url.path = NULL; url_ciss_tostring (&url, hook, sizeof (hook), 0); mutt_account_hook (hook); conn = start ? start->next : Connections; while (conn) { if (mutt_account_match (account, &(conn->account))) return conn; conn = conn->next; } conn = socket_new_conn (); memcpy (&conn->account, account, sizeof (ACCOUNT)); conn->next = Connections; Connections = conn; if (Tunnel && *Tunnel) mutt_tunnel_socket_setup (conn); else if (account->flags & M_ACCT_SSL) { #if defined(USE_SSL) if (mutt_ssl_socket_setup (conn) < 0) { mutt_socket_free (conn); return NULL; } #else mutt_error _("SSL is unavailable."); mutt_sleep (2); mutt_socket_free (conn); return NULL; #endif } else { conn->conn_read = raw_socket_read; conn->conn_write = raw_socket_write; conn->conn_open = raw_socket_open; conn->conn_close = raw_socket_close; conn->conn_poll = raw_socket_poll; } return conn; }
void menu_redraw_prompt (MUTTMENU * menu) { if (menu->dialog) { if (option (OPTMSGERR)) { mutt_sleep (1); unset_option (OPTMSGERR); } if (*Errorbuf) mutt_clear_error (); SETCOLOR (MT_COLOR_NORMAL); mvaddstr (LINES - 1, 0, menu->prompt); clrtoeol (); } }
/* this is basically a stripped-down version of the cram-md5 method. */ imap_auth_res_t imap_auth_anon (IMAP_DATA* idata, const char* method) { int rc; if (!mutt_bit_isset (idata->capabilities, AUTH_ANON)) return IMAP_AUTH_UNAVAIL; if (mutt_account_getuser (&idata->conn->account)) return IMAP_AUTH_FAILURE; if (idata->conn->account.user[0] != '\0') return IMAP_AUTH_UNAVAIL; mutt_message _("Authenticating (anonymous)..."); imap_cmd_start (idata, "AUTHENTICATE ANONYMOUS"); do rc = imap_cmd_step (idata); while (rc == IMAP_CMD_CONTINUE); if (rc != IMAP_CMD_RESPOND) { dprint (1, (debugfile, "Invalid response from server.\n")); goto bail; } mutt_socket_write (idata->conn, "ZHVtbXkK\r\n"); /* base64 ("dummy") */ do rc = imap_cmd_step (idata); while (rc == IMAP_CMD_CONTINUE); if (rc != IMAP_CMD_OK) { dprint (1, (debugfile, "Error receiving server response.\n")); goto bail; } if (imap_code (idata->buf)) return IMAP_AUTH_SUCCESS; bail: mutt_error _("Anonymous authentication failed."); mutt_sleep (2); return IMAP_AUTH_FAILURE; }
/* reconnect and verify idnexes if connection was lost */ int pop_reconnect (CONTEXT *ctx) { int ret; POP_DATA *pop_data = (POP_DATA *)ctx->data; progress_t progressbar; if (pop_data->status == POP_CONNECTED) return 0; if (pop_data->status == POP_BYE) return -1; FOREVER { mutt_socket_close (pop_data->conn); ret = pop_open_connection (pop_data); if (ret == 0) { int i; mutt_progress_init (&progressbar, _("Verifying message indexes..."), M_PROGRESS_SIZE, NetInc, 0); for (i = 0; i < ctx->msgcount; i++) ctx->hdrs[i]->refno = -1; ret = pop_fetch_data (pop_data, "UIDL\r\n", &progressbar, check_uidl, ctx); if (ret == -2) { mutt_error ("%s", pop_data->err_msg); mutt_sleep (2); } } if (ret == 0) return 0; pop_logout (ctx); if (ret < -1) return -1; if (query_quadoption (OPT_POPRECONNECT, _("Connection lost. Reconnect to POP server?")) != M_YES) return -1; } }
void mutt_account_hook (const char* url) { /* parsing commands with URLs in an account hook can cause a recursive * call. We just skip processing if this occurs. Typically such commands * belong in a folder-hook -- perhaps we should warn the user. */ static int inhook = 0; HOOK* hook; BUFFER token; BUFFER err; if (inhook) return; mutt_buffer_init (&err); err.dsize = STRING; err.data = safe_malloc (err.dsize); mutt_buffer_init (&token); for (hook = Hooks; hook; hook = hook->next) { if (! (hook->command && (hook->type & M_ACCOUNTHOOK))) continue; if ((regexec (hook->rx.rx, url, 0, NULL, 0) == 0) ^ hook->rx.not) { inhook = 1; if (mutt_parse_rc_line (hook->command, &token, &err) == -1) { FREE (&token.data); mutt_error ("%s", err.data); FREE (&err.data); mutt_sleep (1); inhook = 0; return; } inhook = 0; } } FREE (&token.data); FREE (&err.data); }
static int smtp_fill_account (ACCOUNT* account) { static unsigned short SmtpPort = 0; struct servent* service; ciss_url_t url; char* urlstr; account->flags = 0; account->port = 0; account->type = M_ACCT_TYPE_SMTP; urlstr = safe_strdup (SmtpUrl); url_parse_ciss (&url, urlstr); if ((url.scheme != U_SMTP && url.scheme != U_SMTPS) || mutt_account_fromurl (account, &url) < 0) { FREE (&urlstr); mutt_error (_("Invalid SMTP URL: %s"), SmtpUrl); mutt_sleep (1); return -1; } FREE (&urlstr); if (url.scheme == U_SMTPS) account->flags |= M_ACCT_SSL; if (!account->port) { if (account->flags & M_ACCT_SSL) account->port = SMTPS_PORT; else { if (!SmtpPort) { service = getservbyname ("smtp", "tcp"); if (service) SmtpPort = ntohs (service->s_port); else SmtpPort = SMTP_PORT; dprint (3, (debugfile, "Using default SMTP port %d\n", SmtpPort)); } account->port = SmtpPort; } } return 0; }
static int tls_init (void) { static unsigned char init_complete = 0; int err; if (init_complete) return 0; err = gnutls_global_init(); if (err < 0) { mutt_error ("gnutls_global_init: %s", gnutls_strerror(err)); mutt_sleep (2); return -1; } init_complete = 1; return 0; }
static int socket_preconnect (void) { int rc; int save_errno; if (mutt_strlen (Preconnect)) { dprint (2, (debugfile, "Executing preconnect: %s\n", Preconnect)); rc = mutt_system (Preconnect); dprint (2, (debugfile, "Preconnect result: %d\n", rc)); if (rc) { save_errno = errno; mutt_perror (_("Preconnect command failed.")); mutt_sleep (1); return save_errno; } } return 0; }
int mutt_socket_read (CONNECTION* conn, char* buf, size_t len) { int rc; if (conn->fd < 0) { dprint (1, (debugfile, "mutt_socket_read: attempt to read from closed connection\n")); return -1; } rc = conn->conn_read (conn, buf, len); /* EOF */ if (rc == 0) { mutt_error (_("Connection to %s closed"), conn->account.host); mutt_sleep (2); } if (rc <= 0) mutt_socket_close (conn); return rc; }
/* imap_auth_login: Plain LOGIN support */ imap_auth_res_t imap_auth_login (IMAP_DATA* idata, const char* method) { char q_user[SHORT_STRING], q_pass[SHORT_STRING]; char buf[STRING]; int rc; if (mutt_bit_isset (idata->capabilities, LOGINDISABLED)) { mutt_message _("LOGIN disabled on this server."); return IMAP_AUTH_UNAVAIL; } if (mutt_account_getuser (&idata->conn->account)) return IMAP_AUTH_FAILURE; if (mutt_account_getpass (&idata->conn->account)) return IMAP_AUTH_FAILURE; mutt_message _("Logging in..."); imap_quote_string (q_user, sizeof (q_user), idata->conn->account.user); imap_quote_string (q_pass, sizeof (q_pass), idata->conn->account.pass); #ifdef DEBUG /* don't print the password unless we're at the ungodly debugging level * of 5 or higher */ if (debuglevel < IMAP_LOG_PASS) dprint (2, (debugfile, "Sending LOGIN command for %s...\n", idata->conn->account.user)); #endif snprintf (buf, sizeof (buf), "LOGIN %s %s", q_user, q_pass); rc = imap_exec (idata, buf, IMAP_CMD_FAIL_OK | IMAP_CMD_PASS); if (!rc) return IMAP_AUTH_SUCCESS; mutt_error _("Login failed."); mutt_sleep (2); return IMAP_AUTH_FAILURE; }