From: Ken Hornstein Date: Sat, 20 Aug 2016 05:18:13 +0000 (-0400) Subject: Retrieve appropriate profile entries and pass them to post(8). X-Git-Url: https://diplodocus.org/git/nmh/commitdiff_plain/63fc8244f0ddecdbdacc21ab797acd2f466a2823?ds=sidebyside;hp=-c Retrieve appropriate profile entries and pass them to post(8). Not quite working yet. --- 63fc8244f0ddecdbdacc21ab797acd2f466a2823 diff --git a/Makefile.am b/Makefile.am index 9b1d2650..dbcd7c32 100644 --- a/Makefile.am +++ b/Makefile.am @@ -325,11 +325,11 @@ uip_burst_LDADD = $(LDADD) $(ICONVLIB) $(POSTLINK) uip_comp_SOURCES = uip/comp.c uip/whatnowproc.c uip/whatnowsbr.c uip/sendsbr.c \ uip/annosbr.c uip/distsbr.c -uip_comp_LDADD = $(LDADD) $(READLINELIB) $(TERMLIB) $(ICONVLIB) $(CURLLIB) $(POSTLINK) +uip_comp_LDADD = $(LDADD) $(READLINELIB) $(TERMLIB) $(ICONVLIB) $(POSTLINK) uip_dist_SOURCES = uip/dist.c uip/whatnowproc.c uip/whatnowsbr.c uip/sendsbr.c \ uip/annosbr.c uip/distsbr.c uip/forwsbr.c -uip_dist_LDADD = $(LDADD) $(READLINELIB) $(TERMLIB) $(ICONVLIB) $(CURLLIB) $(POSTLINK) +uip_dist_LDADD = $(LDADD) $(READLINELIB) $(TERMLIB) $(ICONVLIB) $(POSTLINK) uip_flist_SOURCES = uip/flist.c uip_flist_LDADD = $(LDADD) $(POSTLINK) @@ -339,7 +339,7 @@ uip_folder_LDADD = $(LDADD) $(POSTLINK) uip_forw_SOURCES = uip/forw.c uip/whatnowproc.c uip/whatnowsbr.c uip/sendsbr.c \ uip/annosbr.c uip/distsbr.c uip/forwsbr.c -uip_forw_LDADD = $(LDADD) $(READLINELIB) $(TERMLIB) $(ICONVLIB) $(CURLLIB) $(POSTLINK) +uip_forw_LDADD = $(LDADD) $(READLINELIB) $(TERMLIB) $(ICONVLIB) $(POSTLINK) uip_inc_SOURCES = uip/inc.c uip/scansbr.c uip/dropsbr.c uip/popsbr.c uip_inc_LDADD = $(LDADD) $(TERMLIB) $(ICONVLIB) $(SASLLIB) $(CURLLIB) $(POSTLINK) @@ -408,7 +408,7 @@ uip_refile_LDADD = $(LDADD) $(POSTLINK) uip_repl_SOURCES = uip/repl.c uip/replsbr.c uip/whatnowproc.c uip/whatnowsbr.c \ uip/sendsbr.c uip/annosbr.c uip/distsbr.c -uip_repl_LDADD = $(LDADD) $(READLINELIB) $(TERMLIB) $(ICONVLIB) $(CURLLIB) $(POSTLINK) +uip_repl_LDADD = $(LDADD) $(READLINELIB) $(TERMLIB) $(ICONVLIB) $(POSTLINK) uip_rmf_SOURCES = uip/rmf.c uip_rmf_LDADD = $(LDADD) $(POSTLINK) @@ -421,7 +421,7 @@ uip_scan_LDADD = $(LDADD) $(TERMLIB) $(ICONVLIB) $(POSTLINK) uip_send_SOURCES = uip/send.c uip/sendsbr.c uip/annosbr.c \ uip/distsbr.c -uip_send_LDADD = $(LDADD) $(TERMLIB) $(CURLLIB) $(ICONVLIB) $(POSTLINK) +uip_send_LDADD = $(LDADD) $(TERMLIB) $(ICONVLIB) $(POSTLINK) uip_show_SOURCES = uip/show.c uip/mhlsbr.c uip_show_LDADD = $(LDADD) $(TERMLIB) $(ICONVLIB) $(POSTLINK) @@ -431,7 +431,7 @@ uip_sortm_LDADD = $(LDADD) $(POSTLINK) uip_whatnow_SOURCES = uip/whatnow.c uip/whatnowsbr.c uip/sendsbr.c \ uip/annosbr.c uip/distsbr.c -uip_whatnow_LDADD = $(LDADD) $(READLINELIB) $(TERMLIB) $(CURLLIB) $(ICONVLIB) \ +uip_whatnow_LDADD = $(LDADD) $(READLINELIB) $(TERMLIB) $(ICONVLIB) \ $(POSTLINK) uip_whom_SOURCES = uip/whom.c uip/distsbr.c @@ -463,7 +463,8 @@ uip_mkstemp_SOURCES = uip/mkstemp.c uip_mkstemp_LDADD = $(LDADD) $(POSTLINK) uip_post_SOURCES = uip/post.c uip/aliasbr.c -uip_post_LDADD = mts/libmts.a $(LDADD) $(SASLLIB) $(TLSLIB) $(POSTLINK) +uip_post_LDADD = mts/libmts.a $(LDADD) $(SASLLIB) $(CURLLIB) $(TLSLIB) \ + $(POSTLINK) uip_rcvdist_SOURCES = uip/rcvdist.c uip/distsbr.c uip_rcvdist_LDADD = $(LDADD) $(TERMLIB) $(ICONVLIB) $(POSTLINK) @@ -482,7 +483,7 @@ uip_slocal_LDADD = $(LDADD) $(NDBM_LIBS) $(POSTLINK) uip_viamail_SOURCES = uip/viamail.c uip/mhmisc.c uip/sendsbr.c \ uip/annosbr.c uip/distsbr.c -uip_viamail_LDADD = $(LDADD) $(TERMLIB) $(CURLLIB) $(ICONVLIB) $(POSTLINK) +uip_viamail_LDADD = $(LDADD) $(TERMLIB) $(ICONVLIB) $(POSTLINK) ## ## Other program definitions @@ -627,7 +628,7 @@ sbr_libmh_a_SOURCES = sbr/addrsbr.c sbr/ambigsw.c sbr/atooi.c sbr/arglist.c \ sbr/trimcpy.c sbr/unquote.c \ sbr/uprf.c sbr/vfgets.c \ sbr/mf.c sbr/utils.c sbr/ctype-checked.c \ - sbr/m_mktemp.c sbr/vector.c sbr/oauth.c \ + sbr/m_mktemp.c sbr/vector.c sbr/oauth.c sbr/oauth_prof.c \ config/config.c config/version.c \ thirdparty/jsmn/jsmn.c diff --git a/h/oauth.h b/h/oauth.h index 0abaaa34..d1c9c220 100644 --- a/h/oauth.h +++ b/h/oauth.h @@ -75,6 +75,32 @@ typedef struct mh_oauth_ctx mh_oauth_ctx; typedef struct mh_oauth_cred mh_oauth_cred; +typedef struct mh_oauth_service_info mh_oauth_service_info; + +struct mh_oauth_service_info { + /* Name of service, so we can search static internal services array + * and for determining default credential file name. */ + char *name; + + /* Human-readable name of the service; in mh_oauth_ctx::svc this is not + * another buffer to free, but a pointer to either static SERVICE data + * (below) or to the name field. */ + char *display_name; + + /* [1] 2.2 Client Identifier, 2.3.1 Client Password */ + char *client_id; + /* [1] 2.3.1 Client Password */ + char *client_secret; + /* [1] 3.1 Authorization Endpoint */ + char *auth_endpoint; + /* [1] 3.1.2 Redirection Endpoint */ + char *redirect_uri; + /* [1] 3.2 Token Endpoint */ + char *token_endpoint; + /* [1] 3.3 Access Token Scope */ + char *scope; +}; + /* * Do the complete dance for XOAUTH2 as used by POP3 and SMTP. * @@ -223,3 +249,14 @@ mh_oauth_cred_load(FILE *fp, mh_oauth_ctx *ctx, const char *user); const char * mh_oauth_sasl_client_response(size_t *res_len, const char *user, const mh_oauth_cred *cred); + +/* + * Retrieve the various entries for the OAuth mechanism + */ + +boolean +mh_oauth_get_service_info(const char *svc_name, mh_oauth_service_info *svcinfo, + char *errbuf, size_t errbuflen); + +char * +mh_oauth_node_name_for_svc(const char *entry, const char *svc_name); diff --git a/mts/smtp/smtp.c b/mts/smtp/smtp.c index 8a78dea5..75e59f6f 100644 --- a/mts/smtp/smtp.c +++ b/mts/smtp/smtp.c @@ -11,6 +11,7 @@ #include #include #include +#include #ifdef CYRUS_SASL #include @@ -174,7 +175,7 @@ static int sm_fputs(char *); static int sm_fputc(int); static void sm_fflush(void); static int sm_fgets(char *, int, FILE *); -static int sm_auth_xoauth2(const char *); +static int sm_auth_xoauth2(const char *, const char *, int); #ifdef CYRUS_SASL /* @@ -187,12 +188,12 @@ static int sm_auth_sasl(char *, int, char *, char *); int sm_init (char *client, char *server, char *port, int watch, int verbose, int debug, int sasl, int saslssf, char *saslmech, char *user, - const char *xoauth_client_res, int tls) + const char *oauth_svc, int tls) { if (sm_mts == MTS_SMTP) return smtp_init (client, server, port, watch, verbose, debug, sasl, saslssf, saslmech, user, - xoauth_client_res, tls); + oauth_svc, tls); else return sendmail_init (client, server, watch, verbose, debug, sasl, saslssf, saslmech, user); @@ -202,7 +203,7 @@ static int smtp_init (char *client, char *server, char *port, int watch, int verbose, int debug, int sasl, int saslssf, char *saslmech, char *user, - const char *xoauth_client_res, int tls) + const char *oauth_svc, int tls) { int result, sd1, sd2; #ifndef CYRUS_SASL @@ -380,7 +381,7 @@ smtp_init (char *client, char *server, char *port, int watch, int verbose, /* Don't call sm_auth_sasl() for XAUTH2 with -sasl. Instead, call sm_auth_xoauth2() below. */ - if (xoauth_client_res == NULL && + if (oauth_svc == NULL && sm_auth_sasl(user, saslssf, saslmech ? saslmech : server_mechs, server) != RP_OK) { sm_end(NOTOK); @@ -389,14 +390,14 @@ smtp_init (char *client, char *server, char *port, int watch, int verbose, } #endif /* CYRUS_SASL */ - if (xoauth_client_res != NULL) { + if (oauth_svc != NULL) { char *server_mechs; if ((server_mechs = EHLOset("AUTH")) == NULL || stringdex("XOAUTH2", server_mechs) == -1) { sm_end(NOTOK); return sm_ierror("SMTP server does not support SASL XOAUTH2"); } - if (sm_auth_xoauth2(xoauth_client_res) != RP_OK) { + if (sm_auth_xoauth2(user, oauth_svc, debug) != RP_OK) { sm_end(NOTOK); return NOTOK; } @@ -1154,9 +1155,18 @@ sm_get_pass(sasl_conn_t *conn, void *context, int id, /* https://developers.google.com/gmail/xoauth2_protocol */ static int -sm_auth_xoauth2(const char *client_res) +sm_auth_xoauth2(const char *user, const char *oauth_svc, int snoop) { - int status = smtalk(SM_AUTH, "AUTH XOAUTH2 %s", client_res); + const char *xoauth_client_res; + int status; + + xoauth_client_res = mh_oauth_do_xoauth(user, oauth_svc, + snoop ? stderr : NULL); + + if (xoauth_client_res == NULL) + return sm_ierror("Internal error: oauth_do_xoauth() returned NULL"); + + status = smtalk(SM_AUTH, "AUTH XOAUTH2 %s", xoauth_client_res); if (status == 235) { /* It worked! */ return RP_OK; diff --git a/sbr/oauth.c b/sbr/oauth.c index b3e47a93..e86aefe4 100644 --- a/sbr/oauth.c +++ b/sbr/oauth.c @@ -54,46 +54,6 @@ */ #define URL_MAX 8192 -struct service_info { - /* Name of service, so we can search static SERVICES (below) and for - * determining default credential file name. */ - char *name; - - /* Human-readable name of the service; in mh_oauth_ctx::svc this is not - * another buffer to free, but a pointer to either static SERVICE data - * (below) or to the name field. */ - char *display_name; - - /* [1] 2.2 Client Identifier, 2.3.1 Client Password */ - char *client_id; - /* [1] 2.3.1 Client Password */ - char *client_secret; - /* [1] 3.1 Authorization Endpoint */ - char *auth_endpoint; - /* [1] 3.1.2 Redirection Endpoint */ - char *redirect_uri; - /* [1] 3.2 Token Endpoint */ - char *token_endpoint; - /* [1] 3.3 Access Token Scope */ - char *scope; -}; - -static const struct service_info SERVICES[] = { - /* https://developers.google.com/accounts/docs/OAuth2InstalledApp */ - { - /* name */ "gmail", - /* display_name */ "Gmail", - - /* client_id */ "91584523849-8lv9kgp1rvp8ahta6fa4b125tn2polcg.apps.googleusercontent.com", - /* client_secret */ "Ua8sX34xyv7hVrKM-U70dKI6", - - /* auth_endpoint */ "https://accounts.google.com/o/oauth2/auth", - /* redirect_uri */ "urn:ietf:wg:oauth:2.0:oob", - /* token_endpoint */ "https://accounts.google.com/o/oauth2/token", - /* scope */ "https://mail.google.com/" - } -}; - struct mh_oauth_cred { mh_oauth_ctx *ctx; @@ -114,7 +74,7 @@ struct mh_oauth_cred { }; struct mh_oauth_ctx { - struct service_info svc; + struct mh_oauth_service_info svc; CURL *curl; FILE *log; @@ -283,78 +243,6 @@ set_err_http(mh_oauth_ctx *ctx, const struct curl_ctx *curl_ctx) free(error); } -/* Copy service info so we don't have to free it only sometimes. */ -static void -copy_svc(struct service_info *to, const struct service_info *from) -{ - to->display_name = from->display_name; -#define copy(_field_) to->_field_ = getcpy(from->_field_) - copy(name); - copy(scope); - copy(client_id); - copy(client_secret); - copy(auth_endpoint); - copy(token_endpoint); - copy(redirect_uri); -#undef copy -} - -/* Return profile component node name for a service parameter. */ -static char * -node_name_for_svc(const char *base_name, const char *svc) -{ - char *result = mh_xmalloc(sizeof "oauth-" - 1 - + strlen(svc) - + 1 /* '-' */ - + strlen(base_name) - + 1 /* '\0' */); - sprintf(result, "oauth-%s-%s", svc, base_name); - /* TODO: s/_/-/g ? */ - return result; -} - -/* Update one service_info field if overridden in profile. */ -static void -update_svc_field(char **field, const char *base_name, const char *svc) -{ - char *name = node_name_for_svc(base_name, svc); - const char *value = context_find(name); - if (value != NULL) { - free(*field); - *field = getcpy(value); - } - free(name); -} - -/* Update all service_info fields that are overridden in profile. */ -static boolean -update_svc(struct service_info *svc, const char *svc_name, mh_oauth_ctx *ctx) -{ -#define update(name) \ - update_svc_field(&svc->name, #name, svc_name); \ - if (svc->name == NULL) { \ - set_err_details(ctx, MH_OAUTH_BAD_PROFILE, #name " is missing"); \ - return FALSE; \ - } - update(scope); - update(client_id); - update(client_secret); - update(auth_endpoint); - update(token_endpoint); - update(redirect_uri); -#undef update - - if (svc->name == NULL) { - svc->name = getcpy(svc_name); - } - - if (svc->display_name == NULL) { - svc->display_name = svc->name; - } - - return TRUE; -} - static char * make_user_agent() { @@ -373,26 +261,15 @@ boolean mh_oauth_new(mh_oauth_ctx **result, const char *svc_name) { mh_oauth_ctx *ctx = *result = mh_xmalloc(sizeof *ctx); - size_t i; ctx->curl = NULL; ctx->log = NULL; ctx->cred_fn = ctx->sasl_client_res = ctx->err_formatted = NULL; - ctx->svc.name = ctx->svc.display_name = NULL; - ctx->svc.scope = ctx->svc.client_id = NULL; - ctx->svc.client_secret = ctx->svc.auth_endpoint = NULL; - ctx->svc.token_endpoint = ctx->svc.redirect_uri = NULL; - - for (i = 0; i < sizeof SERVICES / sizeof SERVICES[0]; i++) { - if (strcmp(SERVICES[i].name, svc_name) == 0) { - copy_svc(&ctx->svc, &SERVICES[i]); - break; - } - } - - if (!update_svc(&ctx->svc, svc_name, ctx)) { + if (!mh_oauth_get_service_info(svc_name, &ctx->svc, ctx->err_buf, + sizeof(ctx->err_buf))) { + set_err_details(ctx, MH_OAUTH_BAD_PROFILE, ctx->err_buf); return FALSE; } @@ -698,7 +575,7 @@ mh_oauth_cred_fn(mh_oauth_ctx *ctx) char *result, *result_if_allocated; const char *svc = ctx->svc.name; - char *component = node_name_for_svc("credential-file", svc); + char *component = mh_oauth_node_name_for_svc("credential-file", svc); result = context_find(component); free(component); diff --git a/sbr/oauth_prof.c b/sbr/oauth_prof.c new file mode 100644 index 00000000..4f9e2a2f --- /dev/null +++ b/sbr/oauth_prof.c @@ -0,0 +1,137 @@ +/* + * This code is Copyright (c) 2014, by the authors of nmh. See the + * COPYRIGHT file in the root directory of the nmh distribution for + * complete copyright information. + */ + +#include + +#ifdef OAUTH_SUPPORT + +#include + +#include +#include +#include +#include +#include +#include + +#include +#include + +static const struct mh_oauth_service_info SERVICES[] = { + /* https://developers.google.com/accounts/docs/OAuth2InstalledApp */ + { + /* name */ "gmail", + /* display_name */ "Gmail", + + /* client_id */ "91584523849-8lv9kgp1rvp8ahta6fa4b125tn2polcg.apps.googleusercontent.com", + /* client_secret */ "Ua8sX34xyv7hVrKM-U70dKI6", + + /* auth_endpoint */ "https://accounts.google.com/o/oauth2/auth", + /* redirect_uri */ "urn:ietf:wg:oauth:2.0:oob", + /* token_endpoint */ "https://accounts.google.com/o/oauth2/token", + /* scope */ "https://mail.google.com/" + } +}; + +/* Copy service info so we don't have to free it only sometimes. */ +static void +copy_svc(mh_oauth_service_info *to, const mh_oauth_service_info *from) +{ + to->display_name = from->display_name; +#define copy(_field_) to->_field_ = getcpy(from->_field_) + copy(name); + copy(scope); + copy(client_id); + copy(client_secret); + copy(auth_endpoint); + copy(token_endpoint); + copy(redirect_uri); +#undef copy +} + +/* Return profile component node name for a service parameter. */ +char * +mh_oauth_node_name_for_svc(const char *base_name, const char *svc) +{ + char *result = mh_xmalloc(sizeof "oauth-" - 1 + + strlen(svc) + + 1 /* '-' */ + + strlen(base_name) + + 1 /* '\0' */); + sprintf(result, "oauth-%s-%s", svc, base_name); + /* TODO: s/_/-/g ? */ + return result; +} + +/* Update one service_info field if overridden in profile. */ +static void +update_svc_field(char **field, const char *base_name, const char *svc) +{ + char *name = mh_oauth_node_name_for_svc(base_name, svc); + const char *value = context_find(name); + if (value != NULL) { + free(*field); + *field = getcpy(value); + } + free(name); +} + +/* Update all service_info fields that are overridden in profile. */ +static boolean +update_svc(mh_oauth_service_info *svc, const char *svc_name, char *errbuf, + size_t errbuflen) +{ +#define update(name) \ + update_svc_field(&svc->name, #name, svc_name); \ + if (svc->name == NULL) { \ + snprintf(errbuf, errbuflen, "%s", #name " is missing"); \ + errbuf[errbuflen - 1] = '\0'; \ + return FALSE; \ + } + update(scope); + update(client_id); + update(client_secret); + update(auth_endpoint); + update(token_endpoint); + update(redirect_uri); +#undef update + + if (svc->name == NULL) { + svc->name = getcpy(svc_name); + } + + if (svc->display_name == NULL) { + svc->display_name = svc->name; + } + + return TRUE; +} + +boolean +mh_oauth_get_service_info(const char *svc_name, mh_oauth_service_info *svcinfo, + char *errbuf, size_t errbuflen) +{ + int i; + + svcinfo->name = svcinfo->display_name = NULL; + svcinfo->scope = svcinfo->client_id = NULL; + svcinfo->client_secret = svcinfo->auth_endpoint = NULL; + svcinfo->token_endpoint = svcinfo->redirect_uri = NULL; + + for (i = 0; i < (int) (sizeof SERVICES / sizeof SERVICES[0]); i++) { + if (strcmp(SERVICES[i].name, svc_name) == 0) { + copy_svc(svcinfo, &SERVICES[i]); + break; + } + } + + if (!update_svc(svcinfo, svc_name, errbuf, errbuflen)) { + return FALSE; + } + + return TRUE; +} +#endif diff --git a/uip/post.c b/uip/post.c index 0660f17b..43110f36 100644 --- a/uip/post.c +++ b/uip/post.c @@ -40,7 +40,7 @@ #ifndef OAUTH_SUPPORT # define OAUTHminc(a) (a) #else /* OAUTH_SUPPORT */ -# define OAUTHmine(a) 0 +# define OAUTHminc(a) 0 #endif /* OAUTH_SUPPORT */ #define FCCS 10 /* max number of fccs allowed */ @@ -86,7 +86,6 @@ X("nosasl", SASLminc(6), NOSASLSW) \ X("saslmaxssf", SASLminc(10), SASLMXSSFSW) \ X("saslmech", SASLminc(5), SASLMECHSW) \ - X("authservice", SASLminc(0), AUTHSERVICESW) \ X("user", SASLminc(-4), USERSW) \ X("port server submission port name/number", 4, PORTSW) \ X("tls", TLSminc(-3), TLSSW) \ @@ -115,6 +114,25 @@ DEFINE_SWITCH_ARRAY(POST, switches); #undef X +/* + * Mapping between command-line switches and profile entries, communicated + * from 'send'. We use a service name of 'post' internally. + */ + +static struct oauth_profile { + const char *profname; + int switchnum; +} oauthswitches[] = { + { "oauth-post-credential-file", OAUTHCREDFILESW }, + { "oauth-post-client_id", OAUTHCLIDSW }, + { "oauth-post-client_secret", OAUTHCLSECSW }, + { "oauth-post-auth_endpoint", OAUTHAUTHENDSW }, + { "oauth-post-redirect_url", OAUTHREDIRSW }, + { "oauth-post-token_endpoint", OAUTHTOKENDSW }, + { "oauth-post-scope", OAUTHSCOPESW }, + { NULL, 0 } +}; + struct headers { char *value; unsigned int flags; @@ -271,14 +289,14 @@ static void anno (void); static int annoaux (struct mailname *); static void insert_fcc (struct headers *, char *); static void make_bcc_file (int); -static void verify_all_addresses (int, char *, const char *); +static void verify_all_addresses (int, char *, int); static void chkadr (void); static void sigon (void); static void sigoff (void); static void p_refile (char *); static void fcc (char *, char *); static void die (char *, char *, ...); -static void post (char *, int, int, char *, const char *); +static void post (char *, int, int, char *, int); static void do_text (char *file, int fd); static void do_an_address (struct mailname *, int); static void do_addresses (int, int); @@ -288,12 +306,11 @@ static int find_prefix (void); int main (int argc, char **argv) { - int state, compnum, dashstuff = 0; + int state, compnum, dashstuff = 0, swnum, oauth_flag = 0; char *cp, *msg = NULL, **argp, **arguments, *envelope; char buf[BUFSIZ], name[NAMESZ]; FILE *in, *out; m_getfld_state_t gstate = 0; - char *xoauth_client_res = NULL; if (nmh_init(argv[0], 0 /* use context_foil() */)) { return 1; } @@ -303,7 +320,7 @@ main (int argc, char **argv) while ((cp = *argp++)) { if (*cp == '-') { - switch (smatch (++cp, switches)) { + switch ((swnum = smatch (++cp, switches))) { case AMBIGSW: ambigsw (cp, switches); done (1); @@ -455,14 +472,34 @@ main (int argc, char **argv) adios (NULL, "missing argument to %s", argp[-2]); continue; - case AUTHSERVICESW: -#ifdef OAUTH_SUPPORT - if (!(xoauth_client_res = *argp++) || *xoauth_client_res == '-') + case OAUTHCREDFILESW: + case OAUTHCLIDSW: + case OAUTHCLSECSW: + case OAUTHAUTHENDSW: + case OAUTHREDIRSW: + case OAUTHTOKENDSW: + case OAUTHSCOPESW: + { + int i; + + if (!(cp = *argp++) || *cp == '-') adios (NULL, "missing argument to %s", argp[-2]); -#else - adios (NULL, "not built with OAuth support"); -#endif + + for (i = 0; oauthswitches[i].profname != NULL; i++) { + if (oauthswitches[i].switchnum == swnum) { + add_profile_entry(oauthswitches[i].profname, cp); + break; + } + } + + if (oauthswitches[i].profname == NULL) + adios (NULL, "internal error: cannot map switch %s " + "to profile entry", argp[-2]); + + oauth_flag++; + continue; + } case USERSW: if (!(user = *argp++) || *user == '-') @@ -651,7 +688,7 @@ main (int argc, char **argv) /* If we are doing a "whom" check */ if (whomsw) { /* This won't work with MTS_SENDMAIL_PIPE. */ - verify_all_addresses (1, envelope, xoauth_client_res); + verify_all_addresses (1, envelope, oauth_flag); done (0); } @@ -663,14 +700,14 @@ main (int argc, char **argv) verify_all_addresses with MTS_SENDMAIL_PIPE, but that might require running sendmail as root. Note that spost didn't verify addresses. */ - verify_all_addresses (verbose, envelope, xoauth_client_res); + verify_all_addresses (verbose, envelope, oauth_flag); } - post (tmpfil, 0, verbose, envelope, xoauth_client_res); + post (tmpfil, 0, verbose, envelope, oauth_flag); } - post (bccfil, 1, verbose, envelope, xoauth_client_res); + post (bccfil, 1, verbose, envelope, oauth_flag); (void) m_unlink (bccfil); } else { - post (tmpfil, 0, isatty (1), envelope, xoauth_client_res); + post (tmpfil, 0, isatty (1), envelope, oauth_flag); } p_refile (tmpfil); @@ -1517,8 +1554,7 @@ do_addresses (int bccque, int talk) */ static void -post (char *file, int bccque, int talk, char *envelope, - const char *xoauth_client_res) +post (char *file, int bccque, int talk, char *envelope, int oauth_flag) { int fd; int retval, i; @@ -1568,7 +1604,8 @@ post (char *file, int bccque, int talk, char *envelope, } else { if (rp_isbad (retval = sm_init (clientsw, serversw, port, watch, verbose, snoop, sasl, saslssf, - saslmech, user, xoauth_client_res, tls)) + saslmech, user, + oauth_flag ? "post" : NULL, tls)) || rp_isbad (retval = sm_winit (envelope))) die (NULL, "problem initializing server; %s", rp_string (retval)); @@ -1598,7 +1635,7 @@ post (char *file, int bccque, int talk, char *envelope, /* Address Verification */ static void -verify_all_addresses (int talk, char *envelope, const char *xoauth_client_res) +verify_all_addresses (int talk, char *envelope, int oauth_flag) { int retval; struct mailname *lp; @@ -1608,7 +1645,8 @@ verify_all_addresses (int talk, char *envelope, const char *xoauth_client_res) if (!whomsw || checksw) if (rp_isbad (retval = sm_init (clientsw, serversw, port, watch, verbose, snoop, sasl, saslssf, - saslmech, user, xoauth_client_res, tls)) + saslmech, user, + oauth_flag ? "post" : NULL, tls)) || rp_isbad (retval = sm_winit (envelope))) die (NULL, "problem initializing server; %s", rp_string (retval)); diff --git a/uip/sendsbr.c b/uip/sendsbr.c index 89894af5..62229340 100644 --- a/uip/sendsbr.c +++ b/uip/sendsbr.c @@ -26,7 +26,7 @@ #ifdef OAUTH_SUPPORT #include -static int setup_oauth_params(char *[], int *, int, const char **); +static int setup_oauth_params(char *[], int *, const char **); #endif /* OAUTH_SUPPORT */ int debugsw = 0; /* global */ @@ -749,17 +749,7 @@ handle_sendfrom(char **vec, int *vecp, char *draft) { for (vp = vec; *vp; ++vp) { if (strcmp(*vp, "xoauth2") == 0) { #ifdef OAUTH_SUPPORT - int snoop = 0; - - /* -snoop will be in vec if it was enabled. */ - for (vp = vec; vp && *vp; ++vp) { - if (strcmp(*vp, "-snoop") == 0) { - snoop = 1; - break; - } - } - - if (setup_oauth_params(vec, vecp, snoop, &message) != OK) { + if (setup_oauth_params(vec, vecp, &message) != OK) { adios(NULL, message); } break; @@ -775,12 +765,13 @@ handle_sendfrom(char **vec, int *vecp, char *draft) { #ifdef OAUTH_SUPPORT /* - * For XOAUTH2, append access token, from mh_oauth_do_xoauth(), for the user to vec. + * For XOAUTH2, append profile entries so post can do the heavy lifting */ -static -int -setup_oauth_params(char *vec[], int *vecp, int snoop, const char **message) { +static int +setup_oauth_params(char *vec[], int *vecp, const char **message) { const char *saslmech = NULL, *user = NULL, *auth_svc = NULL; + mh_oauth_service_info svc; + char errbuf[256]; int i; /* Make sure we have all the information we need. */ @@ -807,6 +798,7 @@ setup_oauth_params(char *vec[], int *vecp, int snoop, const char **message) { return NOTOK; } + vec[(*vecp)++] = getcpy("-authservice"); if (saslmech && ! strcasecmp(saslmech, "xoauth2")) { vec[(*vecp)++] = mh_oauth_do_xoauth(user, auth_svc, snoop ? stderr : NULL);