Not quite working yet.
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)
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)
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)
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)
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
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)
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
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
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.
*
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);
#include <h/mts.h>
#include <h/signals.h>
#include <h/utils.h>
+#include <h/oauth.h>
#ifdef CYRUS_SASL
#include <sasl/sasl.h>
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
/*
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);
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
/* 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);
}
#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;
}
/* 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;
*/
#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;
};
struct mh_oauth_ctx {
- struct service_info svc;
+ struct mh_oauth_service_info svc;
CURL *curl;
FILE *log;
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()
{
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;
}
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);
--- /dev/null
+/*
+ * 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 <h/mh.h>
+
+#ifdef OAUTH_SUPPORT
+
+#include <sys/stat.h>
+
+#include <stdarg.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <strings.h>
+#include <unistd.h>
+
+#include <h/oauth.h>
+#include <h/utils.h>
+
+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
#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 */
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) \
#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;
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);
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; }
while ((cp = *argp++)) {
if (*cp == '-') {
- switch (smatch (++cp, switches)) {
+ switch ((swnum = smatch (++cp, switches))) {
case AMBIGSW:
ambigsw (cp, switches);
done (1);
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 == '-')
/* 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);
}
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);
*/
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;
} 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));
/* 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;
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));
#ifdef OAUTH_SUPPORT
#include <h/oauth.h>
-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 */
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;
#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. */
return NOTOK;
}
+
vec[(*vecp)++] = getcpy("-authservice");
if (saslmech && ! strcasecmp(saslmech, "xoauth2")) {
vec[(*vecp)++] = mh_oauth_do_xoauth(user, auth_svc, snoop ? stderr : NULL);