summaryrefslogtreecommitdiff
path: root/alpine
diff options
context:
space:
mode:
authorEduardo Chappa <chappa@washington.edu>2020-06-12 02:21:59 -0600
committerEduardo Chappa <chappa@washington.edu>2020-06-12 02:21:59 -0600
commit6c120b9e3730f997af56fbbe19229915b6380b2d (patch)
tree2acef9df0ffa1991a90cc1ded54400d1e0c1b35f /alpine
parentd600da07926e1ec3243c2a96cd988c61d6a97614 (diff)
downloadalpine-6c120b9e3730f997af56fbbe19229915b6380b2d.tar.xz
* Initial implementation of XOAUTH2 authentication support for Outlook.
Based on documentation suggested by Andrew C Aitchison.
Diffstat (limited to 'alpine')
-rw-r--r--alpine/alpine.c1
-rw-r--r--alpine/imap.c259
-rw-r--r--alpine/imap.h3
-rw-r--r--alpine/keymenu.c14
-rw-r--r--alpine/keymenu.h1
-rw-r--r--alpine/mailview.c16
-rw-r--r--alpine/mailview.h5
-rw-r--r--alpine/xoauth2.h4
-rw-r--r--alpine/xoauth2conf.c6
9 files changed, 277 insertions, 32 deletions
diff --git a/alpine/alpine.c b/alpine/alpine.c
index 8155f54a..d72c60cf 100644
--- a/alpine/alpine.c
+++ b/alpine/alpine.c
@@ -344,6 +344,7 @@ main(int argc, char **argv)
mail_parameters(NULL, SET_FREEBODYSPAREP, (void *) free_body_sparep);
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);
init_pinerc(pine_state, &init_pinerc_debugging);
diff --git a/alpine/imap.c b/alpine/imap.c
index f86587e6..54a58c68 100644
--- a/alpine/imap.c
+++ b/alpine/imap.c
@@ -153,45 +153,48 @@ OAUTH2_S alpine_oauth2_list[] =
{"grant_type", "refresh_token"},
{"response_type", "code"},
{"state", NULL},
- {"prompt", NULL}
+ {"prompt", NULL},
+ {"device_code", NULL}
},
{{"GET", "https://accounts.google.com/o/oauth2/auth",
{OA2_Id, OA2_Scope, OA2_Redirect, OA2_Response, OA2_End, OA2_End, OA2_End}},
{"POST", "https://accounts.google.com/o/oauth2/token",
{OA2_Id, OA2_Secret, OA2_Redirect, OA2_GrantTypeforAccessToken, OA2_Code, OA2_End, OA2_End}},
{"POST", "https://accounts.google.com/o/oauth2/token",
- {OA2_Id, OA2_Secret, OA2_RefreshToken, OA2_GrantTypefromRefreshToken, OA2_End, OA2_End, OA2_End}}
+ {OA2_Id, OA2_Secret, OA2_RefreshToken, OA2_GrantTypefromRefreshToken, OA2_End, OA2_End, OA2_End}},
+ {NULL, NULL, {OA2_End, OA2_End, OA2_End, OA2_End, OA2_End, OA2_End, OA2_End}}
},
- NULL, 0
+ {NULL, NULL, NULL, 0, 0, NULL}, /* devicecode info */
+ NULL, 0, 0
},
-#if 0
{"Outlook",
- {"outlook.office365.com", "smtp.gmail.com", NULL, NULL},
-// {{"client_id", "2d681b88-9675-4ff0-b033-4de97dcb7a04"},
-// {"client_secret", "FHLY770;@%fmrzxbnEKG44!"},
+ {"outlook.office365.com", "smtp.office365.com", NULL, NULL},
{{"client_id", NULL},
{"client_secret", NULL},
{"code", NULL},
{"refresh_token", NULL},
- {"scope", "openid offline_access profile https://outlook.office.com/mail.readwrite https://outlook.office.com/mail.readwrite.shared https://outlook.office.com/mail.send https://outlook.office.com/mail.send.shared https://outlook.office.com/calendars.readwrite https://outlook.office.com/calendars.readwrite.shared https://outlook.office.com/contacts.readwrite https://outlook.office.com/contacts.readwrite.shared https://outlook.office.com/tasks.readwrite https://outlook.office.com/tasks.readwrite.shared https://outlook.office.com/mailboxsettings.readwrite https://outlook.office.com/people.read https://outlook.office.com/user.readbasic.all"},
- {"redirect_uri", "https://login.microsoftonline.com/common/oauth2/nativeclient"},
- {"grant_type", "authorization_code"},
+ {"scope", "offline_access https://outlook.office.com/IMAP.AccessAsUser.All https://outlook.office.com/SMTP.Send"},
+ {"grant_type", "urn:ietf:params:oauth:grant-type:device_code"},
+ {"scope", "https://graph.microsoft.com/mail.read"},
{"grant_type", "refresh_token"},
{"response_type", "code"},
{"state", NULL},
- {"prompt", "login"}
+ {"prompt", "login"},
+ {"device_code", NULL}
},
{{"GET", "https://login.microsoftonline.com/common/oauth2/authorize",
{OA2_Id, OA2_Scope, OA2_Redirect, OA2_Response, OA2_State, OA2_Prompt, OA2_End}},
- {"POST", "https://login.microsoftonline.com/common/oauth2/token",
- {OA2_Id, OA2_Secret, OA2_Redirect, OA2_GrantTypeforAccessToken, OA2_Code, OA2_Scope, OA2_End}},
- {"POST", "https://login.microsoftonline.com/common/oauth2/token",
- {OA2_Id, OA2_Secret, OA2_RefreshToken, OA2_GrantTypefromRefreshToken, OA2_End, OA2_End, OA2_End}}
+ {"POST", "https://login.microsoftonline.com/common/oauth2/v2.0/token",
+ {OA2_Id, OA2_Redirect, OA2_DeviceCode, OA2_End, OA2_End, OA2_End}},
+ {"POST", "https://login.microsoftonline.com/common/oauth2/v2.0/token",
+ {OA2_Id, OA2_RefreshToken, OA2_Scope, OA2_GrantTypefromRefreshToken, OA2_End, OA2_End, OA2_End}},
+ {"POST", "https://login.microsoftonline.com/common/oauth2/v2.0/devicecode",
+ {OA2_Id, OA2_Scope, OA2_End, OA2_End, OA2_End, OA2_End, OA2_End}}
},
- NULL, 0
+ {NULL, NULL, NULL, 0, 0, NULL},
+ NULL, 0, 0
},
-#endif
- { NULL, NULL, NULL, NULL, NULL, 0},
+ { NULL, NULL, NULL, NULL, NULL, NULL, 0, 0},
};
typedef struct auth_code_s {
@@ -199,6 +202,219 @@ typedef struct auth_code_s {
int answer;
} AUTH_CODE_S;
+UCS
+oauth2device_decode_reply(void *datap, void *replyp)
+{
+ OAUTH2_DEVICEPROC_S *av = (OAUTH2_DEVICEPROC_S *)datap;
+ int reply = *(int *) replyp;
+
+ return reply < 0 ? av->code_failure : (reply == 0 ? av->code_success : av->code_wait);
+}
+
+int
+oauth2_elapsed_done(void *aux_valuep)
+{
+ OAUTH2_S *oauth2 = aux_valuep ? ((OAUTH2_DEVICEPROC_S *) aux_valuep)->xoauth2 : NULL;
+ static time_t savedt = 0, now;
+ int rv = 0;
+
+ if(aux_valuep == NULL) savedt = 0; /* reset last time we approved */
+ else{
+ now = time(0);
+ if(oauth2->devicecode.interval + now >= savedt)
+ savedt = now;
+ else
+ rv = -1;
+ }
+ return rv;
+}
+
+void
+oauth2_set_device_info(OAUTH2_S *oa2, char *method)
+{
+ char tmp[MAILTMPLEN];
+ char *code;
+ char *name = oa2->name;
+ int aux_rv_value;
+ OAUTH2_DEVICECODE_S *deviceinfo = &oa2->devicecode;
+ OAUTH2_DEVICEPROC_S aux_value;
+
+ if(ps_global->ttyo){
+ SCROLL_S sargs;
+ STORE_S *in_store, *out_store;
+ gf_io_t pc, gc;
+ HANDLE_S *handles = NULL;
+ AUTH_CODE_S user_input;
+
+ if(!(in_store = so_get(CharStar, NULL, EDIT_ACCESS)) ||
+ !(out_store = so_get(CharStar, NULL, EDIT_ACCESS)))
+ goto try_wantto;
+
+ aux_value.xoauth2 = oa2;
+ aux_value.code_success = 'e';
+ aux_value.code_failure = 'e';
+ aux_value.code_wait = NO_OP_COMMAND;
+
+ so_puts(in_store, "<HTML><P>");
+ sprintf(tmp, _("<CENTER>Authorizing Alpine Access to %s Email Services</CENTER>"), name);
+ so_puts(in_store, tmp);
+ sprintf(tmp, _("<P>Alpine is attempting to log you into your %s account, using the %s method."), name, method),
+ so_puts(in_store, tmp);
+
+ if(deviceinfo->verification_uri && deviceinfo->user_code){
+ sprintf(tmp,
+ _("</P><P>To sign in, use a web browser to open the page <A HREF=\"%s\">%s</A> and enter the code \"%s\" without the quotes."),
+ deviceinfo->verification_uri, deviceinfo->verification_uri, deviceinfo->user_code);
+ so_puts(in_store, tmp);
+ }
+ else{
+ so_puts(in_store, "</P><P>");
+ so_puts(in_store, deviceinfo->message);
+ }
+ so_puts(in_store, _("</P><P> Alpine will try to use your URL Viewers setting to find a browser to open this URL."));
+ sprintf(tmp, _(" When you open this link, you will be sent to %s's servers to complete this process."), name);
+ so_puts(in_store, tmp);
+ so_puts(in_store, _(" Alternatively, you can copy and paste the previous link and open it with the browser of your choice."));
+
+ so_puts(in_store, _("</P><P> After you open the previous link, please enter the code above, and then you will be asked to authenticate and later "));
+ so_puts(in_store, _("to grant access to Alpine to your data. "));
+ so_puts(in_store, _("</P><P> Once you have authorized Alpine, you will be asked if you want to preserve the Refresh Token and Access Code. If you do "));
+ so_puts(in_store, _("not wish to repeat this process again, answer \'Y\'es. If you did this process quickly, your connection to the server will still be "));
+ so_puts(in_store, _("alive at the end of this process, and your connection will proceed from there."));
+ so_puts(in_store, _(" </P><P>If you do not wish to proceed, cancel at any time by pressing 'E' to exit"));
+ so_puts(in_store, _("</P></HTML>"));
+
+ so_seek(in_store, 0L, 0);
+ init_handles(&handles);
+ gf_filter_init();
+ gf_link_filter(gf_html2plain,
+ gf_html2plain_opt(NULL,
+ ps_global->ttyo->screen_cols, non_messageview_margin(),
+ &handles, NULL, GFHP_LOCAL_HANDLES));
+ gf_set_so_readc(&gc, in_store);
+ gf_set_so_writec(&pc, out_store);
+ gf_pipe(gc, pc);
+ gf_clear_so_writec(out_store);
+ gf_clear_so_readc(in_store);
+
+ memset(&sargs, 0, sizeof(SCROLL_S));
+ sargs.text.handles = handles;
+ sargs.text.text = so_text(out_store);
+ sargs.text.src = CharStar;
+ sargs.text.desc = _("help text");
+ sargs.bar.title = _("SETTING UP XOAUTH2 AUTHORIZATION");
+ sargs.proc.tool = oauth2_auth_answer;
+ sargs.proc.data.p = (void *)&user_input;
+ sargs.keys.menu = &oauth2_device_auth_keymenu;
+ /* don't want to re-enter c-client */
+ sargs.quell_newmail = 1;
+ setbitmap(sargs.keys.bitmap);
+ sargs.help.text = h_oauth2_start;
+ sargs.help.title = _("HELP FOR SETTING UP XOAUTH2");
+ sargs.aux_function = oauth2deviceinfo_get_accesscode;
+ sargs.aux_value = (void *) &aux_value;
+ sargs.aux_condition = oauth2_elapsed_done;
+ sargs.decode_aux_rv_value = oauth2device_decode_reply;
+ sargs.aux_rv_value = (void *) &aux_rv_value;
+
+ do {
+ scrolltool(&sargs);
+ ps_global->mangled_screen = 1;
+ ps_global->painted_body_on_startup = 0;
+ ps_global->painted_footer_on_startup = 0;
+ } while (user_input.answer != 'e');
+
+ so_give(&in_store);
+ so_give(&out_store);
+ free_handles(&handles);
+ oauth2_elapsed_done(NULL);
+ }
+ else{
+ int flags, rc, q_line;
+ /* TRANSLATORS: user needs to input an access code from the server */
+ char prompt[MAILTMPLEN], token[MAILTMPLEN];
+ /*
+ * If screen hasn't been initialized yet, use want_to.
+ */
+try_wantto:
+
+ tmp_20k_buf[0] = '\0';
+ snprintf(tmp_20k_buf+strlen(tmp_20k_buf), SIZEOF_20KBUF-strlen(tmp_20k_buf),
+ _("Authorizing Alpine Access to %s Email Services\n\n"), name);
+ tmp_20k_buf[SIZEOF_20KBUF-1] = '\0';
+
+ snprintf(tmp_20k_buf+strlen(tmp_20k_buf), SIZEOF_20KBUF-strlen(tmp_20k_buf),
+ _("Alpine is attempting to log you into your %s account, using the %s method. "), name, method),
+ tmp_20k_buf[SIZEOF_20KBUF-1] = '\0';
+
+ if(deviceinfo->verification_uri && deviceinfo->user_code){
+ snprintf(tmp_20k_buf+strlen(tmp_20k_buf), SIZEOF_20KBUF-strlen(tmp_20k_buf),
+ _("To sign in, user a web browser to open the page %s and enter the code \"%s\" without the quotes.\n\n"),
+ deviceinfo->verification_uri, deviceinfo->user_code);
+ tmp_20k_buf[SIZEOF_20KBUF-1] = '\0';
+ }
+ else{
+ snprintf(tmp_20k_buf+strlen(tmp_20k_buf), SIZEOF_20KBUF-strlen(tmp_20k_buf),
+ "%s\n\n", deviceinfo->message);
+ tmp_20k_buf[SIZEOF_20KBUF-1] = '\0';
+ }
+
+ snprintf(tmp_20k_buf+strlen(tmp_20k_buf), SIZEOF_20KBUF-strlen(tmp_20k_buf),
+ _("Copy and paste the previous URL into a web browser that supports javascript, to take you to %s's servers to complete this process.\n\n"), name);
+ tmp_20k_buf[SIZEOF_20KBUF-1] = '\0';
+
+ snprintf(tmp_20k_buf+strlen(tmp_20k_buf), SIZEOF_20KBUF-strlen(tmp_20k_buf),
+ "%s", _("After you open the previous link, please enter the code above, and then you will be asked to authenticate and later "));
+ tmp_20k_buf[SIZEOF_20KBUF-1] = '\0';
+
+ snprintf(tmp_20k_buf+strlen(tmp_20k_buf), SIZEOF_20KBUF-strlen(tmp_20k_buf),
+ "%s", _("to grant access to Alpine to your data.\n\n"));
+ tmp_20k_buf[SIZEOF_20KBUF-1] = '\0';
+
+ snprintf(tmp_20k_buf+strlen(tmp_20k_buf), SIZEOF_20KBUF-strlen(tmp_20k_buf),
+ "%s", _(" Once you have authorized Alpine, you will be asked if you want to preserve the Refresh Token and Access Code. "));
+ tmp_20k_buf[SIZEOF_20KBUF-1] = '\0';
+
+ snprintf(tmp_20k_buf+strlen(tmp_20k_buf), SIZEOF_20KBUF-strlen(tmp_20k_buf),
+ "%s", _("If you do not wish to repeat this process again, answer \'Y\'es. If you did this process quickly, your connection "));
+ tmp_20k_buf[SIZEOF_20KBUF-1] = '\0';
+
+ snprintf(tmp_20k_buf+strlen(tmp_20k_buf), SIZEOF_20KBUF-strlen(tmp_20k_buf),
+ "%s", _("to the server will still be alive at the end of this process, and your connection will proceed from there.\n\n"));
+ tmp_20k_buf[SIZEOF_20KBUF-1] = '\0';
+
+ display_init_err(tmp_20k_buf, 0);
+ memset((void *)tmp, 0, sizeof(tmp));
+ strncpy(tmp, _("Alpine would like to get authorization to access your email. Proceed "), sizeof(tmp));
+ tmp[sizeof(tmp)-1] = '\0';
+
+ if(want_to(tmp, 'n', 'x', NO_HELP, WT_NORM) == 'y'){
+ int rv;
+ UCS ch;
+ q_line = -(ps_global->ttyo ? ps_global->ttyo->footer_rows : 3);
+ flags = OE_APPEND_CURRENT;
+
+ snprintf(tmp_20k_buf+strlen(tmp_20k_buf), SIZEOF_20KBUF-strlen(tmp_20k_buf),
+ "%s", _("After you are done going through the process described above, press \'y\' to continue, or \'n\' to cancel\n"));
+ tmp_20k_buf[SIZEOF_20KBUF-1] = '\0';
+
+ aux_value.xoauth2 = oa2;
+ aux_value.code_success = 'y';
+ aux_value.code_failure = 'n';
+ aux_value.code_wait = 'w';
+
+ strncpy(tmp, _("Continue waiting"), sizeof(tmp));
+ tmp[sizeof(tmp)-1] = '\0';
+ do {
+ if(oauth2_elapsed_done((void *) &aux_value) == 0)
+ oauth2deviceinfo_get_accesscode((void *) &aux_value, (void *) &rv);
+ ch = oauth2device_decode_reply((void *) &aux_value, (void *) &rv);
+ } while (ch == 'w' || want_to(tmp, 'n', 'x', NO_HELP, WT_NORM) == 'y');
+ oauth2_elapsed_done(NULL);
+ }
+ }
+}
+
char *
oauth2_get_access_code(unsigned char *url, char *method, OAUTH2_S *oauth2, int *tryanother)
{
@@ -238,7 +454,7 @@ oauth2_get_access_code(unsigned char *url, char *method, OAUTH2_S *oauth2, int *
so_puts(in_store, _("</P><P> If you completed these steps successfully, you are ready to move to the second part, where you will authorize Gmail to give access to Alpine to access your email."));
}
- so_puts(in_store, _("</P><P><A NAME=\"secondpart\">In order</A> to authrorize Alpine to access your email, Alpine needs to open the following URL:"));
+ so_puts(in_store, _("</P><P><A NAME=\"secondpart\">In order</A> to authorize Alpine to access your email, Alpine needs to open the following URL:"));
so_puts(in_store,"</P><P>");
sprintf(tmp_20k_buf, _("<A HREF=\"%s\">%s</A>"), url, url);
so_puts(in_store, tmp_20k_buf);
@@ -362,9 +578,8 @@ try_wantto:
display_init_err(tmp_20k_buf, 0);
memset((void *)tmp, 0, sizeof(tmp));
- strncpy(tmp, _("Alpine would like to get authorization to access your email: "), sizeof(tmp));
+ strncpy(tmp, _("Alpine would like to get authorization to access your email. Proceed "), sizeof(tmp));
tmp[sizeof(tmp)-1] = '\0';
- strncat(tmp, _(": Proceed "), sizeof(tmp)-strlen(tmp)-1);
if(want_to(tmp, 'n', 'x', NO_HELP, WT_NORM) == 'y'){
q_line = -(ps_global->ttyo ? ps_global->ttyo->footer_rows : 3);
@@ -623,6 +838,7 @@ mm_login_oauth2(NETMBX *mb, char *user, char *method,
if(NewAccessToken && (NewExpirationTime == 0L || !*NewAccessToken))
fs_give((void **) &NewAccessToken);
}
+ else login->first_time++;
/* Default to saving what we already had saved */
@@ -685,6 +901,7 @@ mm_login_oauth2(NETMBX *mb, char *user, char *method,
oa2list->param[OA2_RefreshToken].value = SaveRefreshToken;
oa2list->access_token = SaveAccessToken;
oa2list->expiration = SaveExpirationTime;
+ oa2list->first_time = login->first_time;
*login = *oa2list; /* load login pointer */
}
diff --git a/alpine/imap.h b/alpine/imap.h
index c4195fba..e595e196 100644
--- a/alpine/imap.h
+++ b/alpine/imap.h
@@ -32,6 +32,9 @@ int url_local_certdetails(char *);
void pine_sslfailure(char *, char *, unsigned long);
void mm_expunged_current(long unsigned int);
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);
diff --git a/alpine/keymenu.c b/alpine/keymenu.c
index 65ba6f88..519622a6 100644
--- a/alpine/keymenu.c
+++ b/alpine/keymenu.c
@@ -577,6 +577,20 @@ struct key oauth2_alpine_auth_keys[] =
{"S", N_("Save"), {MC_SAVETEXT,1,{'s'}}, KS_SAVE}};
INST_KEY_MENU(oauth2_auth_keymenu, oauth2_alpine_auth_keys);
+struct key oauth2_device_alpine_auth_keys[] =
+ {HELP_MENU,
+ NULL_MENU,
+ NULL_MENU,
+ {"V","[" N_("View URL") "]",{MC_VIEW_HANDLE,3,{'v',ctrl('M'),ctrl('J')}},KS_NONE},
+ {"E",N_("Exit"),{MC_NO,1,{'e'}},KS_NONE},
+ NULL_MENU,
+ PREVPAGE_MENU,
+ NEXTPAGE_MENU,
+ PRYNTTXT_MENU,
+ WHEREIS_MENU,
+ FWDEMAIL_MENU,
+ {"S", N_("Save"), {MC_SAVETEXT,1,{'s'}}, KS_SAVE}};
+INST_KEY_MENU(oauth2_device_auth_keymenu, oauth2_alpine_auth_keys);
struct key forge_keys[] =
{HELP_MENU,
diff --git a/alpine/keymenu.h b/alpine/keymenu.h
index e29ec201..87d1151d 100644
--- a/alpine/keymenu.h
+++ b/alpine/keymenu.h
@@ -585,6 +585,7 @@ extern struct key_menu cancel_keymenu,
ans_certfail_keymenu,
ans_certquery_keymenu,
oauth2_auth_keymenu,
+ oauth2_device_auth_keymenu,
forge_keymenu,
listmgr_keymenu,
index_keymenu,
diff --git a/alpine/mailview.c b/alpine/mailview.c
index a6531ea3..d1ace2f2 100644
--- a/alpine/mailview.c
+++ b/alpine/mailview.c
@@ -2382,7 +2382,7 @@ scrolltool(SCROLL_S *sparms)
UCS ch;
int result, done, cmd, found_on, found_on_index,
first_view, force, scroll_lines, km_size,
- cursor_row, cursor_col, km_popped,
+ cursor_row, cursor_col, km_popped, rv,
nrows, ncols;
char *utf8str;
long jn;
@@ -2712,11 +2712,21 @@ scrolltool(SCROLL_S *sparms)
if(ps_global->prev_screen == mail_view_screen)
mswin_setviewinwindcallback(view_in_new_window);
#endif
- if(cmd == MC_RESIZE
+ rv = -1;
+ if(sparms->aux_function
+ && sparms->aux_condition
+ && ((rv = (sparms->aux_condition)(sparms->aux_value)) == 0))
+ (sparms->aux_function)(sparms->aux_value, sparms->aux_rv_value);
+
+ if(rv == 0){
+ ch = (sparms->decode_aux_rv_value)(sparms->aux_value, sparms->aux_rv_value);
+ if (ch == NO_OP_COMMAND) ch = read_command(&utf8str);
+ }
+ else if(cmd == MC_RESIZE
|| ps_global->ttyo == NULL
|| (ps_global->ttyo->screen_cols == ncols
&& ps_global->ttyo->screen_rows == nrows))
- ch = (sparms->quell_newmail || read_command_prep()) ? read_command(&utf8str) : NO_OP_COMMAND;
+ ch = (sparms->quell_newmail || read_command_prep()) ? read_command(&utf8str) : NO_OP_COMMAND;
#ifdef MOUSE
#ifndef WIN32
if(sparms->text.handles)
diff --git a/alpine/mailview.h b/alpine/mailview.h
index 9df7aeb6..35d4ac4b 100644
--- a/alpine/mailview.h
+++ b/alpine/mailview.h
@@ -63,6 +63,11 @@ typedef struct scrolltool_s {
HelpType text; /* help text */
char *title; /* title for help screen */
} help;
+ UCS (*decode_aux_rv_value)(void *, void *); /* transforms a reply to a command */
+ int (*aux_condition)(void *); /* has the condition been met to execute aux_function, 0 = success */
+ void (*aux_function)(void *, void *); /* auxiliary function to help us decide what to do */
+ void *aux_value; /* argument of aux_function */
+ void *aux_rv_value; /* the return value of aux_function in (void *) */
struct {
int (*click)(struct scrolltool_s *);
int (*clickclick)(struct scrolltool_s *);
diff --git a/alpine/xoauth2.h b/alpine/xoauth2.h
index c9c69974..8a3fc3f7 100644
--- a/alpine/xoauth2.h
+++ b/alpine/xoauth2.h
@@ -26,7 +26,7 @@ typedef struct xoauth_default_s {
#define GMAIL_SECRET "vwnqVJQrJZpR6JilCfAN5nY7"
#define OUTLOOK_NAME "Outlook"
-#define OUTLOOK_ID "c8df0dbf-4750-4bb9-98e9-562b10caa26a"
-#define OUTLOOK_SECRET "ijrmPVDYP4yxbNL3442;!!_"
+#define OUTLOOK_ID "f21dcaf2-8020-469b-8135-343bfc35d046"
+#define OUTLOOK_SECRET "lIE42T4kZ2ZrN-2-AVNYSZ~8i_Co2WG4m."
#endif /* ALPINE_XOAUTH2_INCLUDED */
diff --git a/alpine/xoauth2conf.c b/alpine/xoauth2conf.c
index 97900d25..4a69eb9c 100644
--- a/alpine/xoauth2conf.c
+++ b/alpine/xoauth2conf.c
@@ -26,9 +26,7 @@ extern OAUTH2_S alpine_oauth2_list[];
XOAUTH2_INFO_S xoauth_default[] = {
{ GMAIL_NAME, GMAIL_ID, GMAIL_SECRET},
-#if 0
{ OUTLOOK_NAME, OUTLOOK_ID, OUTLOOK_SECRET},
-#endif
{ NULL, NULL, NULL}
};
@@ -202,9 +200,7 @@ void
alpine_xoauth2_configuration(struct pine *ps, int edit_exceptions)
{
struct variable gmail_client_id_var, gmail_client_secret_var;
-#if 0
struct variable outlook_client_id_var, outlook_client_secret_var;
-#endif
struct variable *varlist[2*NXSERVERS + 1];
char tmp[MAXPATH+1], *pval, **lval;
char *id, *secret;
@@ -245,10 +241,8 @@ alpine_xoauth2_configuration(struct pine *ps, int edit_exceptions)
varlist[0] = &gmail_client_id_var;
varlist[1] = &gmail_client_secret_var;
-#if 0
varlist[2] = &outlook_client_id_var;
varlist[3] = &outlook_client_secret_var;
-#endif
varlist[2*NXSERVERS] = NULL;
for(i = 0; i < 2*NXSERVERS; i++)