test/mhbuild/test-forw test/mhbuild/test-header-encode \
test/mhbuild/test-utf8-body \
test/mhfixmsg/test-mhfixmsg test/mhical/test-mhical \
- test/mhl/test-mhl-flags \
+ test/mhl/test-mhl-flags test/mhl/test-rfc6532 \
test/mhlist/test-mhlist test/mhlist/test-ext-params \
test/mhmail/test-mhmail \
test/mhparam/test-mhparam test/mhpath/test-mhpath \
noinst_HEADERS = h/addrsbr.h h/aliasbr.h h/crawl_folders.h h/dropsbr.h \
h/fmt_compile.h h/fmt_scan.h h/icalendar.h h/md5.h h/mf.h \
h/mh.h h/mhcachesbr.h h/mhparse.h h/mime.h \
- h/mts.h h/nmh.h h/picksbr.h h/popsbr.h h/prototypes.h \
- h/rcvmail.h h/scansbr.h h/signals.h h/tws.h h/utils.h \
- mts/smtp/smtp.h sbr/ctype-checked.h h/oauth.h \
+ h/mts.h h/nmh.h h/netsec.h h/picksbr.h h/popsbr.h
+ h/prototypes.h h/rcvmail.h h/scansbr.h h/signals.h h/tws.h
+ h/utils.h mts/smtp/smtp.h sbr/ctype-checked.h h/oauth.h \
thirdparty/jsmn/jsmn.h
##
test/post/test-post-common.sh test/send/README \
test/oauth/common.sh \
test/valgrind.supp uip/mhmail \
- SPECS/nmh.spec SPECS/build-nmh-cygwin $(man_SRCS)
+ SPECS/nmh.spec SPECS/nmh.cygport $(man_SRCS)
##
## These are all of the definitions for each of the programs listed above.
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_inc_LDADD = $(LDADD) $(TERMLIB) $(ICONVLIB) $(SASLLIB) $(CURLLIB) \
+ $(TLSLIB) $(POSTLINK)
uip_install_mh_SOURCES = uip/install-mh.c
uip_install_mh_LDADD = $(LDADD) $(POSTLINK)
uip_mhstore_LDADD = $(LDADD) $(TERMLIB) $(ICONVLIB) $(POSTLINK)
uip_msgchk_SOURCES = uip/msgchk.c uip/popsbr.c
- uip_msgchk_LDADD = $(LDADD) $(SASLLIB) $(CURLLIB) $(POSTLINK)
+ uip_msgchk_LDADD = $(LDADD) $(SASLLIB) $(CURLLIB) $(TLSLIB) $(POSTLINK)
uip_new_SOURCES = uip/new.c
uip_new_LDADD = $(LDADD) $(POSTLINK)
sbr/m_draft.c sbr/m_getfld.c sbr/m_gmprot.c \
sbr/m_maildir.c sbr/m_name.c sbr/m_popen.c sbr/m_rand.c \
sbr/makedir.c sbr/md5.c sbr/message_id.c \
- sbr/mime_type.c sbr/mts.c sbr/norm_charmap.c sbr/path.c \
+ sbr/mime_type.c sbr/mts.c sbr/netsec.c \
+ sbr/norm_charmap.c sbr/path.c \
sbr/peekc.c sbr/pidwait.c sbr/pidstatus.c \
sbr/print_help.c sbr/print_sw.c sbr/print_version.c \
sbr/push.c sbr/putenv.c sbr/refile.c sbr/remdir.c \
config/sbr_libmh_a-config.$(OBJEXT) sbr/sbr_libmh_a-mts.$(OBJEXT): Makefile
-sbr_libmh_a_CPPFLAGS = -I./sbr \
+sbr_libmh_a_CPPFLAGS = ${AM_CPPFLAGS} -I./sbr \
-DNMHBINDIR='"$(bindir)"' \
-DNMHLIBEXECDIR='"$(nmhlibexecdir)"' \
-DNMHETCDIR='"@nmhetcdirinst@$(nmhetcdir)"' \
static boolean make_query_url(char *, size_t, CURL *, const char *, ...);
static boolean post(struct curl_ctx *, const char *, const char *);
- char *
- mh_oauth_do_xoauth(const char *user, const char *svc, FILE *log)
+ int
+ mh_oauth_do_xoauth(const char *user, const char *svc, unsigned char **oauth_res,
+ size_t *oauth_res_len, FILE *log)
{
mh_oauth_ctx *ctx;
mh_oauth_cred *cred;
char *fn;
int failed_to_lock = 0;
FILE *fp;
- size_t client_res_len;
char *client_res;
- char *client_res_b64;
if (!mh_oauth_new (&ctx, svc)) adios(NULL, mh_oauth_get_err_string(ctx));
free(fn);
/* XXX writeBase64raw modifies the source buffer! make a copy */
- client_res = getcpy(mh_oauth_sasl_client_response(&client_res_len, user,
+ client_res = getcpy(mh_oauth_sasl_client_response(oauth_res_len, user,
cred));
mh_oauth_cred_free(cred);
mh_oauth_free(ctx);
- client_res_b64 = mh_xmalloc(((((client_res_len) + 2) / 3 ) * 4) + 1);
- if (writeBase64raw((unsigned char *)client_res, client_res_len,
- (unsigned char *)client_res_b64) != OK) {
- adios(NULL, "base64 encoding of XOAUTH2 client response failed");
- }
- free(client_res);
- return client_res_b64;
+ *oauth_res = (unsigned char *) client_res;
+
+ return OK;
}
static boolean
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_callback);
curl_easy_setopt(curl, CURLOPT_WRITEDATA, ctx);
+ if (strncmp(url, "http://127.0.0.1:", 17) == 0) {
+ /* Hack: on Cygwin, curl doesn't fail to connect with ECONNREFUSED.
+ Instead, it waits to timeout. So set a really short timeout, but
+ just on localhost (for convenience of the user, and the test
+ suite). */
+ curl_easy_setopt(curl, CURLOPT_CONNECTTIMEOUT, 2L);
+ }
+
status = curl_easy_perform(curl);
/* first check for error from callback */
if (ctx->too_big) {
# define SASLminc(a) 0
#endif
+ #ifndef TLS_SUPPORT
+ # define TLSminc(a) (a)
+ #else
+ # define TLSminc(a) 0
+ #endif
+
#define INC_SWITCHES \
X("audit audit-file", 0, AUDSW) \
X("noaudit", 0, NAUDSW) \
X("width columns", 0, WIDTHSW) \
X("version", 0, VERSIONSW) \
X("help", 0, HELPSW) \
- X("snoop", -5, SNOOPSW) \
+ X("snoop", 0, SNOOPSW) \
X("sasl", SASLminc(5), SASLSW) \
X("nosasl", SASLminc(3), NOSASLSW) \
X("saslmech", SASLminc(5), SASLMECHSW) \
+ X("initialtls", TLSminc(-10), INITTLSSW) \
+ X("notls", TLSminc(-12), NOTLSSW) \
X("authservice", SASLminc(0), AUTHSERVICESW) \
X("proxy command", 0, PROXYSW) \
int chgflag = 1, trnflag = 1;
int noisy = 1, width = -1;
int hghnum = 0, msgnum = 0;
- int sasl = 0;
+ int sasl = 0, tls = 0;
int incerr = 0; /* <0 if inc hits an error which means it should not truncate mailspool */
char *cp, *maildir = NULL, *folder = NULL;
char *format = NULL, *form = NULL;
if (nmh_init(argv[0], 1)) { return 1; }
- mts_init (invo_name);
+ mts_init ();
arguments = getarguments (invo_name, argc, argv, 1);
argp = arguments;
while ((cp = *argp++)) {
if (*cp == '-') {
switch (smatch (++cp, switches)) {
- case AMBIGSW:
+ case AMBIGSW:
ambigsw (cp, switches);
done (1);
- case UNKWNSW:
+ case UNKWNSW:
adios (NULL, "-%s unknown", cp);
- case HELPSW:
+ case HELPSW:
snprintf (buf, sizeof(buf), "%s [+folder] [switches]", invo_name);
print_help (buf, switches, 1);
done (0);
print_version(invo_name);
done (0);
- case AUDSW:
+ case AUDSW:
if (!(cp = *argp++) || *cp == '-')
adios (NULL, "missing argument to %s", argp[-2]);
audfile = getcpy (m_maildir (cp));
continue;
- case NAUDSW:
+ case NAUDSW:
audfile = NULL;
continue;
- case CHGSW:
+ case CHGSW:
chgflag++;
continue;
- case NCHGSW:
+ case NCHGSW:
chgflag = 0;
continue;
* 1 by default (truncating is default)
* 0 if -notruncate is given
*/
- case TRNCSW:
+ case TRNCSW:
trnflag = 2;
continue;
- case NTRNCSW:
+ case NTRNCSW:
trnflag = 0;
continue;
- case FILESW:
+ case FILESW:
if (!(cp = *argp++) || *cp == '-')
adios (NULL, "missing argument to %s", argp[-2]);
from = path (cp, TFILE);
trnflag = 0;
continue;
- case SILSW:
+ case SILSW:
noisy = 0;
continue;
- case NSILSW:
+ case NSILSW:
noisy++;
continue;
- case FORMSW:
+ case FORMSW:
if (!(form = *argp++) || *form == '-')
adios (NULL, "missing argument to %s", argp[-2]);
format = NULL;
continue;
- case FMTSW:
+ case FMTSW:
if (!(format = *argp++) || *format == '-')
adios (NULL, "missing argument to %s", argp[-2]);
form = NULL;
continue;
- case WIDTHSW:
+ case WIDTHSW:
if (!(cp = *argp++) || *cp == '-')
adios (NULL, "missing argument to %s", argp[-2]);
width = atoi (cp);
adios (NULL, "missing argument to %s", argp[-2]);
continue;
+ case INITTLSSW:
+ tls++;
+ continue;
+
+ case NOTLSSW:
+ tls = 0;
+ continue;
+
case AUTHSERVICESW:
#ifdef OAUTH_SUPPORT
if (!(auth_svc = *argp++) || *auth_svc == '-')
* initialize POP connection
*/
if (pop_init (host, port, creds.user, creds.password, proxy, snoop,
- sasl, saslmech, auth_svc) == NOTOK)
+ sasl, saslmech, tls, auth_svc) == NOTOK)
adios (NULL, "%s", response);
/* Check if there are any messages */
switch (incerr = scan (pf, msgnum, 0, nfs, width,
packfile ? 0 : msgnum == mp->hghmsg + 1 && chgflag,
1, NULL, stop - start, noisy, &scanl)) {
- case SCNEOF:
+ case SCNEOF:
printf ("%*d empty\n", DMAXFOLDER, msgnum);
break;
/* fall thru */
case SCNERR:
- case SCNNUM:
+ case SCNNUM:
break;
- case SCNMSG:
+ case SCNMSG:
case SCNENC:
- default:
+ default:
if (aud)
fputs (charstring_buffer (scanl), aud);
if (noisy)
msgnum == hghnum && chgflag, 1, NULL, 0L, noisy,
&scanl)) {
case SCNFAT:
- case SCNEOF:
+ case SCNEOF:
break;
case SCNERR:
advise (NULL, "aborted!"); /* doesn't clean up locks! */
break;
- case SCNNUM:
+ case SCNNUM:
advise (NULL, "BUG in %s, number out of range", invo_name);
break;
- default:
+ default:
advise (NULL, "BUG in %s, scan() botch (%d)", invo_name, incerr);
break;
}
fclose (sf);
sf = NULL;
- }
+ }
if (pf == NULL && (pf = fopen (cp, "r")) == NULL)
adios (cp, "not available");
chmod (cp, m_gmprot ());
switch (incerr = scan (pf, msgnum, 0, nfs, width,
msgnum == mp->hghmsg + 1 && chgflag,
1, NULL, stop - start, noisy, &scanl)) {
- case SCNEOF:
+ case SCNEOF:
printf ("%*d empty\n", DMAXFOLDER, msgnum);
break;
/* fall thru */
case SCNERR:
- case SCNNUM:
+ case SCNNUM:
break;
- case SCNMSG:
+ case SCNMSG:
case SCNENC:
- default:
+ default:
/*
* Run the external program hook on the message.
*/
/* sbeck -- handle suffixes */
CI ci;
CE ce = &ct->c_cefile;
- const char *decoded;
+ unsigned char *decoded;
size_t decoded_len;
unsigned char digest[16];
if (decodeBase64 (buffer, &decoded, &decoded_len, ct->c_type == CT_TEXT,
ct->c_digested ? digest : NULL) == OK) {
size_t i;
- const char *decoded_p = decoded;
+ unsigned char *decoded_p = decoded;
for (i = 0; i < decoded_len; ++i) {
putc (*decoded_p++, ce->ce_fp);
}
+ free ((char *) decoded);
if (ferror (ce->ce_fp)) {
content_error (ce->ce_file, ct, "error writing to");
goto clean_up;
static int
readDigest (CT ct, char *cp)
{
- const char *digest;
+ unsigned char *digest;
size_t len;
if (decodeBase64 (cp, &digest, &len, 0, NULL) == OK) {
const size_t maxlen = sizeof ct->c_digest / sizeof ct->c_digest[0];
- if (strlen (digest) <= maxlen) {
+ if (strlen ((char *) digest) <= maxlen) {
memcpy (ct->c_digest, digest, maxlen);
if (debugsw) {
} else {
if (debugsw) {
fprintf (stderr, "invalid MD5 digest (got %d octets)\n",
- (int) strlen (digest));
+ (int) strlen ((char *) digest));
}
return NOTOK;
X("port name/number", 0, PORTSW) \
X("version", 0, VERSIONSW) \
X("help", 0, HELPSW) \
- X("snoop", -5, SNOOPSW) \
+ X("snoop", 0, SNOOPSW) \
X("sasl", SASLminc(4), SASLSW) \
X("saslmech", SASLminc(5), SASLMECHSW) \
X("authservice", SASLminc(0), AUTHSERVICESW) \
if (nmh_init(argv[0], 1)) { return 1; }
- mts_init (invo_name);
+ mts_init ();
arguments = getarguments (invo_name, argc, argv, 1);
argp = arguments;
/* open the POP connection */
if (pop_init (host, port, creds.user, creds.password, proxy, snoop, sasl,
- saslmech, auth_svc) == NOTOK
+ saslmech, 0, auth_svc) == NOTOK
|| pop_stat (&nmsgs, &nbytes) == NOTOK /* check for messages */
|| pop_quit () == NOTOK) { /* quit POP connection */
advise (NULL, "%s", response);
X("partno", -6, PARTSW) \
X("sasl", SASLminc(4), SASLSW) \
X("nosasl", SASLminc(6), NOSASLSW) \
- X("saslmaxssf", SASLminc(10), SASLMXSSFSW) \
X("saslmech", SASLminc(5), SASLMECHSW) \
X("user", SASLminc(-4), USERSW) \
X("port server submission port name/number", 4, PORTSW) \
static int linepos=0; /* putadr()'s position on the line */
static int nameoutput=0; /* putadr() has output header name */
static int sasl=0; /* Use SASL auth for SMTP */
- static int saslssf=-1; /* Our maximum SSF for SASL */
static char *saslmech=NULL; /* Force use of particular SASL mech */
static char *user=NULL; /* Authenticate as this user */
static char *port="submission"; /* Name of server port for SMTP submission */
if (nmh_init(argv[0], 0 /* use context_foil() */)) { return 1; }
- mts_init (invo_name);
+ mts_init ();
arguments = getarguments (invo_name, argc, argv, 0);
argp = arguments;
sasl = 0;
continue;
- case SASLMXSSFSW:
- if (!(cp = *argp++) || *cp == '-')
- adios (NULL, "missing argument to %s", argp[-2]);
- saslssf = atoi(cp);
- continue;
-
case SASLMECHSW:
if (!(saslmech = *argp++) || *saslmech == '-')
adios (NULL, "missing argument to %s", argp[-2]);
}
} else {
if (rp_isbad (retval = sm_init (clientsw, serversw, port, watch,
- verbose, snoop, sasl, saslssf,
- saslmech, user,
+ verbose, snoop, sasl, saslmech, user,
oauth_flag ? auth_svc : NULL, tls))
|| rp_isbad (retval = sm_winit (envelope)))
die (NULL, "problem initializing server; %s", rp_string (retval));
if (!whomsw || checksw)
if (rp_isbad (retval = sm_init (clientsw, serversw, port, watch,
- verbose, snoop, sasl, saslssf,
- saslmech, user,
+ verbose, snoop, sasl, saslmech, user,
oauth_flag ? auth_svc : NULL, tls))
|| rp_isbad (retval = sm_winit (envelope)))
die (NULL, "problem initializing server; %s", rp_string (retval));
X("client host", -6, CLIESW) \
X("server host", 6, SERVSW) \
X("snoop", -5, SNOOPSW) \
- X("draftfolder +folder", -6, SDRFSW) \
- X("draftmessage msg", -6, SDRMSW) \
- X("nodraftfolder", -3, SNDRFSW) \
+ X("draftfolder +folder", 0, SDRFSW) \
+ X("draftmessage msg", 0, SDRMSW) \
+ X("nodraftfolder", 0, SNDRFSW) \
X("sasl", SASLminc(4), SASLSW) \
X("nosasl", SASLminc(6), NOSASLSW) \
- X("saslmaxssf", SASLminc(10), SASLMXSSFSW) \
X("saslmech", SASLminc(5), SASLMECHSW) \
X("authservice", SASLminc(0), AUTHSERVICESW) \
X("user username", SASLminc(4), USERSW) \
case WIDTHSW:
case CLIESW:
case SERVSW:
- case SASLMXSSFSW:
case USERSW:
case PORTSW:
case MTSSM: