summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEduardo Chappa <chappa@washington.edu>2021-09-09 21:01:09 -0600
committerEduardo Chappa <chappa@washington.edu>2021-09-09 21:01:09 -0600
commit7feb75607413687c38c51197a73611cb30d39127 (patch)
treed8da4994dcd377360494775f5c1a666a30676e47
parent68ac2c9a0ed6d3b0aa1f14c1b5efc9a44e9d871f (diff)
downloadalpine-7feb75607413687c38c51197a73611cb30d39127.tar.xz
* Alpine will delete passwords that do not work from internal memory
and the local password cache (password file or system local cache.)
-rw-r--r--alpine/alpine.c1
-rw-r--r--alpine/imap.c75
-rw-r--r--alpine/imap.h2
-rw-r--r--imap/src/c-client/imap4r1.c6
-rw-r--r--imap/src/c-client/mail.c14
-rw-r--r--imap/src/c-client/mail.h5
-rw-r--r--imap/src/c-client/nntp.c5
-rw-r--r--imap/src/c-client/pop3.c4
-rw-r--r--imap/src/c-client/smtp.c3
-rw-r--r--pith/imap.c58
-rw-r--r--pith/imap.h2
-rw-r--r--pith/pine.hlp5
12 files changed, 175 insertions, 5 deletions
diff --git a/alpine/alpine.c b/alpine/alpine.c
index 545406bf..7ca1047c 100644
--- a/alpine/alpine.c
+++ b/alpine/alpine.c
@@ -333,6 +333,7 @@ main(int argc, char **argv)
mail_parameters(NULL, SET_FREESTREAMSPAREP, (void *) sp_free_callback);
mail_parameters(NULL, SET_FREEELTSPAREP, (void *) free_pine_elt);
mail_parameters(NULL, SET_FREEBODYSPAREP, (void *) free_body_sparep);
+ mail_parameters(NULL, SET_ERASEPASSWORD, (void *) pine_delete_pwd);
mail_parameters(NULL, SET_OA2CLIENTGETACCESSCODE, (void *) oauth2_get_access_code);
mail_parameters(NULL, SET_OA2CLIENTINFO, (void *) oauth2_get_client_info);
mail_parameters(NULL, SET_OA2DEVICEINFO, (void *) oauth2_set_device_info);
diff --git a/alpine/imap.c b/alpine/imap.c
index 39edda1f..95ce4396 100644
--- a/alpine/imap.c
+++ b/alpine/imap.c
@@ -904,6 +904,16 @@ mm_login_oauth2(NETMBX *mb, char *user, char *method,
if(registered)
oa2list->param[OA2_State].value = login->param[OA2_State].value;
+ if(login->cancel_refresh_token){
+ login->cancel_refresh_token = 0;
+ imap_delete_passwd_auth(&mm_login_list, user,
+ registered ? hostlist2 : hostlist,
+ (mb->sslflag||mb->tlsflag), OA2NAME);
+#ifdef LOCAL_PASSWD_CACHE
+ write_passfile(ps_global->pinerc, mm_login_list);
+#endif /* LOCAL_PASSWD_CACHE */
+ }
+
/*
* We check if we have a refresh token saved somewhere, if so
* we use it to get a new access token, otherwise we need to
@@ -947,7 +957,7 @@ mm_login_oauth2(NETMBX *mb, char *user, char *method,
NewExpirationTime = 0L;
ChangeAccessToken = ChangeRefreshToken = ChangeExpirationTime = 0;
- if(token && *token && !login->cancel_refresh_token){
+ if(token && *token){
char *s, *t;
s = token;
@@ -1002,7 +1012,7 @@ mm_login_oauth2(NETMBX *mb, char *user, char *method,
/* Default to saving what we already had saved */
- SaveRefreshToken = login->cancel_refresh_token ? NULL : NewRefreshToken;
+ SaveRefreshToken = NewRefreshToken;
SaveAccessToken = NewAccessToken;
SaveExpirationTime = NewExpirationTime;
@@ -1068,7 +1078,7 @@ mm_login_oauth2(NETMBX *mb, char *user, char *method,
}
if(token) fs_give((void **) &token);
- if(!ChangeAccessToken && !ChangeRefreshToken && !login->cancel_refresh_token)
+ if(!ChangeAccessToken && !ChangeRefreshToken)
return;
/* get ready to save this information. The format will be
@@ -1121,6 +1131,65 @@ set_alpine_id(char *pname, char *pversion)
return id;
}
+void
+pine_delete_pwd(NETMBX *mb, char *user)
+{
+ char hostlist0[MAILTMPLEN], hostlist1[MAILTMPLEN];
+ char port[20], non_def_port[20];
+ STRLIST_S hostlist[2];
+ MMLOGIN_S *l;
+ struct servent *sv;
+ /* do not invalidate password on cancel */
+ if(ps_global->user_says_cancel != 0)
+ return;
+
+ dprint((9, "pine_delete_pwd\n"));
+
+ /* setup hostlist */
+ non_def_port[0] = '\0';
+ if(mb->port && mb->service &&
+ (sv = getservbyname(mb->service, "tcp")) &&
+ (mb->port != ntohs(sv->s_port))){
+ snprintf(non_def_port, sizeof(non_def_port), ":%lu", mb->port);
+ non_def_port[sizeof(non_def_port)-1] = '\0';
+ dprint((9, "mm_login: using non-default port=%s\n",
+ non_def_port ? non_def_port : "?"));
+ }
+
+ if(*non_def_port){
+ strncpy(hostlist0, mb->host, sizeof(hostlist0)-1);
+ hostlist0[sizeof(hostlist0)-1] = '\0';
+ strncat(hostlist0, non_def_port, sizeof(hostlist0)-strlen(hostlist0)-1);
+ hostlist0[sizeof(hostlist0)-1] = '\0';
+ hostlist[0].name = hostlist0;
+ if(mb->orighost && mb->orighost[0] && strucmp(mb->host, mb->orighost)){
+ strncpy(hostlist1, mb->orighost, sizeof(hostlist1)-1);
+ hostlist1[sizeof(hostlist1)-1] = '\0';
+ strncat(hostlist1, non_def_port, sizeof(hostlist1)-strlen(hostlist1)-1);
+ hostlist1[sizeof(hostlist1)-1] = '\0';
+ hostlist[0].next = &hostlist[1];
+ hostlist[1].name = hostlist1;
+ hostlist[1].next = NULL;
+ }
+ else
+ hostlist[0].next = NULL;
+ }
+ else{
+ hostlist[0].name = mb->host;
+ if(mb->orighost && mb->orighost[0] && strucmp(mb->host, mb->orighost)){
+ hostlist[0].next = &hostlist[1];
+ hostlist[1].name = mb->orighost;
+ hostlist[1].next = NULL;
+ }
+ else
+ hostlist[0].next = NULL;
+ }
+ imap_delete_passwd(&mm_login_list, user, hostlist, mb->sslflag||mb->tlsflag);
+#ifdef LOCAL_PASSWD_CACHE
+ write_passfile(ps_global->pinerc, mm_login_list);
+#endif /* LOCAL_PASSWD_CACHE */
+}
+
/*----------------------------------------------------------------------
receive notification from IMAP
diff --git a/alpine/imap.h b/alpine/imap.h
index 5e1b7703..7885b21e 100644
--- a/alpine/imap.h
+++ b/alpine/imap.h
@@ -32,11 +32,13 @@ int url_local_certdetails(char *);
void pine_sslfailure(char *, char *, unsigned long);
void mm_expunged_current(long unsigned int);
IDLIST *set_alpine_id(char *, char *);
+void pine_delete_pwd(NETMBX *mb, char *user);
char *oauth2_get_access_code(unsigned char *, char *, OAUTH2_S *, int *);
void oauth2_set_device_info(OAUTH2_S *, char *);
int oauth2_elapsed_done(void *);
UCS oauth2device_decode_reply(void *, void *);
+
#ifdef LOCAL_PASSWD_CACHE
int get_passfile_passwd(char *, char **, char *, STRLIST_S *, int);
int get_passfile_passwd_auth(char *, char **, char *, STRLIST_S *, int, char *);
diff --git a/imap/src/c-client/imap4r1.c b/imap/src/c-client/imap4r1.c
index 155b4d5c..b29d7201 100644
--- a/imap/src/c-client/imap4r1.c
+++ b/imap/src/c-client/imap4r1.c
@@ -1206,6 +1206,7 @@ long imap_auth (MAILSTREAM *stream,NETMBX *mb,char *tmp,char *usr)
sprintf (tmp,"Retrying using %s authentication after %.80s",
at->name,lsterr);
mm_log (tmp,NIL);
+ delete_password(mb, usr);
fs_give ((void **) &lsterr);
}
trial = 0; /* initial trial count */
@@ -1215,6 +1216,7 @@ long imap_auth (MAILSTREAM *stream,NETMBX *mb,char *tmp,char *usr)
sprintf (tmp,"Retrying %s authentication after %.80s",at->name,lsterr);
mm_log (tmp,WARN);
fs_give ((void **) &lsterr);
+ delete_password(mb, usr);
}
LOCAL->saslcancel = NIL;
sprintf (tag,"%08lx",0xffffffff & (stream->gensym++));
@@ -1233,6 +1235,7 @@ long imap_auth (MAILSTREAM *stream,NETMBX *mb,char *tmp,char *usr)
if(base && !trial){ /* do it now, instead of later */
mm_log ("IMAP Authentication cancelled",ERROR);
+ delete_password(mb, usr);
return NIL;
}
/* make sure have a response */
@@ -1250,6 +1253,7 @@ long imap_auth (MAILSTREAM *stream,NETMBX *mb,char *tmp,char *usr)
}
if (!trial) { /* if main program requested cancellation */
mm_log ("IMAP Authentication cancelled",ERROR);
+ delete_password(mb, usr);
return NIL;
}
/* no error if protocol-initiated cancel */
@@ -1264,6 +1268,7 @@ long imap_auth (MAILSTREAM *stream,NETMBX *mb,char *tmp,char *usr)
sprintf (tmp,"Can not authenticate to IMAP server: %.80s",lsterr);
mm_log (tmp,ERROR);
}
+ delete_password(mb, usr);
fs_give ((void **) &lsterr);
}
if(mb && *mb->auth){
@@ -1316,6 +1321,7 @@ long imap_login (MAILSTREAM *stream,NETMBX *mb,char *pwd,char *usr)
if (imap_OK (stream,reply = imap_send (stream,"LOGIN",args)))
ret = LONGT; /* success */
else {
+ delete_password(mb, usr);
mm_log (reply->text,WARN);
if (!LOCAL->referral && (trial == imap_maxlogintrials))
mm_log ("Too many login failures",ERROR);
diff --git a/imap/src/c-client/mail.c b/imap/src/c-client/mail.c
index 730201c2..471269c0 100644
--- a/imap/src/c-client/mail.c
+++ b/imap/src/c-client/mail.c
@@ -58,6 +58,8 @@ static mailcache_t mailcache = mm_cache;
static rfc822out_t mail822out = NIL;
/* RFC-822 output generator (new style) */
static rfc822outfull_t mail822outfull = NIL;
+ /* Erase password (client side) */
+static deletepwd_t erase_password = NIL;
/* SMTP verbose callback */
static smtpverbose_t mailsmtpverbose = mm_dlog;
/* proxy copy routine */
@@ -581,6 +583,11 @@ void *mail_parameters (MAILSTREAM *stream,long function,void *value)
case GET_SENDCOMMAND:
ret = (void *) mailsendcommand;
break;
+ case SET_ERASEPASSWORD:
+ erase_password = (deletepwd_t) value;
+ case GET_ERASEPASSWORD:
+ ret = (void *) erase_password;
+ break;
case SET_SERVICENAME:
servicename = (char *) value;
@@ -6242,7 +6249,12 @@ unsigned int mail_lookup_auth_name (char *mechanism,long flags)
return i;
return 0;
}
-
+/* Client side callback warning to delete wrong password */
+void delete_password(NETMBX *mb, char *user)
+{
+ deletepwd_t ep = mail_parameters(NULL, GET_ERASEPASSWORD, NULL);
+ if (ep) (ep)(mb, user);
+}
/* Standard TCP/IP network driver */
static NETDRIVER tcpdriver = {
diff --git a/imap/src/c-client/mail.h b/imap/src/c-client/mail.h
index d40d7ebe..8e848201 100644
--- a/imap/src/c-client/mail.h
+++ b/imap/src/c-client/mail.h
@@ -308,6 +308,8 @@
#define SET_IDLETIMEOUT (long) 453
#define GET_FETCHLOOKAHEADLIMIT (long) 454
#define SET_FETCHLOOKAHEADLIMIT (long) 455
+#define GET_ERASEPASSWORD (long) 456
+#define SET_ERASEPASSWORD (long) 457
/* HTTP SUPPORT DEFINES THEIR OWN SET_ AND GET_ CONSTANTS (490..493). See http.h */
/* 5xx: local file drivers */
@@ -1416,6 +1418,7 @@ typedef ADDRESS *(*parsephrase_t) (char *phrase,char *end,char *host);
typedef void *(*blocknotify_t) (int reason,void *data);
typedef long (*kinit_t) (char *host,char *reason);
typedef void (*sendcommand_t) (MAILSTREAM *stream,char *cmd,long flags);
+typedef void (*deletepwd_t) (NETMBX *mb,char *user);
typedef char *(*newsrcquery_t) (MAILSTREAM *stream,char *mulname,char *name);
typedef void (*getacl_t) (MAILSTREAM *stream,char *mailbox,ACLLIST *acl);
typedef void (*listrights_t) (MAILSTREAM *stream,char *mailbox,char *id,
@@ -1698,6 +1701,8 @@ long mm_diskerror (MAILSTREAM *stream,long errcode,long serious);
void mm_fatal (char *string);
void *mm_cache (MAILSTREAM *stream,unsigned long msgno,long op);
+void delete_password (NETMBX *mb, char *user);
+
extern STRINGDRIVER mail_string;
void mail_versioncheck (char *version);
void mail_link (DRIVER *driver);
diff --git a/imap/src/c-client/nntp.c b/imap/src/c-client/nntp.c
index b8d89893..3875b351 100644
--- a/imap/src/c-client/nntp.c
+++ b/imap/src/c-client/nntp.c
@@ -2058,6 +2058,7 @@ long nntp_send_auth_work (SENDSTREAM *stream,NETMBX *mb,char *pwd,long flags)
sprintf (tmp,"Retrying using %s authentication after %.80s",
at->name,lsterr);
mm_log (tmp,NIL);
+ delete_password(mb, mb ? mb->user : NULL);
fs_give ((void **) &lsterr);
}
trial = 0; /* initial trial count */
@@ -2066,6 +2067,7 @@ long nntp_send_auth_work (SENDSTREAM *stream,NETMBX *mb,char *pwd,long flags)
if (lsterr) {
sprintf (tmp,"Retrying %s authentication after %.80s",at->name,lsterr);
mm_log (tmp,WARN);
+ delete_password(mb, mb ? mb->user : NULL);
fs_give ((void **) &lsterr);
}
stream->saslcancel = NIL;
@@ -2096,6 +2098,7 @@ long nntp_send_auth_work (SENDSTREAM *stream,NETMBX *mb,char *pwd,long flags)
sprintf (tmp,"Can not authenticate to NNTP server: %.80s",lsterr);
mm_log (tmp,ERROR);
}
+ delete_password(mb, mb ? mb->user : NULL);
fs_give ((void **) &lsterr);
}
else if (mb->secflag) /* no SASL, can't do /secure */
@@ -2124,6 +2127,8 @@ long nntp_send_auth_work (SENDSTREAM *stream,NETMBX *mb,char *pwd,long flags)
stream->sensitive = T; /* hide this command */
if (nntp_send_work (stream,"AUTHINFO PASS",pwd2) == NNTPAUTHED)
ret = LONGT; /* password OK */
+ else
+ delete_password(mb, mb ? mb->user : NULL);
stream->sensitive = NIL; /* unhide */
if (ret) break; /* OK if successful */
default: /* authentication failed */
diff --git a/imap/src/c-client/pop3.c b/imap/src/c-client/pop3.c
index 89c3d9cb..ea8a64f5 100644
--- a/imap/src/c-client/pop3.c
+++ b/imap/src/c-client/pop3.c
@@ -628,12 +628,14 @@ long pop3_auth (MAILSTREAM *stream,NETMBX *mb,char *pwd,char *usr)
at->name,t);
mm_log (pwd,NIL);
fs_give ((void **) &t);
+ delete_password(mb, usr);
}
trial = 0; /* initial trial count */
do {
if (t) {
sprintf (pwd,"Retrying %s authentication after %.80s",at->name,t);
mm_log (pwd,WARN);
+ delete_password(mb, usr);
fs_give ((void **) &t);
}
if(at->flags & AU_SINGLE){
@@ -664,6 +666,7 @@ long pop3_auth (MAILSTREAM *stream,NETMBX *mb,char *pwd,char *usr)
sprintf (pwd,"Can not authenticate to POP3 server: %.80s",t);
mm_log (pwd,ERROR);
}
+ delete_password(mb, usr);
fs_give ((void **) &t);
}
if(mb && *mb->auth){
@@ -696,6 +699,7 @@ long pop3_auth (MAILSTREAM *stream,NETMBX *mb,char *pwd,char *usr)
LOCAL->sensitive=NIL; /* unhide */
}
if (!ret) { /* failure */
+ delete_password(mb, usr);
mm_log (LOCAL->reply,WARN);
if (trial == pop3_maxlogintrials)
mm_log ("Too many login failures",ERROR);
diff --git a/imap/src/c-client/smtp.c b/imap/src/c-client/smtp.c
index bee34565..7c1f9936 100644
--- a/imap/src/c-client/smtp.c
+++ b/imap/src/c-client/smtp.c
@@ -301,6 +301,7 @@ long smtp_auth (SENDSTREAM *stream,NETMBX *mb,char *tmp)
sprintf (tmp,"Retrying using %s authentication after %.80s",
at->name,lsterr);
mm_log (tmp,NIL);
+ delete_password(mb, usr);
fs_give ((void **) &lsterr);
}
trial = 0; /* initial trial count */
@@ -310,6 +311,7 @@ long smtp_auth (SENDSTREAM *stream,NETMBX *mb,char *tmp)
sprintf (tmp,"Retrying %s authentication after %.80s",at->name,lsterr);
mm_log (tmp,WARN);
fs_give ((void **) &lsterr);
+ delete_password(mb, usr);
}
if(at->flags & AU_SINGLE){
sprintf(tmp, "AUTH %s", at->name);
@@ -343,6 +345,7 @@ long smtp_auth (SENDSTREAM *stream,NETMBX *mb,char *tmp)
sprintf (tmp,"Can not authenticate to SMTP server: %.80s",lsterr);
mm_log (tmp,ERROR);
}
+ delete_password(mb, usr);
fs_give ((void **) &lsterr);
}
if(mb && *mb->auth){
diff --git a/pith/imap.c b/pith/imap.c
index f91937b1..7c74efaf 100644
--- a/pith/imap.c
+++ b/pith/imap.c
@@ -1149,6 +1149,64 @@ imap_flush_passwd_cache(int dumpcache)
}
}
+void
+imap_delete_passwd(MMLOGIN_S **m_list, char *user, STRLIST_S *hostlist, int altflag)
+{
+ if(m_list == NULL || *m_list == NULL) return;
+ imap_delete_passwd_auth(m_list, user, hostlist, altflag,
+ strchr((*m_list)->user, PWDAUTHSEP) != NULL ? OA2NAME : NULL);
+}
+
+void
+imap_delete_passwd_auth(MMLOGIN_S **m_list, char *user,
+ STRLIST_S *hostlist, int altflag, char *authtype)
+{
+ MMLOGIN_S *l, *p;
+ int len, offset;
+
+ if(m_list == NULL || *m_list == NULL) return;
+
+ dprint((9, "imap_delete_password: user=%s, host=%s, authtype=%s.",
+ user ? user : "no user!?",
+ hostlist && hostlist->name ? hostlist->name : "unknown host",
+ authtype ? authtype : "password authentication"));
+
+ len = authtype ? strlen(authtype) : 0;
+ offset = authtype ? 1 : 0;
+ for(p = *m_list; p; p = p->next){
+ if(imap_same_host_auth(p->hosts, hostlist, authtype)
+ && *user
+ && (len == 0 || (!struncmp(p->user, authtype, len)
+ && p->user[len] == PWDAUTHSEP))
+ && !strcmp(user, p->user + len + offset)
+ && p->altflag == altflag)
+ break;
+ }
+
+ dprint((9, "imap_delete_password: %s",
+ p ? "found a match!" : "did not find a match!"));
+
+ if(!p) return;
+
+ /* relink *mlist */
+ if(p == *m_list)
+ *m_list = (*m_list)->next;
+ else{
+ for(l = *m_list; l && l->next != p; l = l->next);
+ l->next = p->next;
+ }
+ /* so now p is out of the list. Free it */
+ p->next = NULL;
+ if(p->user) fs_give((void **) &p->user);
+
+ if(!(p->passwd >= (char *) private_store
+ && p->passwd <= (char *) private_store + sizeof(private_store)))
+ fs_give((void **) &p->passwd);
+
+ free_strlist(&p->hosts);
+ fs_give((void **) &p);
+ dprint((9, "imap_delete_password: done with deletion."));
+}
/*
* Mimics fs_get except it only works for char * (no alignment hacks), it
diff --git a/pith/imap.h b/pith/imap.h
index b6575565..8c78a9c6 100644
--- a/pith/imap.h
+++ b/pith/imap.h
@@ -131,6 +131,8 @@ int imap_get_passwd_auth (MMLOGIN_S *, char **, char *, STRLIST_S *, int, char *
void imap_set_passwd(MMLOGIN_S **, char *, char *, STRLIST_S *, int, int, int);
void imap_set_passwd_auth(MMLOGIN_S **, char *, char *, STRLIST_S *, int, int, int, char *);
void imap_flush_passwd_cache(int);
+void imap_delete_passwd_auth (MMLOGIN_S **, char *, STRLIST_S *, int, char *);
+void imap_delete_passwd (MMLOGIN_S **, char *, STRLIST_S *, int);
/* currently mandatory to implement stubs */
diff --git a/pith/pine.hlp b/pith/pine.hlp
index 2b865435..0e3f27cc 100644
--- a/pith/pine.hlp
+++ b/pith/pine.hlp
@@ -140,7 +140,7 @@ with help text for the config screen and the composer that didn't have any
reasonable place to be called from.
Dummy change to get revision in pine.hlp
============= h_revision =================
-Alpine Commit 587 2021-09-07 08:43:39
+Alpine Commit 588 2021-09-09 21:01:05
============= h_news =================
<HTML>
<HEAD>
@@ -237,6 +237,9 @@ New features include:
<LI> Add option -xoauth2-flow to the command line, so that users can specify the
parameters to set up an xoauth2 connection through the command line.
+
+<LI> Alpine deletes, from its internal memory and external cache, passwords
+ that do not work, even if they were saved by the user.
</UL>
<P>