summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--VERSION2
-rw-r--r--alpine/confscroll.c6
-rw-r--r--alpine/keymenu.c4
-rw-r--r--alpine/osdep/mswin.rc16
-rw-r--r--alpine/smime.c21
-rwxr-xr-xconfigure38
-rw-r--r--configure.ac6
-rw-r--r--doc/alpine.12
-rw-r--r--doc/tech-notes/index.html2
-rw-r--r--doc/tech-notes/tech-notes.txt2
-rw-r--r--imap/src/c-client/mail.c33
-rw-r--r--imap/src/c-client/mail.h1
-rw-r--r--include/config.h.in9
-rw-r--r--mapi/pmapi.c2
-rw-r--r--mapi/pmapi.rc14
-rw-r--r--pico/edef.h2
-rw-r--r--pico/estruct.h1
-rw-r--r--pico/osdep/mswin.c12
-rw-r--r--pico/pico.c30
-rw-r--r--pith/adrbklib.c42
-rw-r--r--pith/adrbklib.h2
-rw-r--r--pith/conf.c2
-rw-r--r--pith/conftype.h1
-rw-r--r--pith/mimedesc.c7
-rw-r--r--pith/pattern.c6
-rw-r--r--pith/pine.hlp119
-rw-r--r--pith/reply.c2
-rw-r--r--pith/send.c18
-rw-r--r--pith/smime.c196
-rw-r--r--pith/smime.h11
-rw-r--r--pith/smkeys.c71
-rw-r--r--po/Makefile.in2
32 files changed, 433 insertions, 249 deletions
diff --git a/VERSION b/VERSION
index b27c5902..f14b0551 100644
--- a/VERSION
+++ b/VERSION
@@ -1 +1 @@
-2.19.991
+2.19.999
diff --git a/alpine/confscroll.c b/alpine/confscroll.c
index 5ca2702b..71648202 100644
--- a/alpine/confscroll.c
+++ b/alpine/confscroll.c
@@ -4611,6 +4611,12 @@ toggle_feature_bit(struct pine *ps, int index, struct variable *var, CONF_S *cl,
ps->pass_ctrl_chars = F_ON(F_PASS_CONTROL_CHARS,ps_global) ? 1 : 0;
break;
+ case F_USE_CERT_STORE_ONLY:
+ if(F_OFF(F_USE_CERT_STORE_ONLY, ps))
+ q_status_message(SM_ORDER | SM_DING, 3, 4,
+ "Disabling this feature should only be done for testing. Press \"?\" for help");
+ break;
+
case F_PASS_C1_CONTROL_CHARS :
ps->pass_c1_ctrl_chars = F_ON(F_PASS_C1_CONTROL_CHARS,ps_global) ? 1 : 0;
break;
diff --git a/alpine/keymenu.c b/alpine/keymenu.c
index 3e90f1b7..3ce23503 100644
--- a/alpine/keymenu.c
+++ b/alpine/keymenu.c
@@ -2686,8 +2686,8 @@ struct key smime_certificate_info_keys[] =
{"R",N_("Private Key"),{MC_PRIVATE,1,{'r'}},KS_NONE},
NULL_MENU,
NULL_MENU,
- FWDEMAIL_MENU,
- {"S", N_("Save"), {MC_SAVETEXT,1,{'s'}}, KS_SAVE},
+ NULL_MENU,
+ NULL_MENU,
HELP_MENU,
OTHER_MENU,
diff --git a/alpine/osdep/mswin.rc b/alpine/osdep/mswin.rc
index eb6950ec..a6ae8c6c 100644
--- a/alpine/osdep/mswin.rc
+++ b/alpine/osdep/mswin.rc
@@ -244,8 +244,8 @@ END
//
VS_VERSION_INFO VERSIONINFO
- FILEVERSION 2,19,991,0
- PRODUCTVERSION 2,19,991,0
+ FILEVERSION 2,19,999,0
+ PRODUCTVERSION 2,19,999,0
FILEFLAGSMASK 0x3fL
#ifdef _DEBUG
FILEFLAGS 0x1L
@@ -260,19 +260,19 @@ BEGIN
BEGIN
BLOCK "040904b0"
BEGIN
- VALUE "Comments", "see http://www.washington.edu/alpine\0"
- VALUE "CompanyName", "University of Washington\0"
+ VALUE "Comments", "see http://patches.freeiz.com/alpine/\0"
+ VALUE "CompanyName", "Patches for Alpine\0"
#ifdef _PCP_W2K
VALUE "FileDescription", "Alpine with krb5 for Windows\0"
#else
VALUE "FileDescription", "Alpine\0"
#endif
- VALUE "FileVersion", "2.19.991\0"
+ VALUE "FileVersion", "2.19.999\0"
VALUE "InternalName", "alpine\0"
- VALUE "LegalCopyright", "Copyright 2006-2009\0"
+ VALUE "LegalCopyright", "Copyright 2006-2009 University of Washington, Copyright 2013-2014\0"
VALUE "OriginalFilename", "alpine.exe\0"
VALUE "ProductName", "alpine\0"
- VALUE "ProductVersion", "2.19.991\0"
+ VALUE "ProductVersion", "2.19.999\0"
END
END
BLOCK "VarFileInfo"
@@ -583,7 +583,7 @@ END
STRINGTABLE DISCARDABLE
BEGIN
- IDS_BYLINE "Copyright 2006-2009 University of Washington"
+ IDS_BYLINE "Copyright 2013-2014 Eduardo Chappa, Copyright 2006-2009 University of Washington"
IDS_APPNAME "Alpine"
IDS_APPIDENT "alpine"
END
diff --git a/alpine/smime.c b/alpine/smime.c
index 135ab3cf..1249ec72 100644
--- a/alpine/smime.c
+++ b/alpine/smime.c
@@ -56,7 +56,7 @@ void revert_to_saved_smime_config(struct pine *ps, SAVED_CONFIG_S *vsave);
SAVED_CONFIG_S *save_smime_config_vars(struct pine *ps);
void free_saved_smime_config(struct pine *ps, SAVED_CONFIG_S **vsavep);
int smime_helper_tool(struct pine *, int, CONF_S **, unsigned);
-int smime_public_certs_tool(struct pine *, int, CONF_S **, unsigned);
+//int smime_public_certs_tool(struct pine *, int, CONF_S **, unsigned);
void manage_certificates(struct pine *, WhichCerts);
void smime_manage_certs_init (struct pine *, CONF_S **, CONF_S **, WhichCerts, int);
void display_certificate_information(struct pine *, X509 *, char *, WhichCerts, int num);
@@ -187,7 +187,7 @@ smime_info_screen(struct pine *ps)
void
format_smime_info(int pass, BODY *body, long msgno, gf_io_t pc)
{
- PKCS7 *p7;
+ PKCS7 *p7 = NULL;
int i;
if(body->type == TYPEMULTIPART){
@@ -196,8 +196,10 @@ format_smime_info(int pass, BODY *body, long msgno, gf_io_t pc)
for(p=body->nested.part; p; p=p->next)
format_smime_info(pass, &p->body, msgno, pc);
}
-
- p7 = body->sparep;
+ if(body->sparep)
+ p7 = get_smime_sparep_type(body->sparep) == P7Type
+ ? (PKCS7 *)get_smime_sparep_data(body->sparep)
+ : NULL;
if(p7){
if(PKCS7_type_is_signed(p7)){
@@ -766,6 +768,17 @@ smime_config_init_display(struct pine *ps, CONF_S **ctmp, CONF_S **first_line)
(*ctmp)->varmem = ind;
(*ctmp)->value = pretty_value(ps, (*ctmp));
+ ind = feature_list_index(F_USE_CERT_STORE_ONLY);
+ feature = feature_list(ind);
+ new_confline(ctmp)->var = vtmp;
+ (*ctmp)->varnamep = ctmpb;
+ (*ctmp)->keymenu = &config_checkbox_keymenu;
+ (*ctmp)->help = config_help(vtmp-ps->vars, feature->id);
+ (*ctmp)->tool = checkbox_tool;
+ (*ctmp)->valoffset = feature_indent();
+ (*ctmp)->varmem = ind;
+ (*ctmp)->value = pretty_value(ps, (*ctmp));
+
#ifdef APPLEKEYCHAIN
new_confline(ctmp);
(*ctmp)->flags |= CF_NOSELECT | CF_B_LINE;
diff --git a/configure b/configure
index 87e253b0..dccad1d1 100755
--- a/configure
+++ b/configure
@@ -1,7 +1,7 @@
#! /bin/sh
-# From configure.ac Rev:13 by chappa@washington.edu.
+# From configure.ac Rev:14 by chappa@washington.edu.
# Guess values for system-dependent variables and create Makefiles.
-# Generated by GNU Autoconf 2.69 for alpine 2.19.991.
+# Generated by GNU Autoconf 2.69 for alpine 2.19.999.
#
# Report bugs to <chappa@washington.edu>.
#
@@ -730,8 +730,8 @@ MAKEFLAGS=
# Identity of this package.
PACKAGE_NAME='alpine'
PACKAGE_TARNAME='alpine'
-PACKAGE_VERSION='2.19.991'
-PACKAGE_STRING='alpine 2.19.991'
+PACKAGE_VERSION='2.19.999'
+PACKAGE_STRING='alpine 2.19.999'
PACKAGE_BUGREPORT='chappa@washington.edu'
PACKAGE_URL=''
@@ -1596,7 +1596,7 @@ if test "$ac_init_help" = "long"; then
# Omit some internal or obsolete options to make the list less imposing.
# This message is too long to be a string in the A/UX 3.1 sh.
cat <<_ACEOF
-\`configure' configures alpine 2.19.991 to adapt to many kinds of systems.
+\`configure' configures alpine 2.19.999 to adapt to many kinds of systems.
Usage: $0 [OPTION]... [VAR=VALUE]...
@@ -1666,7 +1666,7 @@ fi
if test -n "$ac_init_help"; then
case $ac_init_help in
- short | recursive ) echo "Configuration of alpine 2.19.991:";;
+ short | recursive ) echo "Configuration of alpine 2.19.999:";;
esac
cat <<\_ACEOF
@@ -1953,7 +1953,7 @@ fi
test -n "$ac_init_help" && exit $ac_status
if $ac_init_version; then
cat <<\_ACEOF
-alpine configure 2.19.991
+alpine configure 2.19.999
generated by GNU Autoconf 2.69
Copyright (C) 2012 Free Software Foundation, Inc.
@@ -2559,7 +2559,7 @@ cat >config.log <<_ACEOF
This file contains any messages produced by compilers while
running configure, to aid debugging if configure makes a mistake.
-It was created by alpine $as_me 2.19.991, which was
+It was created by alpine $as_me 2.19.999, which was
generated by GNU Autoconf 2.69. Invocation command line was
$ $0 $@
@@ -3380,7 +3380,7 @@ fi
# Define the identity of the package.
PACKAGE='alpine'
- VERSION='2.19.991'
+ VERSION='2.19.999'
cat >>confdefs.h <<_ACEOF
@@ -15533,6 +15533,22 @@ _ACEOF
+cat >>confdefs.h <<_ACEOF
+#define DF_PUBLIC_CONTAINER "PublicContainer"
+_ACEOF
+
+
+cat >>confdefs.h <<_ACEOF
+#define DF_PRIVATE_CONTAINER "PrivateContainer"
+_ACEOF
+
+
+cat >>confdefs.h <<_ACEOF
+#define DF_CA_CONTAINER "CAContainer"
+_ACEOF
+
+
+
# Check whether --with-passfile was given.
if test "${with_passfile+set}" = set; then :
withval=$with_passfile;
@@ -20339,7 +20355,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
# report actual input values of CONFIG_FILES etc. instead of their
# values after options handling.
ac_log="
-This file was extended by alpine $as_me 2.19.991, which was
+This file was extended by alpine $as_me 2.19.999, which was
generated by GNU Autoconf 2.69. Invocation command line was
CONFIG_FILES = $CONFIG_FILES
@@ -20405,7 +20421,7 @@ _ACEOF
cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`"
ac_cs_version="\\
-alpine config.status 2.19.991
+alpine config.status 2.19.999
configured by $0, generated by GNU Autoconf 2.69,
with options \\"\$ac_cs_config\\"
diff --git a/configure.ac b/configure.ac
index 1e818b7c..672a0bdb 100644
--- a/configure.ac
+++ b/configure.ac
@@ -15,7 +15,7 @@ dnl */
AC_PREREQ([2.69])
-AC_REVISION([Rev:13 by chappa@washington.edu])
+AC_REVISION([Rev:14 by chappa@washington.edu])
dnl Alpine Version Number is in $srcdir/VERSION
AC_INIT([alpine],[m4_normalize(m4_include(VERSION))],[chappa@washington.edu])
@@ -631,6 +631,10 @@ PINEVAR(smime-private-key-directory, DF_PRIVATEKEY_DIR, [.alpine-smime/private],
PINEVAR(smime-cacert-directory, DF_CACERT_DIR, [.alpine-smime/ca], [Default Cert Authority Directory])
PINEVAR_UNQUOTED(default-printer, DF_DEFAULT_PRINTER, [ANSI_PRINTER], [Default printer])
+AC_DEFINE_UNQUOTED([DF_PUBLIC_CONTAINER], "PublicContainer", [Name of default public container])
+AC_DEFINE_UNQUOTED([DF_PRIVATE_CONTAINER], "PrivateContainer", [Name of default private container])
+AC_DEFINE_UNQUOTED([DF_CA_CONTAINER], "CAContainer", [Name of default certificate authority container])
+
dnl set PASSFILE?
AC_ARG_WITH(passfile,
AS_HELP_STRING([--with-passfile=FILENAME],[Password cache file (recommended when S/MIME is enabled and configured)]),
diff --git a/doc/alpine.1 b/doc/alpine.1
index 550e676e..51e8a70a 100644
--- a/doc/alpine.1
+++ b/doc/alpine.1
@@ -1,4 +1,4 @@
-.TH alpine 1 "Version 2.19.991"
+.TH alpine 1 "Version 2.19.999"
.SH NAME
alpine \- an Alternatively Licensed Program for Internet News and Email
.SH SYNTAX
diff --git a/doc/tech-notes/index.html b/doc/tech-notes/index.html
index ad0b5095..5a05c1e4 100644
--- a/doc/tech-notes/index.html
+++ b/doc/tech-notes/index.html
@@ -3,7 +3,7 @@
<BODY>
<H1>Alpine Technical Notes</H1>
-Version 2.19.991, April 2014
+Version 2.19.999, May 2014
<H2><A NAME="TOC">Table of Contents</A></H2><P>
diff --git a/doc/tech-notes/tech-notes.txt b/doc/tech-notes/tech-notes.txt
index acfecdc2..e9bed323 100644
--- a/doc/tech-notes/tech-notes.txt
+++ b/doc/tech-notes/tech-notes.txt
@@ -1,7 +1,7 @@
Alpine Technical Notes
- Version 2.19.991, April 2014
+ Version 2.19.999, May 2014
Table of Contents
diff --git a/imap/src/c-client/mail.c b/imap/src/c-client/mail.c
index 871d07eb..03952d2e 100644
--- a/imap/src/c-client/mail.c
+++ b/imap/src/c-client/mail.c
@@ -2723,21 +2723,18 @@ void mail_gc_body (BODY *body)
if (body->mime.text.data) fs_give ((void **) &body->mime.text.data);
if (body->contents.text.data) fs_give ((void **) &body->contents.text.data);
}
-
-/* Mail get body part
- * Accepts: mail stream
- * message number
- * section specifier
- * Returns: pointer to body
+/* Mail get body section
+ * Accepts: body of message
+ * section specifier
+ * Returns: pointer to body at given section
*/
-BODY *mail_body (MAILSTREAM *stream,unsigned long msgno,unsigned char *section)
+BODY *mail_body_section (BODY *b, unsigned char *section)
{
- BODY *b = NIL;
PART *pt;
unsigned long i;
/* make sure have a body */
- if (section && *section && mail_fetchstructure (stream,msgno,&b) && b)
+ if (section && *section && b)
while (*section) { /* find desired section */
if (isdigit (*section)) { /* get section specifier */
/* make sure what follows is valid */
@@ -2768,6 +2765,24 @@ BODY *mail_body (MAILSTREAM *stream,unsigned long msgno,unsigned char *section)
else return NIL; /* unknown section specifier */
}
return b;
+}
+
+/* Mail get body part
+ * Accepts: mail stream
+ * message number
+ * section specifier
+ * Returns: pointer to body
+ */
+
+BODY *mail_body (MAILSTREAM *stream,unsigned long msgno,unsigned char *section)
+{
+ BODY *b = NIL;
+ PART *pt;
+ unsigned long i;
+ /* make sure have a body */
+ if (section && *section && mail_fetchstructure (stream,msgno,&b) && b)
+ return mail_body_section(b, section);
+ return b;
}
/* Mail output date from elt fields
diff --git a/imap/src/c-client/mail.h b/imap/src/c-client/mail.h
index fe7eaa77..2accc85b 100644
--- a/imap/src/c-client/mail.h
+++ b/imap/src/c-client/mail.h
@@ -1704,6 +1704,7 @@ void mail_gc (MAILSTREAM *stream,long gcflags);
void mail_gc_msg (MESSAGE *msg,long gcflags);
void mail_gc_body (BODY *body);
+BODY *mail_body_section (BODY *b, unsigned char *section);
BODY *mail_body (MAILSTREAM *stream,unsigned long msgno,
unsigned char *section);
char *mail_date (char *string,MESSAGECACHE *elt);
diff --git a/include/config.h.in b/include/config.h.in
index 8c0097da..edb0db6d 100644
--- a/include/config.h.in
+++ b/include/config.h.in
@@ -51,6 +51,9 @@
/* Default configuration value */
#undef DF_CACERT_DIR
+/* Name of default certificate authority container */
+#undef DF_CA_CONTAINER
+
/* Default configuration value */
#undef DF_DEFAULT_FCC
@@ -99,9 +102,15 @@
/* Default configuration value */
#undef DF_PRIVATEKEY_DIR
+/* Name of default private container */
+#undef DF_PRIVATE_CONTAINER
+
/* Default configuration value */
#undef DF_PUBLICCERT_DIR
+/* Name of default public container */
+#undef DF_PUBLIC_CONTAINER
+
/* Default configuration value */
#undef DF_REMOTE_ABOOK_HISTORY
diff --git a/mapi/pmapi.c b/mapi/pmapi.c
index bfdda141..4d4b3101 100644
--- a/mapi/pmapi.c
+++ b/mapi/pmapi.c
@@ -1952,7 +1952,7 @@ BOOL APIENTRY DllMain(
now = time((time_t *)0);
tm_now = localtime(&now);
- fprintf(ms_global->dfd, "pmapi32.dll for Alpine Version 2.19.991\r\n");
+ fprintf(ms_global->dfd, "pmapi32.dll for Alpine Version 2.19.999\r\n");
fprintf(ms_global->dfd, " Build date: %s\r\n", datestamp);
fprintf(ms_global->dfd,
" please report all bugs to chappa@gmx.com\r\n");
diff --git a/mapi/pmapi.rc b/mapi/pmapi.rc
index e6a37725..ed2e7b7e 100644
--- a/mapi/pmapi.rc
+++ b/mapi/pmapi.rc
@@ -98,8 +98,8 @@ END
//
VS_VERSION_INFO VERSIONINFO
- FILEVERSION 2,19,991,0
- PRODUCTVERSION 2,19,991,0
+ FILEVERSION 2,19,999,0
+ PRODUCTVERSION 2,19,999,0
FILEFLAGSMASK 0x3fL
#ifdef _DEBUG
FILEFLAGS 0x29L
@@ -114,17 +114,17 @@ BEGIN
BEGIN
BLOCK "040904b0"
BEGIN
- VALUE "Comments", "alpine info: http://www.washington.edu/alpine\0"
- VALUE "CompanyName", "University of Washington\0"
+ VALUE "Comments", "alpine info: http://patches.freeiz.com/alpine\0"
+ VALUE "CompanyName", "Patches for Alpine\0"
VALUE "FileDescription", "Simple MAPI DLL for Alpine for Windows\0"
- VALUE "FileVersion", "2.19.991\0"
+ VALUE "FileVersion", "2.19.999\0"
VALUE "InternalName", "pmapi32\0"
- VALUE "LegalCopyright", "Copyright ? 2006-2009\0"
+ VALUE "LegalCopyright", "Copyright ? University of Washington 2006-2009, Eduardo Chappa 2013-2014\0"
VALUE "LegalTrademarks", "Apache License, Version 2.0\0"
VALUE "OriginalFilename", "pmapi32.dll\0"
VALUE "PrivateBuild", " \0"
VALUE "ProductName", "Simple MAPI for Alpine for Windows\0"
- VALUE "ProductVersion", "2.19.991\0"
+ VALUE "ProductVersion", "2.19.999\0"
VALUE "SpecialBuild", " \0"
END
END
diff --git a/pico/edef.h b/pico/edef.h
index 209a4600..3cc7fd3e 100644
--- a/pico/edef.h
+++ b/pico/edef.h
@@ -32,6 +32,7 @@
/* initialized global definitions */
+int direction = 0; /* direction of writing */
int fillcol = 72; /* Current fill column */
int userfillcol = -1; /* Fillcol set from cmd line */
UCS pat[NPAT]; /* Search pattern */
@@ -84,6 +85,7 @@ void *input_cs; /* passed to mbtow() via kbseq() */
/* initialized global external declarations */
+extern int direction;
extern int fillcol; /* Fill column */
extern int userfillcol; /* Fillcol set from cmd line */
extern UCS pat[]; /* Search pattern */
diff --git a/pico/estruct.h b/pico/estruct.h
index cff5a6de..0cfe2e01 100644
--- a/pico/estruct.h
+++ b/pico/estruct.h
@@ -239,6 +239,7 @@ typedef struct {
typedef struct CELL {
unsigned int c : 24; /* Character value in cell */
unsigned int a : 8; /* Its attributes */
+ unsigned int d : 1; /* direction */
} CELL;
/* flags for color_options */
diff --git a/pico/osdep/mswin.c b/pico/osdep/mswin.c
index 538e0d33..6fce077a 100644
--- a/pico/osdep/mswin.c
+++ b/pico/osdep/mswin.c
@@ -157,6 +157,9 @@
#define CQ_FLAG_EXTENDED 0x02
#define CQ_FLAG_ALT 0x04
+#define ARABIC_LRM 0x200E
+#define ARABIC_RLM 0x200F
+
/* Special ASCII characters. */
#define ASCII_BEL 0x07
#define ASCII_BS 0x08
@@ -3395,6 +3398,10 @@ WriteTTYBlock (HWND hWnd, LPTSTR lpBlock, int nLength)
for (i = 0 ; i < nLength; i++) {
switch (lpBlock[i]) {
+ case ARABIC_LRM:
+ case ARABIC_RLM:
+ break;
+
case ASCII_BEL:
/* Bell */
MessageBeep (0) ;
@@ -7054,6 +7061,11 @@ int
mswin_putc (UCS ucs)
{
TCHAR cc = (TCHAR)ucs;
+ if(ucs == ARABIC_LRM || ucs == ARABIC_RLM){
+ FlushWriteAccum();
+ WriteTTYBlock (ghTTYWnd, &cc, 1);
+ return 0;
+ }
if (ucs >= (UCS)(' ')) {
/* Not carriage control. */
gpTTYInfo->writeAccum[gpTTYInfo->writeAccumCount++] = (TCHAR)ucs;
diff --git a/pico/pico.c b/pico/pico.c
index 40d971b9..ca09749f 100644
--- a/pico/pico.c
+++ b/pico/pico.c
@@ -72,6 +72,7 @@ static char rcsid[] = "$Id: pico.c 921 2008-01-31 02:09:25Z hubert@u.washington.
#include "../pith/charconv/filesys.h"
+void remove_directions_mark(void);
void func_init(void);
void breplace(void *w);
int any_header_changes(void);
@@ -102,6 +103,33 @@ static UCS pfkm[12][2] = {
};
+void
+remove_directions_mark(void)
+{
+ LINE *lp;
+ int i, ll;
+ UCS c;
+
+ for(lp = lforw(curbp->b_linep); lp != curbp->b_linep; lp = lforw(lp)){
+ ll = llength(lp);
+ for(i = 0; i < ll;){
+ c = lgetc(lp, i).c;
+ if(c == 0x200E || c == 0x200F){
+ curwp->w_dotp = lp;
+ curwp->w_doto = i;
+ forwdel(FALSE, 1);
+ direction = c == 0x200E ? 0 : 1;
+ }
+ else
+ lgetc(lp,i++).d = direction;
+ }
+ }
+ curwp->w_linep = lforw(curbp->b_linep);
+ curwp->w_dotp = lforw(curbp->b_linep);
+ curwp->w_doto = 0;
+}
+
+
/*
* flag for the various functions in pico() to set when ready
* for pico() to return...
@@ -172,6 +200,8 @@ pico(PICO *pm)
if(pm->msgtext)
breplace(pm->msgtext);
+ remove_directions_mark();
+
#ifdef _WINDOWS
cursor_shown = mswin_showcaret(1); /* turn on for main window */
mswin_allowpaste(MSWIN_PASTE_FULL);
diff --git a/pith/adrbklib.c b/pith/adrbklib.c
index 51979bdc..bdd505fb 100644
--- a/pith/adrbklib.c
+++ b/pith/adrbklib.c
@@ -6026,3 +6026,45 @@ add_forced_entries(AdrBk *abook)
}
}
}
+
+/* Go through the list of addressbooks and check if any
+ * of them point to the given stream.
+ */
+int
+any_addressbook_in_remote_stream(MAILSTREAM *stream)
+{
+ int rv = 0;
+ int i = 0, num = 0;
+ char *nickname = NULL;
+ char *filename = NULL;
+ char *q = NULL;
+
+ do{
+ if(ps_global->VAR_ADDRESSBOOK &&
+ ps_global->VAR_ADDRESSBOOK[num] &&
+ ps_global->VAR_ADDRESSBOOK[num][0]){
+ q = ps_global->VAR_ADDRESSBOOK[num++];
+ i = num;
+ }
+ else if(ps_global->VAR_GLOB_ADDRBOOK &&
+ ps_global->VAR_GLOB_ADDRBOOK[i-num] &&
+ ps_global->VAR_GLOB_ADDRBOOK[i-num][0]){
+ q = ps_global->VAR_GLOB_ADDRBOOK[i - num];
+ i++;
+ } else q = NULL;
+ if(q != NULL){
+ get_pair(q, &nickname, &filename, 0, 0);
+
+ if(nickname) fs_give((void **)&nickname);
+
+ if(filename){
+ if(*filename == '{'
+ && same_stream(filename, stream) != NULL)
+ rv = 1;
+ fs_give((void **)&filename);
+ }
+ }
+ } while (rv == 0 && q != NULL);
+
+ return rv;
+}
diff --git a/pith/adrbklib.h b/pith/adrbklib.h
index 9fbeb37c..505a8525 100644
--- a/pith/adrbklib.h
+++ b/pith/adrbklib.h
@@ -852,6 +852,6 @@ void adrbk_maintenance(void);
char **parse_addrlist(char *);
char *skip_to_next_addr(char *);
void add_forced_entries(AdrBk *);
-
+int any_addressbook_in_remote_stream(MAILSTREAM *);
#endif /* PITH_ADRBKLIB_INCLUDED */
diff --git a/pith/conf.c b/pith/conf.c
index 4bc9481b..81eed75b 100644
--- a/pith/conf.c
+++ b/pith/conf.c
@@ -3259,6 +3259,8 @@ feature_list(int index)
F_REMEMBER_SMIME_PASSPHRASE, h_config_smime_remember_passphrase, PREF_HIDDEN, 0},
{"smime-sign-by-default", "S/MIME -- Sign by Default",
F_SIGN_DEFAULT_ON, h_config_smime_sign_by_default, PREF_HIDDEN, 0},
+ {"smime-use-store-only", "S/MIME -- Validate Using Certificate Store Only",
+ F_USE_CERT_STORE_ONLY, h_config_smime_use_cert_store, PREF_HIDDEN, 1},
#ifdef APPLEKEYCHAIN
{"publiccerts-in-keychain", "S/MIME -- Public Certs in MacOS Keychain",
F_PUBLICCERTS_IN_KEYCHAIN, h_config_smime_pubcerts_in_keychain, PREF_HIDDEN, 0},
diff --git a/pith/conftype.h b/pith/conftype.h
index 16e8de25..8ba7941c 100644
--- a/pith/conftype.h
+++ b/pith/conftype.h
@@ -544,6 +544,7 @@ typedef enum {
F_SIGN_DEFAULT_ON,
F_ENCRYPT_DEFAULT_ON,
F_REMEMBER_SMIME_PASSPHRASE,
+ F_USE_CERT_STORE_ONLY,
#ifdef APPLEKEYCHAIN
F_PUBLICCERTS_IN_KEYCHAIN,
#endif
diff --git a/pith/mimedesc.c b/pith/mimedesc.c
index 5b9db1b4..8a1d7f7d 100644
--- a/pith/mimedesc.c
+++ b/pith/mimedesc.c
@@ -579,12 +579,15 @@ type_desc(int type, char *subtype, PARAMETER *params, PARAMETER *disp_params, in
}
if(full && type != TYPEMULTIPART && type != TYPEMESSAGE){
+ unsigned char decodebuf[10000];
if((parmval = parameter_val(params, "name")) != NULL){
- snprintf(p, sizeof(type_d)-(p-type_d), " (Name: \"%s\")", parmval);
+ rfc1522_decode_to_utf8(decodebuf, sizeof(decodebuf), parmval);
+ snprintf(p, sizeof(type_d)-(p-type_d), " (Name: \"%s\")", decodebuf);
fs_give((void **) &parmval);
}
else if((parmval = parameter_val(disp_params, "filename")) != NULL){
- snprintf(p, sizeof(type_d)-(p-type_d), " (Filename: \"%s\")", parmval);
+ rfc1522_decode_to_utf8(decodebuf, sizeof(decodebuf), parmval);
+ snprintf(p, sizeof(type_d)-(p-type_d), " (Filename: \"%s\")", decodebuf);
fs_give((void **) &parmval);
}
}
diff --git a/pith/pattern.c b/pith/pattern.c
index 3a258e7c..0b2eaf58 100644
--- a/pith/pattern.c
+++ b/pith/pattern.c
@@ -3,8 +3,8 @@ static char rcsid[] = "$Id: pattern.c 1204 2009-02-02 19:54:23Z hubert@u.washing
#endif
/*
* ========================================================================
- * Copyright 2006-2009 University of Washington
* Copyright 2013-2014 Eduardo Chappa
+ * Copyright 2006-2009 University of Washington
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -4764,7 +4764,9 @@ match_pattern(PATGRP_S *patgrp, MAILSTREAM *stream, SEARCHSET *searchset,
}
if(in_client_callback && is_imap_stream(stream)
- && (patgrp->alltext || patgrp->bodytext))
+ && (patgrp->alltext || patgrp->bodytext
+ || (patgrp->inabook != IAB_EITHER
+ && any_addressbook_in_remote_stream(stream))))
return(-1);
pgm = match_pattern_srchpgm(patgrp, stream, searchset);
diff --git a/pith/pine.hlp b/pith/pine.hlp
index b296f024..6377dabb 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 61 2014-05-02 18:29:37
+Alpine Commit 62 2014-05-17 16:49:55
============= h_news =================
<HTML>
<HEAD>
@@ -162,7 +162,7 @@ Version <!--#echo var="ALPINE_VERSION"--> (<!--#echo var="ALPINE_REVISION"-->)
<P>
Alpine is an &quot;Alternatively Licensed Program for Internet
-News and Email&quot; produced until 2008 by the University of Washington.
+News and Email&quot; produced until 2009 by the University of Washington.
It is intended to be an easy-to-use program for
sending, receiving, and filing Internet electronic mail messages and
bulletin board (Netnews) messages. Alpine is designed to run on a wide
@@ -184,6 +184,11 @@ Additions include:
<LI> Upgrade UW-IMAP to Panda IMAP from
<A HREF="https://github.com/jonabbey/panda-imap">https://github.com/jonabbey/panda-imap</A>.
<LI> S/MIME: Add screen to manage certificates.
+ <LI> S/MIME: Signatures are validated using the user's certificates instead
+ of the ones included in the message. Behavior can be disabled by
+ disabling the option <A href="h_config_smime_use_cert_store">
+ <!--#echo var="FEAT_smime-use-storey-only"--></A>, which is enabled
+ by default.
<LI> S/MIME: sign messages using intermediate certificates when needed
and possible.
<LI> S/MIME: validation of certificates for servers that modify signed
@@ -192,7 +197,11 @@ Additions include:
encrypted second, so that they can be decoded by other clients.
<LI> S/MIME: add the sender certificate to the list of certificates in
encrypted messages to make it possible for the sender to decrypt
- the message they sent.
+ the message they sent.
+ <LI> S/MIME: When transferring certificates to a local container, create
+ container with default names PublicContainer, PrivateContainer and
+ CAContainer, as appropriate for these files, unless the user has
+ provided some other names.
<LI> Add support to selective expunge through a subcommand of the
select-apply commands. Read more in the <A
HREF="h_index_cmd_expunge">help</A> for the expunge command.
@@ -235,6 +244,8 @@ Additions include:
<LI> Pico: Justification works without need of a predefined quote
string. This allows justification of blocks of text that are
indented with spaces.
+ <LI> Decode the name of attachment names, so they can be written as part
+ of the description of the part.
<LI> Check bounds and tie strings off to improve security. Contributed
by James Jerkins.
<LI> Replace tabs by spaces in From and Subject fields to control for
@@ -267,10 +278,21 @@ Bugs that have been addressed include:
and Stefan Mueller.
<LI> S/MIME: Certificates are lost when using a pinerc file outside of the
home directory.
- <LI> S/MIME: accessing the S/MIME configuration screen would deinitialize
+ <LI> S/MIME: Accessing the S/MIME configuration screen would deinitialize
SMIME making it not possible to sign or encrypt messages.
+ <LI> S/MIME: Forwarding a signed message might make the body contain mime
+ information that is not part of the body, and hence making the body
+ of the message seem wrong.
<LI> Crash when tcp connection to NNTP server was lost after connection
had been established, but lost immediately afterwards.
+ <LI> Crash with message &quot;lock when already locked&quot;, when painting
+ an index was based on scores that needed information from a remote
+ addressbook in the same server as the folder opened. Reported by
+ Peter Koellner.
+ <LI> Alpine cannot handle correctly some characters in the Windows-1256
+ character set, which might lead to a crash or a corruption in the
+ screen. Work was done to contain the bug. A more complete fix will
+ be done in a future release. Reported by Professor Robert Funnell.
<LI> WebAlpine: add _GNU_SOURCE to make pubcookie build.
<LI> WebAlpine: fail to build with debug disabled. Fix from Sam Hathaway.
<LI> Save command did not warn of existence of a message with a deleted
@@ -294,7 +316,7 @@ Bugs that have been addressed include:
$alpine_TCLINC instead of $alpine_TCLINC/tcl.h. Reported and fixed
by Werner Scheinast.
<LI> Move SSL configurations from UW-IMAP to configure script, and
- update OpenSSL configuration for Mac OSX.
+ update OpenSSL configuration for Mac OS X.
<LI> Remove -lregex from linker flags when building --with-supplied-regex.
</UL>
<P>
@@ -357,7 +379,7 @@ Additions include:
<UL>
<LI> Quota report for IMAP folders that support it (press the &quot;@&quot; command in the index screen of such folder).
<LI> Search a folder for the content of any header with the &quot;;&quot; command.
- <LI> Foreign characters are decoded correctly in IMAP folders.
+ <LI> Foreign characters are decoded correctly in IMAP folder names.
<LI> Question about breaking connection to slow servers includes their name.
<LI> Internal x-alpine-help: resource locator for sending links to internal help.
<LI> OpenSuse: Alpine find location of OpenSSL certificates.
@@ -380,7 +402,7 @@ Bugs that have been addressed include:
<LI> Not display of login prompt during initial keystrokes.
<LI> justification of long urls breaks them.
<LI> Incorrect New Mail message when envelope is not available.
- <LI> Inorrect display of PREFDATE, PREFDATETIME and PREFTIME tokens.
+ <LI> Incorrect display of PREFDATE, PREFDATETIME and PREFTIME tokens.
<LI> Crash when resizing the screen after display of LDAP search.
<LI> Crash when redrawing screen while opening a remote folder collection.
<LI> Infinite loop in scrolltool function during notification of new mail.
@@ -713,7 +735,7 @@ version <!--#echo var="C_CLIENT_VERSION"-->.
Alpine was developed until 2009 by the Office of Computing
&amp; Communications at the University of Washington in Seattle.
Since then, the effort of developing Alpine has been continued by
-a community of volunteers who make a good software even better!
+a community of volunteers who make good software even better!
<P>
Alpine Copyright 2013-2014 Eduardo Chappa,
@@ -1535,7 +1557,7 @@ employer, ... ; or
</UL>
Due to the large number of Alpine installations worldwide, and because we
-receive no funding for it, the Alpine development team <B>cannot provide
+receive no funding for it, the University of Washington <B>cannot provide
individual support services outside the University of Washington</B>.
<P>
If you have no local computing support to turn to, the worldwide <b>comp.mail.pine</b>
@@ -1599,13 +1621,14 @@ select Setup/Config to see many of the options available to you. Also note
that all screens have context-sensitive help text available.<P>
<!--chtml if pinemode="phone_home"-->
SPECIAL REQUEST:
-This software is made available as a public service of the
-University of Washington in Seattle. We are no longer actively developing
-the software, but it is still helpful to us to have an idea of how many
-people are using Alpine. Are you willing to be counted as an Alpine user? Pressing
+This software was originally created and maintained as a public
+service by the University of Washington until 2009; updates are made
+available as a public service of the Alpine community. It is always
+helpful to have an idea of how many users are using Alpine. Are you
+willing to be counted as an Alpine user? Pressing
<A HREF="X-Alpine-Phone-Home:">Return</A>
will send an anonymous (meaning, your real email address will not be revealed)
-message to the Alpine team at the University of Washington for purposes of tallying.
+message to the Alpine developers for purposes of tallying.
<P>
<!--To Exit this screen and continue your Alpine session press "E".-->
<!--chtml else-->
@@ -1632,13 +1655,14 @@ The Release Notes may be viewed by pressing
<P>
<!--chtml if pinemode="phone_home"-->
SPECIAL REQUEST:
-This software is made available as a public service of the
-University of Washington in Seattle. We are no longer actively developing
-the software, but it is still helpful to us to have an idea of how many
-people are using Alpine. Are you willing to be counted as an Alpine user? Pressing
+This software was originally created and maintained as a public
+service by the University of Washington until 2009; updates are made
+available as a public service of the Alpine community. It is always
+helpful to have an idea of how many users are using Alpine. Are you
+willing to be counted as an Alpine user? Pressing
<A HREF="X-Alpine-Phone-Home:">Return</A>
will send an anonymous (meaning, your real email address will not be revealed)
-message to the Alpine team at the University of Washington for purposes of tallying.
+message to the Alpine developers for purposes of tallying.
<P>
<!--To Exit this screen and continue your Alpine session press "E".-->
<!--chtml else-->
@@ -1662,14 +1686,15 @@ documented in the Release Notes, which may be viewed by pressing
<P>
<!--chtml if pinemode="phone_home"-->
SPECIAL REQUEST:
-This software is made available as a public service of the
-University of Washington in Seattle. We are no longer actively developing
-the software, but it is still helpful to us to have an idea of how many
-people are using Alpine. Are you willing to be counted as an Alpine user? Pressing
+This software was originally created and maintained as a public
+service by the University of Washington until 2009; updates are made
+available as a public service of the Alpine community. It is always
+helpful to have an idea of how many users are using Alpine. Are you
+willing to be counted as an Alpine user? Pressing
<A HREF="X-Alpine-Phone-Home:">Return</A>
will send an anonymous (meaning, your real email address will not be revealed)
-message to the Alpine team at the University of Washington for purposes of tallying.
-
+message to the Alpine developers for purposes of tallying.
+<P>
<!--To Exit this screen and continue your Alpine session press "E".-->
<!--chtml else-->
To Exit this screen and continue your Alpine session press "Return".
@@ -1766,7 +1791,7 @@ The &quot;NextLink&quot; and &quot;PrevLink&quot; commands
<H1>Introduction</H1>
Alpine is an &quot;Alternatively Licensed Program for Internet
-News and Email&quot; produced until 2008 by the University of Washington.
+News and Email&quot; produced until 2009 by the University of Washington.
It is intended to be an easy-to-use program for
sending, receiving, and filing Internet electronic mail messages and
bulletin board (Netnews/Usenet) messages. Alpine supports the following
@@ -3945,6 +3970,7 @@ There are also additional details on
<li><a href="h_config_smime_encrypt_by_default">S/MIME FEATURE: <!--#echo var="FEAT_smime-encrypt-by-default"--></a>
<li><a href="h_config_smime_remember_passphrase">S/MIME FEATURE: <!--#echo var="FEAT_smime-remember-passphrase"--></a>
<li><a href="h_config_smime_sign_by_default">S/MIME FEATURE: <!--#echo var="FEAT_smime-sign-by-default"--></a>
+<li><a href="h_config_smime_use_cert_store">S/MIME FEATURE: <!--#echo var="FEAT_smime-use-store-only"--></a>
<li><a href="h_config_smime_pubcerts_in_keychain">S/MIME FEATURE: <!--#echo var="FEAT_publiccerts-in-keychain"--></a>
<li><a href="h_config_smime_cacertcon">S/MIME OPTION: <!--#echo var="VAR_smime-cacert-container"--></a>
<li><a href="h_config_smime_cacertdir">S/MIME OPTION: <!--#echo var="VAR_smime-cacert-directory"--></a>
@@ -34597,6 +34623,47 @@ certificate).
&lt;End of help on this topic&gt;
</BODY>
</HTML>
+========== h_config_smime_use_cert_store ==========
+<HTML>
+<HEAD>
+<TITLE>S/MIME FEATURE: <!--#echo var="FEAT_smime-use-store-only"--></TITLE>
+</HEAD>
+<BODY>
+<H1>S/MIME FEATURE: <!--#echo var="FEAT_smime-use-store-only"--></H1>
+
+UNIX Alpine only.
+<P>
+This feature only has an effect if your version of Alpine includes
+support for S/MIME.
+It affects Alpine's behavior when you validate a message, and should
+not be disabled, unless you are performing a test.
+<P>
+There are two important aspects of validation: validation of the message
+(that is, the message was not modified after it was sent)
+as well as validation of the identity of the sender. This option has to
+do with the latter.
+<P>
+In order to validate that the message came from the sender in the message
+and not an impersonator, Alpine can
+either use the certificates that come in the message, or the ones that
+you have personally stored. If this feature is enabled (the default) then
+Alpine will use certificates that you have already saved in your store
+and not those that come in the message to validate the sender of the
+message. This behavior helps you prevent against impersonation, because
+it is assumed that you trust the certificates that you have saved, and
+might not trust those that came with the message that you are validating.
+<P>
+<UL>
+<LI><A HREF="h_mainhelp_smime">General S/MIME help</A>
+</UL><P>
+<P>
+
+<UL>
+<LI><A HREF="h_finding_help">Finding more information and requesting help</A>
+</UL><P>
+&lt;End of help on this topic&gt;
+</BODY>
+</HTML>
========== h_config_smime_pubcerts_in_keychain ==========
<HTML>
<HEAD>
diff --git a/pith/reply.c b/pith/reply.c
index d7270a2c..60a7c489 100644
--- a/pith/reply.c
+++ b/pith/reply.c
@@ -2253,7 +2253,7 @@ forward_body(MAILSTREAM *stream, ENVELOPE *env, struct mail_bodystruct *orig_bod
&& orig_body->nested.part){
/* only operate on the signed data (not the signature) */
body = forward_body(stream, env, &orig_body->nested.part->body,
- msgno, sect_prefix, msgtext, flags);
+ msgno, section, msgtext, flags);
}
/*---- Message is multipart ----*/
else if(!(orig_body->subtype && !strucmp(orig_body->subtype,
diff --git a/pith/send.c b/pith/send.c
index 4620d1aa..191e186d 100644
--- a/pith/send.c
+++ b/pith/send.c
@@ -4245,6 +4245,7 @@ l_putc(int c)
long
pine_rfc822_output_body(struct mail_bodystruct *body, soutr_t f, void *s)
{
+ STORE_S *bodyso;
PART *part;
PARAMETER *param;
char *t, *cookie = NIL, *encode_error;
@@ -4255,6 +4256,9 @@ pine_rfc822_output_body(struct mail_bodystruct *body, soutr_t f, void *s)
dprint((4, "-- pine_rfc822_output_body: %d\n",
body ? body->type : 0));
+
+ bodyso = (STORE_S *) body->contents.text.data;
+
if(body->type == TYPEMULTIPART) { /* multipart gets special handling */
part = body->nested.part; /* first body part */
/* find cookie */
@@ -4307,8 +4311,8 @@ pine_rfc822_output_body(struct mail_bodystruct *body, soutr_t f, void *s)
dprint((4, "-- pine_rfc822_output_body: segment %ld bytes\n",
body->size.bytes));
- if(body->contents.text.data)
- gf_set_so_readc(&gc, (STORE_S *) body->contents.text.data);
+ if(bodyso)
+ gf_set_so_readc(&gc, bodyso);
else
return(1);
@@ -4316,15 +4320,15 @@ pine_rfc822_output_body(struct mail_bodystruct *body, soutr_t f, void *s)
* Don't add trailing line if it is ExternalText, which already guarantees
* a trailing newline.
*/
- add_trailing_crlf = !(((STORE_S *) body->contents.text.data)->src == ExternalText);
+ add_trailing_crlf = !(bodyso->src == ExternalText);
- so_seek((STORE_S *) body->contents.text.data, 0L, 0);
+ so_seek(bodyso, 0L, 0);
if(body->type != TYPEMESSAGE){ /* NOT encapsulated message */
char *charset;
if(body->type == TYPETEXT
- && so_attr((STORE_S *) body->contents.text.data, "edited", NULL)
+ && so_attr(bodyso, "edited", NULL)
&& (charset = parameter_val(body->parameter, "charset"))){
if(strucmp(charset, "utf-8") && strucmp(charset, "us-ascii")){
if(!strucmp(charset, "iso-2022-jp")){
@@ -4356,7 +4360,7 @@ pine_rfc822_output_body(struct mail_bodystruct *body, soutr_t f, void *s)
*/
if(body->type == TYPETEXT
&& body->encoding != ENCBASE64
- && !so_attr((STORE_S *) body->contents.text.data, "rawbody", NULL)){
+ && !so_attr(bodyso, "rawbody", NULL)){
gf_link_filter(gf_local_nvtnl, NULL);
}
@@ -4380,7 +4384,7 @@ pine_rfc822_output_body(struct mail_bodystruct *body, soutr_t f, void *s)
display_message('x');
}
- gf_clear_so_readc((STORE_S *) body->contents.text.data);
+ gf_clear_so_readc(bodyso);
if(encode_error || !l_flush_net(TRUE))
return(0);
diff --git a/pith/smime.c b/pith/smime.c
index ce7b6a70..6c49fdcc 100644
--- a/pith/smime.c
+++ b/pith/smime.c
@@ -62,7 +62,7 @@ static BIO *bio_from_store(STORE_S *store);
static STORE_S *get_part_contents(long msgno, const char *section);
static PKCS7 *get_pkcs7_from_part(long msgno, const char *section);
static int do_signature_verify(PKCS7 *p7, BIO *in, BIO *out, int silent);
-int do_detached_signature_verify(BODY *b, long msgno, char *section);
+static int do_detached_signature_verify(BODY *b, long msgno, char *section);
static PERSONAL_CERT *find_certificate_matching_pkcs7(PKCS7 *p7);
static int do_decoding(BODY *b, long msgno, const char *section);
static void free_smime_struct(SMIME_STUFF_S **smime);
@@ -90,13 +90,6 @@ static X509_STORE *s_cert_store;
static int seeded = 0;
static int egdsocket = 0;
-typedef enum {P7Type, CharType, SizedText} SpareType;
-
-typedef struct smime_sparep_t {
- SpareType sptype;
- void *data;
-} SMIME_SPARE_S;
-
void *
create_smime_sparep(SpareType stype, void *s)
{
@@ -1410,13 +1403,15 @@ copy_dir_to_container(WhichCerts which, char *contents)
int ret = 0;
BIO *bio_out = NULL, *bio_in = NULL;
char srcpath[MAXPATH+1], dstpath[MAXPATH+1], emailaddr[MAXPATH], file[MAXPATH], line[4096];
- char *tempfile = NULL;
+ char *tempfile = NULL, fpath[MAXPATH+1];
DIR *dirp;
struct dirent *d;
REMDATA_S *rd = NULL;
char *configdir = NULL;
char *configpath = NULL;
+ char *configcontainer = NULL;
char *filesuffix = NULL;
+ char *ret_dir = NULL;
dprint((9, "copy_dir_to_container(%s)", which==Public ? "Public" : which==Private ? "Private" : which==CACert ? "CACert" : "?"));
smime_init();
@@ -1429,16 +1424,19 @@ copy_dir_to_container(WhichCerts which, char *contents)
if(which == Public){
configdir = ps_global->VAR_PUBLICCERT_DIR;
configpath = ps_global->smime->publicpath;
+ configcontainer = cpystr(DF_PUBLIC_CONTAINER);
filesuffix = ".crt";
}
else if(which == Private){
configdir = ps_global->VAR_PRIVATEKEY_DIR;
configpath = ps_global->smime->privatepath;
+ configcontainer = cpystr(DF_PRIVATE_CONTAINER);
filesuffix = ".key";
}
else if(which == CACert){
configdir = ps_global->VAR_CACERT_DIR;
configpath = ps_global->smime->capath;
+ configcontainer = cpystr(DF_CA_CONTAINER);
filesuffix = ".crt";
}
@@ -1534,7 +1532,7 @@ copy_dir_to_container(WhichCerts which, char *contents)
* dstpath is either the local Container file or the local cache file
* for the remote Container file.
*/
- tempfile = tempfile_in_same_dir(dstpath, "az", NULL);
+ tempfile = tempfile_in_same_dir(dstpath, "az", &ret_dir);
}
/*
@@ -1609,12 +1607,24 @@ copy_dir_to_container(WhichCerts which, char *contents)
BIO_free(bio_out);
if(!ret){
- if(rename_file(tempfile, dstpath) < 0){
+ if(ret_dir){
+ if(strlen(dstpath) + strlen(configcontainer) - strlen(ret_dir) + 1 < sizeof(dstpath))
+ snprintf(fpath, sizeof(fpath), "%s%c%s",
+ dstpath, tempfile[strlen(ret_dir)], configcontainer);
+ else
+ ret = -1;
+ }
+ else ret = -1;
+
+ if(!ret){
+ if(rename_file(tempfile, fpath) < 0){
q_status_message2(SM_ORDER, 3, 3,
- _("Can't rename %s to %s"), tempfile, dstpath);
+ _("Can't rename %s to %s"), tempfile, fpath);
ret = -1;
+ } else q_status_message1(SM_ORDER, 3, 3,
+ _("saved container to %s"), fpath);
}
-
+
/* if the container is remote, copy it */
if(!ret && IS_REMOTE(configpath)){
int e;
@@ -1656,6 +1666,12 @@ copy_dir_to_container(WhichCerts which, char *contents)
if(tempfile)
fs_give((void **) &tempfile);
+ if(ret_dir)
+ fs_give((void **) &ret_dir);
+
+ if(configcontainer)
+ fs_give((void **) &configcontainer);
+
return ret;
}
@@ -1921,36 +1937,6 @@ is_pkcs7_body(BODY *body)
}
-#ifdef notdef
-/*
- * Somewhat useful debug utility to dump the contents of a BIO to a file.
- * Note that a memory BIO will have its contents eliminated after they
- * are read so this will break the next step.
- */
-static void
-dump_bio_to_file(BIO *in, char *filename)
-{
- char iobuf[4096];
- int len;
- BIO *out;
-
- out = BIO_new_file(filename, "w");
-
- if(out){
- if(BIO_method_type(in) != BIO_TYPE_MEM)
- BIO_reset(in);
-
- while((len = BIO_read(in, iobuf, sizeof(iobuf))) > 0)
- BIO_write(out, iobuf, len);
-
- BIO_free(out);
- }
-
- BIO_reset(in);
-}
-#endif
-
-
/*
* Recursively stash a pointer to the decrypted data in our
* manufactured body.
@@ -2255,7 +2241,7 @@ end:
/*
* Encrypt a message on the way out. Called from call_mailer in send.c
- * The body may be reallocated.
+ * The body may be reallocated.
*/
int
encrypt_outgoing_message(METAENV *header, BODY **bodyP)
@@ -2287,9 +2273,9 @@ encrypt_outgoing_message(METAENV *header, BODY **bodyP)
for(a=*pf->addr; a; a=a->next){
snprintf(buf, sizeof(buf), "%s@%s", a->mailbox, a->host);
- if((cert = get_cert_for(buf, Public)) != NULL)
+ if((cert = get_cert_for(buf, Public)) != NULL){
sk_X509_push(encerts,cert);
- else{
+ }else{
q_status_message2(SM_ORDER, 1, 1,
_("Unable to find certificate for <%s@%s>"),
a->mailbox, a->host);
@@ -2491,10 +2477,12 @@ static int
do_signature_verify(PKCS7 *p7, BIO *in, BIO *out, int silent)
{
STACK_OF(X509) *otherCerts = NULL;
+ CertList *cl;
int result;
+ int flags;
const char *data;
long err;
-
+
if(!s_cert_store){
if(!silent) q_status_message(SM_ORDER | SM_DING, 2, 2,
_("Couldn't verify S/MIME signature: No CA Certs were loaded"));
@@ -2504,8 +2492,31 @@ do_signature_verify(PKCS7 *p7, BIO *in, BIO *out, int silent)
smime_extract_and_save_cert(p7);
- result = PKCS7_verify(p7, otherCerts, s_cert_store, in, out, 0);
-
+ flags = F_ON(F_USE_CERT_STORE_ONLY, ps_global) ? PKCS7_NOINTERN : 0;
+
+ if(ps_global->smime->publiccertlist == NULL){
+ renew_cert_data(&ps_global->smime->publiccertlist, Public);
+ for(cl = ps_global->smime->publiccertlist; cl ; cl = cl->next){
+ if(cl->x509_cert == NULL){
+ char *s = strrchr(cl->name, '.');
+ *s = '\0';
+ cl->x509_cert = get_cert_for(cl->name, Public);
+ *s = '.';
+ }
+ }
+ }
+
+ if(ps_global->smime->publiccertlist){
+ otherCerts = sk_X509_new_null();
+ for(cl = ps_global->smime->publiccertlist; cl ; cl = cl->next)
+ if(cl->x509_cert != NULL)
+ sk_X509_push(otherCerts, X509_dup(cl->x509_cert));
+ }
+
+ result = PKCS7_verify(p7, otherCerts, s_cert_store, in, out, flags);
+
+ sk_X509_pop_free(otherCerts, X509_free);
+
if(result){
q_status_message(SM_ORDER, 1, 1, _("S/MIME signature verified ok"));
}
@@ -2550,54 +2561,6 @@ free_smime_body_sparep(void **sparep)
}
}
-/* return the mime header for this body part. Memory freed by caller */
-char *
-smime_fetch_mime(BODY *b, MAILSTREAM *stream, long msgno, char * section,
- unsigned long *mimelen)
-{
- char *rv;
- char newSec[100];
-
- if(b->type == TYPEMULTIPART)
- snprintf(newSec, sizeof(newSec), "%s%s1", section ? section : "", (section && *section) ? "." : "");
- else
- strncpy(newSec, section, sizeof(newSec));
- newSec[sizeof(newSec)-1] = '\0';
- rv = mail_fetch_mime(stream, msgno, newSec, mimelen, 0);
- return rv ? cpystr(rv) : NULL;
-}
-
-
-void
-smime_write_body_header(BODY *b, MAILSTREAM *stream, long msgno, char *section, soutr_t f, void *s)
-{
- char *rv;
- char newSec[100];
-
- if(b->nested.part == NULL)
- return;
-
- if(b->nested.part->body.type == TYPEMULTIPART)
- snprintf(newSec, sizeof(newSec), "%s%s1", section ? section : "", (section && *section) ? "." : "");
- else
- strncpy(newSec, section, sizeof(newSec));
- newSec[sizeof(newSec)-1] = '\0';
- rv = mail_fetch_mime(stream, msgno, newSec, NULL, 0);
- if(f && rv != NULL)
- (*f)(s, rv);
-}
-
-int
-write_signed_body(BODY *b, MAILSTREAM *stream, long msgno, char *section, BIO *in)
-{
-
- smime_write_body_header(b, stream, msgno, section, rfc822_output_func, in);
-
-
-}
-
-
-
/* Big comment, explaining the mess that exists out there, and how we deal
with it, and also how we solve the problems that are created this way.
@@ -2664,19 +2627,30 @@ write_signed_body(BODY *b, MAILSTREAM *stream, long msgno, char *section, BIO *i
processed text. Nevertheless, at this time, this is automatic, and is
causing a delay in the processing of the message, but it is validating
correctly all messages.
+
+ PART IV
+
+ When the user sends a message as encrypted and signed, this code used to
+ encrypt first, and then sign the pkcs7 body, but it turns out that some
+ other clients can not handle these messages. While we could argue that the
+ other clients need to improve, we will support reading messages in both
+ ways, and will send messages using this technique; that is, signed first,
+ encrypted second. It seems that all tested clients support this way, so it
+ should be safe to do so.
*/
/*
* Given a multipart body of type multipart/signed, attempt to verify it.
* Returns non-zero if the body was changed.
*/
-int
+static int
do_detached_signature_verify(BODY *b, long msgno, char *section)
{
PKCS7 *p7 = NULL;
BIO *in = NULL;
PART *p;
int result, modified_the_body = 0;
+ int flag; /* 1 silent, 0 not silent */
unsigned long mimelen, bodylen;
char newSec[100], *mimetext, *bodytext;
char *what_we_did;
@@ -2693,7 +2667,7 @@ do_detached_signature_verify(BODY *b, long msgno, char *section)
if(get_smime_sparep_type(b->sparep) == SizedText){
/* bodytext includes mimetext */
st = (SIZEDTEXT *) get_smime_sparep_data(b->sparep);
- bodytext = st->data;
+ bodytext = (char *) st->data;
bodylen = st->size;
mimetext = NULL;
mimelen = 0L;
@@ -2724,7 +2698,9 @@ do_detached_signature_verify(BODY *b, long msgno, char *section)
* validates when we remove the last two characters. Silence
* any failures first.
*/
- if(((result = do_signature_verify(p7, in, NULL, 1)) == 0)
+ flag = (bodylen <= 2 || strncmp(bodytext+bodylen-2, "\r\n", 2))
+ ? 0 : 1;
+ if(((result = do_signature_verify(p7, in, NULL, flag)) == 0)
&& bodylen > 2
&& (strncmp(bodytext+bodylen-2,"\r\n", 2) == 0)){
BUF_MEM *biobuf = NULL;
@@ -2738,7 +2714,9 @@ do_detached_signature_verify(BODY *b, long msgno, char *section)
* information. In this case, we fetch the message and we process
* it by hand.
*/
- if((result = do_signature_verify(p7, in, NULL, 1)) == 0
+ flag = (mimelen == 0 || !IS_REMOTE(ps_global->mail_stream->mailbox))
+ ? 0 : 1;
+ if((result = do_signature_verify(p7, in, NULL, flag)) == 0
&& mimelen > 0 /* do not do this for encrypted messages */
&& IS_REMOTE(ps_global->mail_stream->mailbox)){
char *fetch;
@@ -2766,7 +2744,7 @@ do_detached_signature_verify(BODY *b, long msgno, char *section)
mail_free_envelope(&env);
mail_free_body_part(&b->nested.part);
- b->nested.part = body->nested.part;
+ b->nested.part = mail_body_section(body, section)->nested.part;
create_local_cache(bstart, bstart, &b->nested.part->body, 1);
modified_the_body = 1;
@@ -3086,11 +3064,15 @@ do_decoding(BODY *b, long msgno, const char *section)
char *cookie = NULL;
PARAMETER *param;
for (param = body->parameter; param && !cookie; param = param->next)
- if (!strucmp (param->attribute,"BOUNDARY")) cookie = param->value;
- st = fs_get(sizeof(SIZEDTEXT));
- st->data = (void *) cpystr(bstart + strlen(cookie)+4); /* 4 = strlen("--\r\n") */
- st->size = body->nested.part->next->body.mime.offset - 2*(strlen(cookie) + 4);
- body->sparep = create_smime_sparep(SizedText, (void *)st);
+ if (!strucmp (param->attribute,"BOUNDARY")) cookie = param->value;
+ if(cookie != NULL){
+ st = fs_get(sizeof(SIZEDTEXT));
+ st->data = (void *) cpystr(bstart + strlen(cookie)+4); /* 4 = strlen("--\r\n") */
+ st->size = body->nested.part->next->body.mime.offset - 2*(strlen(cookie) + 4);
+ body->sparep = create_smime_sparep(SizedText, (void *)st);
+ }
+ else
+ q_status_message(SM_ORDER, 3, 3, _("Couldn't find cookie in attachment list."));
}
body->mime.offset = 0;
body->mime.text.size = 0;
diff --git a/pith/smime.h b/pith/smime.h
index 8acaaa8e..a2d2c805 100644
--- a/pith/smime.h
+++ b/pith/smime.h
@@ -34,6 +34,14 @@
#define OUR_PKCS7_ENCLOSURE_SUBTYPE "x-pkcs7-enclosure"
+typedef enum {P7Type, CharType, SizedText} SpareType;
+
+typedef struct smime_sparep_t {
+ SpareType sptype;
+ void *data;
+} SMIME_SPARE_S;
+
+
/* exported protoypes */
int smime_validate_cert(X509 *cert, long *error);
int encrypt_file(char *fp, char *text, PERSONAL_CERT *pc);
@@ -73,6 +81,9 @@ void mark_cert_deleted(WhichCerts ctype, int num, unsigned state);
unsigned get_cert_deleted(WhichCerts ctype, int num);
int smime_expunge_cert(WhichCerts ctype);
int add_file_to_container(WhichCerts ctype, char *fpath, char *altname);
+void *create_smime_sparep(SpareType stype, void *s);
+SpareType get_smime_sparep_type(void *s);
+void *get_smime_sparep_data(void *s);
#endif /* PITH_SMIME_INCLUDED */
#endif /* SMIME */
diff --git a/pith/smkeys.c b/pith/smkeys.c
index 56103e91..23c9d21a 100644
--- a/pith/smkeys.c
+++ b/pith/smkeys.c
@@ -252,58 +252,6 @@ load_key(PERSONAL_CERT *pc, char *pass)
}
-#ifdef notdef
-static char *
-get_x509_name_entry(const char *key, X509_NAME *name)
-{
- int i, c, n;
- char buf[256];
- char *id;
-
- if(!name)
- return NULL;
-
- c = X509_NAME_entry_count(name);
-
- for(i=0; i<c; i++){
- X509_NAME_ENTRY *e;
-
- e = X509_NAME_get_entry(name, i);
- if(!e)
- continue;
-
- buf[0] = 0;
- id = buf;
-
- n = OBJ_obj2nid(e->object);
- if((n == NID_undef) || ((id=(char*) OBJ_nid2sn(n)) == NULL)){
- i2t_ASN1_OBJECT(buf, sizeof(buf), e->object);
- id = buf;
- }
-
- if((strucmp(id, "email")==0) || (strucmp(id, "emailAddress")==0)){
- X509_NAME_get_text_by_OBJ(name, e->object, buf, sizeof(buf)-1);
- return cpystr(buf);
- }
- }
-
- return NULL;
-}
-
-
-char *
-get_x509_subject_email(X509 *x)
-{
- char* result;
- result = get_x509_name_entry("email", X509_get_subject_name(x));
- if( !result ){
- result = get_x509_name_entry("emailAddress", X509_get_subject_name(x));
- }
-
- return result;
-}
-#endif /* notdef */
-
#include <openssl/x509v3.h>
/*
* This newer version is from Adrian Vogel. It looks for the email
@@ -392,7 +340,9 @@ save_cert_for(char *email, X509 *cert, WhichCerts ctype)
}
else if(SMHOLDERTYPE(ctype) == Container){
REMDATA_S *rd = NULL;
+ char *ret_dir = NULL;
char path[MAXPATH];
+ char fpath[MAXPATH];
char *upath = PATHCERTDIR(ctype);
char *tempfile = NULL;
int err = 0;
@@ -472,15 +422,26 @@ save_cert_for(char *email, X509 *cert, WhichCerts ctype)
path[sizeof(path)-1] = '\0';
}
- tempfile = tempfile_in_same_dir(path, "az", NULL);
+ tempfile = tempfile_in_same_dir(path, "az", &ret_dir);
if(tempfile){
if(certlist_to_file(tempfile, DATACERT(ctype)))
err++;
+ if(!err && ret_dir){
+ if(strlen(path) + strlen(tempfile) - strlen(ret_dir) + 1 < sizeof(path))
+ snprintf(fpath, sizeof(fpath), "%s%c%s",
+ path, tempfile[strlen(ret_dir)], tempfile + strlen(ret_dir) + 1);
+ else
+ err++;
+ }
+ else err++;
+
+ fs_give((void **)&ret_dir);
+
if(!err){
- if(rename_file(tempfile, path) < 0){
+ if(rename_file(tempfile, fpath) < 0){
q_status_message2(SM_ORDER, 3, 3,
- _("Can't rename %s to %s"), tempfile, path);
+ _("Can't rename %s to %s"), tempfile, fpath);
err++;
}
}
diff --git a/po/Makefile.in b/po/Makefile.in
index cc1c5abc..4b532b75 100644
--- a/po/Makefile.in
+++ b/po/Makefile.in
@@ -11,7 +11,7 @@
# Origin: gettext-0.16
PACKAGE = alpine
-VERSION = 2.19.991
+VERSION = 2.19.999
PACKAGE_BUGREPORT = chappa@washington.edu
SHELL = /bin/sh