cmd_status cmd_capa : 2; /* optional command CAPA */
cmd_status cmd_stls : 2; /* optional command STLS */
cmd_status cmd_uidl : 2; /* optional command UIDL */
- cmd_status cmd_top : 2; /* optional command TOP */
+ cmd_status cmd_top : 2; /* optional command TOP */
+ cmd_status cmd_user : 2; /* optional command USER */
unsigned resp_codes : 1; /* server supports extended response codes */
unsigned expire : 1; /* expire is greater than 0 */
unsigned clear_cache : 1;
/* }}} */
/* Authentication {{{ */
-/* SASL authenticator */
static pop_auth_res_t pop_auth_sasl(pop_data_t *pop_data, const char *method)
{
sasl_conn_t *saslconn;
return POP_A_FAILURE;
}
-/* APOP authenticator */
static pop_auth_res_t pop_auth_apop(pop_data_t *pop_data, const char *method)
{
MD5_CTX mdContext;
return POP_A_SUCCESS;
case PQ_NOT_CONNECTED:
return POP_A_SOCKET;
- case PFD_FUNCT_ERROR:
- case PQ_ERR:
default:
- break;
+ mutt_error("%s %s", _("APOP authentication failed."), pop_data->err_msg);
+ mutt_sleep(2);
+ return POP_A_FAILURE;
}
-
- mutt_error("%s %s", _("APOP authentication failed."), pop_data->err_msg);
- mutt_sleep(2);
-
- return POP_A_FAILURE;
}
-/* USER authenticator */
static pop_auth_res_t pop_auth_user(pop_data_t *pop_data, const char *method)
{
char buf[LONG_STRING];
pop_query_status ret;
- mutt_message(_("Logging in..."));
+ if (pop_data->cmd_user == CMD_NOT_AVAILABLE)
+ return POP_A_UNAVAIL;
+
+ mutt_message _("Authenticating (USER)...");
snprintf(buf, sizeof(buf), "USER %s\r\n", pop_data->conn->account.user);
ret = pop_query(pop_data, buf, sizeof (buf));
- if (ret == PQ_ERR) {
- snprintf(pop_data->err_msg, sizeof(pop_data->err_msg),
- _("Command USER is not supported by server."));
+ if (pop_data->cmd_user == CMD_UNKNOWN) {
+ if (ret == PQ_OK)
+ pop_data->cmd_user = CMD_AVAILABLE;
+ if (ret == PQ_ERR)
+ pop_data->cmd_user = CMD_NOT_AVAILABLE;
}
if (ret == PQ_OK) {
case PQ_NOT_CONNECTED:
return POP_A_SOCKET;
default:
- mutt_error ("%s %s", _("Login failed."), pop_data->err_msg);
- mutt_sleep (2);
+ mutt_error("%s %s", _("USER authentication failed."), pop_data->err_msg);
+ mutt_sleep(2);
return POP_A_FAILURE;
}
}
};
ACCOUNT *act = &pop_data->conn->account;
- int attempts = 0, ret = POP_A_UNAVAIL;
const pop_auth_t *auth;
+ int attempts = 0;
if (mutt_account_getuser(act) || !act->user[0]
|| mutt_account_getpass(act) || !act->pass[0])
if (auth->method && ascii_strcasecmp(auth->method, buf))
continue;
- ret = auth->do_auth(pop_data, buf);
- if (ret == POP_A_SOCKET) {
- if (pop_connect(pop_data) == PQ_OK) {
- ret = auth->do_auth(pop_data, buf);
- } else {
- ret = POP_A_FAILURE;
- }
- }
-
- if (ret != POP_A_UNAVAIL)
+ switch (auth->do_auth(pop_data, buf)) {
+ case POP_A_SUCCESS:
+ return PQ_OK;
+ case POP_A_SOCKET:
+ return PQ_NOT_CONNECTED;
+ case POP_A_UNAVAIL:
+ break;
+ case POP_A_FAILURE:
attempts++;
- if (ret == POP_A_SUCCESS || ret == POP_A_SOCKET) {
- goto ok;
+ break;
}
}
}
} else {
- /* Fall back to default: any authenticator */
for (auth = pop_authenticators; auth->do_auth; auth++) {
- ret = auth->do_auth(pop_data, auth->method);
- if (ret == POP_A_SOCKET) {
- if (pop_connect(pop_data) == PQ_OK) {
- ret = auth->do_auth(pop_data, auth->method);
- } else {
- ret = POP_A_FAILURE;
- }
- }
-
- if (ret != POP_A_UNAVAIL)
+ switch (auth->do_auth(pop_data, auth->method)) {
+ case POP_A_SUCCESS:
+ return PQ_OK;
+ case POP_A_SOCKET:
+ return PQ_NOT_CONNECTED;
+ case POP_A_UNAVAIL:
+ break;
+ case POP_A_FAILURE:
attempts++;
- if (ret == POP_A_SUCCESS || ret == POP_A_SOCKET)
break;
+ }
}
}
- ok:
- switch (ret) {
- case POP_A_SUCCESS:
- return PQ_OK;
- case POP_A_SOCKET:
- return PQ_NOT_CONNECTED;
- case POP_A_UNAVAIL:
- if (!attempts)
- mutt_error(_("No authenticators available"));
- }
-
+ if (!attempts)
+ mutt_error(_("No authenticators available"));
return PQ_ERR;
}