summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEduardo Chappa <chappa@washington.edu>2017-12-01 23:10:00 -0700
committerEduardo Chappa <chappa@washington.edu>2017-12-01 23:10:00 -0700
commitf670e2888d23408d4386c6614a08b66ccef2992d (patch)
tree0b244498309d6ee8331a2069928088c46e573ff0
parent0ef0caf0d77164aa615fffa8aff4e82a3a540f0f (diff)
downloadalpine-f670e2888d23408d4386c6614a08b66ccef2992d.tar.xz
* PC-Alpine builds with LibreSSL and supports S/MIME.
-rw-r--r--alpine/libcrypto-41.dllbin0 -> 1384064 bytes
-rw-r--r--alpine/libssl-43.dllbin0 -> 294525 bytes
-rw-r--r--alpine/libtls-15.dllbin0 -> 69245 bytes
-rw-r--r--alpine/makefile.wnt5
-rw-r--r--build.bat48
-rw-r--r--include/config.wnt.h22
-rw-r--r--libressl/COPYING133
-rw-r--r--libressl/x86/libcrypto-41.libbin0 -> 784894 bytes
-rw-r--r--libressl/x86/libssl-43.libbin0 -> 62960 bytes
-rw-r--r--libressl/x86/libtls-15.libbin0 -> 20746 bytes
-rw-r--r--pith/pine.hlp41
-rw-r--r--pith/smime.c88
-rw-r--r--pith/smkeys.c197
13 files changed, 401 insertions, 133 deletions
diff --git a/alpine/libcrypto-41.dll b/alpine/libcrypto-41.dll
new file mode 100644
index 00000000..7c7f328f
--- /dev/null
+++ b/alpine/libcrypto-41.dll
Binary files differ
diff --git a/alpine/libssl-43.dll b/alpine/libssl-43.dll
new file mode 100644
index 00000000..369fe403
--- /dev/null
+++ b/alpine/libssl-43.dll
Binary files differ
diff --git a/alpine/libtls-15.dll b/alpine/libtls-15.dll
new file mode 100644
index 00000000..3dd9450c
--- /dev/null
+++ b/alpine/libtls-15.dll
Binary files differ
diff --git a/alpine/makefile.wnt b/alpine/makefile.wnt
index 268534e7..0344aaf5 100644
--- a/alpine/makefile.wnt
+++ b/alpine/makefile.wnt
@@ -35,7 +35,7 @@ LFLAGS= $(LDEBUG) $(EXTRALDFLAGS)
RCFLAGS =
STDLIBS=oldnames.lib kernel32.lib advapi32.lib ws2_32.lib user32.lib gdi32.lib \
- shell32.lib comdlg32.lib winmm.lib crypt32.lib
+ shell32.lib comdlg32.lib winmm.lib
SPELLLIBS=
LIBER=lib
@@ -55,7 +55,8 @@ OFILES= addrbook.obj adrbkcmd.obj after.obj alpine.obj arg.obj busy.obj colorcon
mailindx.obj mailpart.obj mailview.obj newmail.obj \
newuser.obj pattern.obj pipe.obj \
print.obj radio.obj remote.obj reply.obj roleconf.obj \
- send.obj setup.obj signal.obj status.obj takeaddr.obj titlebar.obj
+ send.obj setup.obj signal.obj smime.obj status.obj \
+ takeaddr.obj titlebar.obj
OURLIBS= ../c-client/cclient.lib osdep/libalpineosd.lib osdep/mswin.res \
../pith/osdep/libpithosd.lib ../pith/charconv/libpithcc.lib ../regex/libregex.lib ../pith/libpith.lib \
diff --git a/build.bat b/build.bat
index 30455fee..baab5e5b 100644
--- a/build.bat
+++ b/build.bat
@@ -31,6 +31,18 @@ goto fini
echo PC-Alpine for Windows/Winsock (Win32) build sequence
set cclntmake=makefile.nt
set alpinemake=makefile.wnt
+if not defined ALPINE_LIBRESSL set ALPINE_LIBRESSL=%cd%\libressl
+if exist "%ALPINE_LIBRESSL%" goto yeslibresslwnt
+echo NOT including LIBRESSL functionality
+set libresslflags=
+set libressllibes=
+set libresslextralibes="crypt32.lib"
+goto ldapincludewnt
+:yeslibresslwnt
+set libresslflags=-I\"%ALPINE_LIBRESSL%\"\include -DENABLE_WINDOWS_LIBRESSL -DLIBRESSL_INTERNAL
+set libressllibes=\"%ALPINE_LIBRESSL%\"\x86\libcrypto-41.lib \"%ALPINE_LIBRESSL%\"\x86\libssl-43.lib \"%ALPINE_LIBRESSL%\"\x86\libtls-15.lib
+set libresslextralibes=
+:ldapincludewnt
if not defined ALPINE_LDAP set ALPINE_LDAP=%cd%\ldap
if exist "%ALPINE_LDAP%" goto yesldapwnt
echo NOT including LDAP functionality
@@ -42,17 +54,29 @@ echo including LDAP functionality
set ldapflags=-I\"%ALPINE_LDAP%\"\inckit -DENABLE_LDAP
set ldaplibes=\"%ALPINE_LDAP%\"\binaries\release\ldap32.lib
:noldapwnt
-set extracflagsnq=/DWINVER=0x0501 /Zi -Od %ldapflags% -D_USE_32BIT_TIME_T -D_CRT_SECURE_NO_DEPRECATE -D_CRT_NONSTDC_NO_DEPRECATE -DSPCL_REMARKS=\"\\\"\\\"\"
-set extralibes=
-set extralibesalpine=%ldaplibes%
+set extracflagsnq=/DWINVER=0x0501 /Zi -Od %ldapflags% %libresslflags% -D_USE_32BIT_TIME_T -D_CRT_SECURE_NO_DEPRECATE -D_CRT_NONSTDC_NO_DEPRECATE -DSPCL_REMARKS=\"\\\"\\\"\"
+set extralibes="%libresslextralibes%"
+set extralibesalpine="%ldaplibes% %libressllibes%"
set extrarcflags="/D_PCP_WNT"
set extramakecommand=
goto buildsetup
:w2k
-echo Krb5ized PC-Pine for Windows/Winsock (Win32) build sequence
+echo Krb5ized PC-Alpine for Windows/Winsock (Win32) build sequence
set cclntmake=makefile.w2k
set alpinemake=makefile.wnt
+if not defined ALPINE_LIBRESSL set ALPINE_LIBRESSL=%cd%\libressl
+if exist "%ALPINE_LIBRESSL%" goto yeslibresslw2k
+echo NOT including LIBRESSL functionality
+set libresslflags=
+set libressllibes=
+set libresslextralibes="crypt32.lib"
+goto ldapincludew2k
+:yeslibresslw2k
+set libresslflags=-I\"%ALPINE_LIBRESSL%\"\include -DENABLE_WINDOWS_LIBRESSL -DLIBRESSL_INTERNAL
+set libressllibes=\"%ALPINE_LIBRESSL%\"\x86\libcrypto-41.lib \"%ALPINE_LIBRESSL%\"\x86\libssl-43.lib \"%ALPINE_LIBRESSL%\"\x86\libtls-15.lib
+set libresslextralibes=
+:ldapincludew2k
if not defined ALPINE_LDAP set ALPINE_LDAP=%cd%\ldap
if exist "%ALPINE_LDAP%" goto yesldapw2k
echo NOT including LDAP functionality
@@ -65,8 +89,8 @@ set ldapflags=-I\"%ALPINE_LDAP%\"\inckit -DENABLE_LDAP
set ldaplibes=\"%ALPINE_LDAP%\"\binaries\release\ldap32.lib
:noldapw2k
set extracflagsnq=/DWINVER=0x0501 /Zi -Od %ldapflags% -D_USE_32BIT_TIME_T -D_CRT_SECURE_NO_DEPRECATE -D_CRT_NONSTDC_NO_DEPRECATE -DSPCFC_WINVER=\"\\\" 2000\\\"\" -DSPCL_REMARKS=\"\\\" with krb5\\\"\"
-set extralibes="secur32.lib"
-set extralibesalpine="secur32.lib %ldaplibes%"
+set extralibes="secur32.lib %libresslextralibes%"
+set extralibesalpine="secur32.lib crypt32.lib %ldaplibes% %libressllibes%"
set extrarcflags="/D_PCP_W2K"
set extramakecommand=
goto buildsetup
@@ -115,11 +139,11 @@ copy /Y "%ALPINE_IMAP%"\src\c-client\* c-client\ > garbageout.txt
copy /Y "%ALPINE_IMAP%"\src\charset\* c-client\ > garbageout.txt
copy /Y "%ALPINE_IMAP%"\src\osdep\nt\* c-client\ > garbageout.txt
del garbageout.txt
-if not exist c-client-dll mkdir c-client-dll
-copy /Y "%ALPINE_IMAP%"\src\c-client\* c-client-dll\ > garbageout.txt
-copy /Y "%ALPINE_IMAP%"\src\charset\* c-client-dll\ > garbageout.txt
-copy /Y "%ALPINE_IMAP%"\src\osdep\nt\* c-client-dll\ > garbageout.txt
-del garbageout.txt
+rem if not exist c-client-dll mkdir c-client-dll
+rem copy /Y "%ALPINE_IMAP%"\src\c-client\* c-client-dll\ > garbageout.txt
+rem copy /Y "%ALPINE_IMAP%"\src\charset\* c-client-dll\ > garbageout.txt
+rem copy /Y "%ALPINE_IMAP%"\src\osdep\nt\* c-client-dll\ > garbageout.txt
+rem del garbageout.txt
if not exist mailutil mkdir mailutil
copy /Y "%ALPINE_IMAP%"\src\mailutil\* mailutil\ > garbageout.txt
del garbageout.txt
@@ -213,7 +237,7 @@ cd alpine
nmake -nologo -f %alpinemake% wnt=1 EXTRACFLAGS=%extracflags% EXTRALDFLAGS=%extraldflags% EXTRALIBES=%extralibesalpine% EXTRARCFLAGS=%extrarcflags% %extramakecommand%
if errorlevel 1 goto bogus
cd ..
-goto buildcclntdll
+goto nobuildmapi
:buildcclntdll
if NOT exist c-client-dll goto buildmapi
diff --git a/include/config.wnt.h b/include/config.wnt.h
index d73b2b87..9c4a13fd 100644
--- a/include/config.wnt.h
+++ b/include/config.wnt.h
@@ -531,6 +531,28 @@
/* File name separator as string constant */
#define S_FILESEP "\\"
+/* Enable S/MIME if LibreSSL */
+#ifdef ENABLE_WINDOWS_LIBRESSL
+#define SMIME
+/* Default configuration value */
+#define DF_PRIVATEKEY_DIR "alpine-smime\\private"
+
+/* Default configuration value */
+#define DF_PUBLICCERT_DIR "alpine-smime\\public"
+
+/* Name of default public container */
+#define DF_CACERT_DIR "alpine-smime\\ca"
+
+/* Name of default public container */
+#define DF_PUBLIC_CONTAINER "PublicContainer"
+
+/* Name of default private container */
+#define DF_PRIVATE_CONTAINER "PrivateContainer"
+
+/* Name of default certificate authority container */
+#define DF_CA_CONTAINER "CAContainer"
+#endif /* ENABLE_WINDOWS_LIBRESSL */
+
/* Define to 1 if you can safely include both <sys/time.h> and <time.h>. */
/* #define TIME_WITH_SYS_TIME */
diff --git a/libressl/COPYING b/libressl/COPYING
new file mode 100644
index 00000000..892e14a4
--- /dev/null
+++ b/libressl/COPYING
@@ -0,0 +1,133 @@
+
+ LibReSSL files are retained under the copyright of the authors. New
+ additions are ISC licensed as per OpenBSD's normal licensing policy,
+ or are placed in the public domain.
+
+ The OpenSSL code is distributed under the terms of the original OpenSSL
+ licenses which follow:
+
+ LICENSE ISSUES
+ ==============
+
+ The OpenSSL toolkit stays under a dual license, i.e. both the conditions of
+ the OpenSSL License and the original SSLeay license apply to the toolkit.
+ See below for the actual license texts. In case of any license issues
+ related to OpenSSL please contact openssl-core@openssl.org.
+
+ OpenSSL License
+ ---------------
+
+/* ====================================================================
+ * Copyright (c) 1998-2011 The OpenSSL Project. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ * software must display the following acknowledgment:
+ * "This product includes software developed by the OpenSSL Project
+ * for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ * endorse or promote products derived from this software without
+ * prior written permission. For written permission, please contact
+ * openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ * nor may "OpenSSL" appear in their names without prior written
+ * permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ * acknowledgment:
+ * "This product includes software developed by the OpenSSL Project
+ * for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com). This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+ Original SSLeay License
+ -----------------------
+
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ *
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to. The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code. The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ *
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * "This product includes cryptographic software written by
+ * Eric Young (eay@cryptsoft.com)"
+ * The word 'cryptographic' can be left out if the rouines from the library
+ * being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from
+ * the apps directory (application code) you must include an acknowledgement:
+ * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed. i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
diff --git a/libressl/x86/libcrypto-41.lib b/libressl/x86/libcrypto-41.lib
new file mode 100644
index 00000000..b85bfdfa
--- /dev/null
+++ b/libressl/x86/libcrypto-41.lib
Binary files differ
diff --git a/libressl/x86/libssl-43.lib b/libressl/x86/libssl-43.lib
new file mode 100644
index 00000000..e1c673bc
--- /dev/null
+++ b/libressl/x86/libssl-43.lib
Binary files differ
diff --git a/libressl/x86/libtls-15.lib b/libressl/x86/libtls-15.lib
new file mode 100644
index 00000000..216745dd
--- /dev/null
+++ b/libressl/x86/libtls-15.lib
Binary files differ
diff --git a/pith/pine.hlp b/pith/pine.hlp
index 547cb10d..4589e741 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 233 2017-11-22 11:29:36
+Alpine Commit 234 2017-12-01 23:09:54
============= h_news =================
<HTML>
<HEAD>
@@ -180,6 +180,8 @@ addresses bugs found in previous releases and has a few additions as well.
Additions include:
<UL>
+<LI> PC-Alpine builds with LibreSSL and supports S/MIME.
+
<LI> NTLM authentication support with the ntlm library, in Unix systems.
Based on code provided by Maciej W. Rozycki.
@@ -34940,14 +34942,16 @@ message to you and on how the list works.)
S/MIME is a standard for the public key encryption and signing of email.
UNIX Alpine contains a basic implementation of S/MIME based on
-the <A HREF="http://www.openssl.org/">OpenSSL</A> libraries.
+the <A HREF="http://www.openssl.org/">OpenSSL</A> libraries. The
+same support can be provided using the
+<A HREF="http://www.libressl.org/">LibreSSL</A> libraries. The
+support for S/MIME in PC-Alpine is fully based on the LibreSSL libraries.
To check if this version of Alpine supports S/MIME look at
<A HREF="X-Alpine-Config:">Supported Options in this Alpine</A> and look
for &quot;S/MIME&quot; under the &quot;Encryption&quot; heading.
<P>
Some limitations:
<UL>
- <LI> There is no PC-Alpine implementation.
<LI> There is no provision for checking for CRLs
(Certificate Revocation Lists) in Alpine.
<LI> This built-in S/MIME implementation is not compatible with and does not help with PGP.
@@ -34997,6 +35001,10 @@ The directory name is
<P>
<CENTER><SAMP>.alpine-smime</SAMP></CENTER>
<P>
+For PC-Alpine, the equivalent directory is called
+<CENTER><SAMP>alpine-smime</SAMP></CENTER>
+and is also located under your home directory.
+<P>
Within that directory are three subdirectories.
Each of the three subdirectories contains files with PEM-encoded contents,
the default format for OpenSSL.
@@ -35105,7 +35113,6 @@ as soon as you import them.
<BODY>
<H1>S/MIME OPTION: <!--#echo var="VAR_smime-public-cert-directory"--></H1>
-UNIX Alpine only.
<P>
If the option
<A HREF="h_config_smime_pubcertcon"><!--#echo var="VAR_smime-public-cert-container"--></A>
@@ -35164,7 +35171,6 @@ D6sOwOLJZkLY8FRsfk63K+2EMzA2+qAzMKupgeTLqXIf
<BODY>
<H1>OPTION: <!--#echo var="VAR_smime-public-cert-container"--></H1>
-UNIX Alpine only.
<P>
If this option is set it will be used instead of
<A HREF="h_config_smime_pubcertdir"><!--#echo var="VAR_smime-public-cert-directory"--></A>.
@@ -35202,7 +35208,6 @@ Use the Setup/SMIME screen to modify this variable.
<BODY>
<H1>OPTION: <!--#echo var="VAR_smime-private-key-directory"--></H1>
-UNIX Alpine only.
<P>
In order to sign outgoing S/MIME messages you will need a
personal digital ID certificate.
@@ -35269,7 +35274,6 @@ m+4TJybNGNfAgOctSkEyY/OCb49fRRQTCBZVIhzLGGmpYmkO55HbIA==
<BODY>
<H1>OPTION: <!--#echo var="VAR_smime-private-key-container"--></H1>
-UNIX Alpine only.
<P>
If this option is set it will be used instead of
<A HREF="h_config_smime_privkeydir"><!--#echo var="VAR_smime-private-key-directory"--></A>.
@@ -35307,7 +35311,6 @@ Use the Setup/SMIME screen to modify this variable.
<BODY>
<H1>S/MIME OPTION: <!--#echo var="VAR_smime-cacert-directory"--></H1>
-UNIX Alpine only.
<P>
If the option
<A HREF="h_config_smime_cacertcon"><!--#echo var="VAR_smime-cacert-container"--></A>
@@ -35349,7 +35352,6 @@ certificates for particular email addresses
<BODY>
<H1>S/MIME OPTION: <!--#echo var="VAR_smime-cacert-container"--></H1>
-UNIX Alpine only.
<P>
If this option is set it will be used instead of
<A HREF="h_config_smime_cacertdir"><!--#echo var="VAR_smime-cacert-directory"--></A>.
@@ -35387,7 +35389,6 @@ Use the Setup/SMIME screen to modify this variable.
<BODY>
<H1>S/MIME FEATURE: <!--#echo var="FEAT_smime-sign-by-default"--></H1>
-UNIX Alpine only.
<P>
This feature only has an effect if your version of Alpine includes
support for S/MIME.
@@ -35418,7 +35419,6 @@ certificate).
<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.
@@ -35464,7 +35464,6 @@ might not trust those that came with the message that you are validating.
<BODY>
<H1>S/MIME FEATURE: <!--#echo var="FEAT_publiccerts-in-keychain"--></H1>
-UNIX Alpine only.
<P>
If this feature is set the Mac OS X default keychain will be used as the place
to store public certificates instead of a
@@ -35490,7 +35489,6 @@ or a
<BODY>
<H1>S/MIME FEATURE: <!--#echo var="FEAT_smime-dont-do-smime"--></H1>
-UNIX Alpine only.
<P>
Setting this feature turns off all of Alpine's S/MIME support.
You might want to set this if you are having trouble due to the S/MIME support.
@@ -35514,7 +35512,6 @@ You might want to set this if you are having trouble due to the S/MIME support.
<BODY>
<H1>S/MIME FEATURE: <!--#echo var="FEAT_smime-encrypt-by-default"--></H1>
-UNIX Alpine only.
<P>
This feature only has an effect if your version of Alpine includes
support for S/MIME.
@@ -35545,7 +35542,6 @@ for the recipient).
<BODY>
<H1>S/MIME FEATURE: <!--#echo var="FEAT_smime-remember-passphrase"--></H1>
-UNIX Alpine only.
<P>
This feature only has an effect if your version of Alpine includes
support for S/MIME.
@@ -35571,7 +35567,6 @@ once during an Alpine session.
<BODY>
<H1>S/MIME: Transfer Public Certs to Container</H1>
-UNIX Alpine only.
<P>
The Transfer command will copy the public certificates in your configured
<A HREF="h_config_smime_pubcertdir"><!--#echo var="VAR_smime-public-cert-directory"--></A>
@@ -35600,7 +35595,6 @@ Warning: Any previous contents in the container will be lost.
<BODY>
<H1>S/MIME: Transfer Public Certs to Directory</H1>
-UNIX Alpine only.
<P>
The Transfer command will copy the public certificates in your configured
<A HREF="h_config_smime_pubcertcon"><!--#echo var="VAR_smime-public-cert-container"--></A>
@@ -35627,7 +35621,6 @@ directory.
<BODY>
<H1>S/MIME: Transfer Private Keys to Container</H1>
-UNIX Alpine only.
<P>
The Transfer command will copy the private keys in your configured
<A HREF="h_config_smime_privkeydir"><!--#echo var="VAR_smime-private-key-directory"--></A>.
@@ -35656,7 +35649,6 @@ Warning: Any previous contents in the container will be lost.
<BODY>
<H1>S/MIME: Transfer Private Keys to Directory</H1>
-UNIX Alpine only.
<P>
The Transfer command will copy the private keys in your configured
<A HREF="h_config_smime_privkeydir"><!--#echo var="VAR_smime-private-key-container"--></A>.
@@ -35683,7 +35675,6 @@ directory.
<BODY>
<H1>S/MIME: Transfer CA Certs to Container</H1>
-UNIX Alpine only.
<P>
The Transfer command will copy the CA certificates in your configured
<A HREF="h_config_smime_cacertdir"><!--#echo var="VAR_smime-cacert-directory"--></A>
@@ -35712,7 +35703,6 @@ Warning: Any previous contents in the container will be lost.
<BODY>
<H1>S/MIME: Transfer CA Certs to Directory</H1>
-UNIX Alpine only.
<P>
The Transfer command will copy the CA certificates in your configured
<A HREF="h_config_smime_cacertcon"><!--#echo var="VAR_smime-cacert-container"--></A>.
@@ -35767,7 +35757,6 @@ feature
<BODY>
<H1>S/MIME: Transfer Public Certs to Keychain</H1>
-UNIX Alpine only.
<P>
The Transfer command will copy the public certificates in your configured
<A HREF="h_config_smime_pubcertcon"><!--#echo var="VAR_smime-public-cert-container"--></A>
@@ -35793,7 +35782,6 @@ the Keychain to store your public certs.
<BODY>
<H1>S/MIME: Manage Public Certificates</H1>
-UNIX Alpine only.
<P>
This menu item allows you to manage your public certificates, this
may include your own public certificate, but it normally includes
@@ -35832,7 +35820,6 @@ import a command to this collection.
<BODY>
<H1>S/MIME: Manage Private Keys</H1>
-UNIX Alpine only.
<P>
This option allows you to manage your private key. Normally a person has only
one key, in the same way that a person only has one valid passport, or ID card,
@@ -35869,7 +35856,6 @@ import a command to this collection.
<BODY>
<H1>S/MIME: Manage Certificate Authorities</H1>
-UNIX Alpine only.
<P>
This collection contains certificates that are needed to validate the
certificate of another person, and therefore contains certificates that
@@ -35900,7 +35886,6 @@ import a command to this collection.
<BODY>
<H1>S/MIME: Manage Password File Certificates</H1>
-UNIX Alpine only.
<P>
This option allows you to manage the certificates that are used to
encrypt and decrypt your password file. This is useful in case you
@@ -35973,7 +35958,6 @@ Be safe and keep your password file encrypted with a password.
<BODY>
<H1>S/MIME: Certificate Information Screen</H1>
-UNIX Alpine only.
<P>
The CERTIFICATE INFORMATION screen shows you information contained in a certificate
such as its owner, e-mail address, issuer, and interval of validity,
@@ -36010,7 +35994,6 @@ and private information about your key, with the <B>B</B> and
<BODY>
<H1>S/MIME: Commands that Manage Public Certificates</H1>
-UNIX Alpine only.
<P>
This screen allows you to manage your public certificates.
<P>
@@ -36061,7 +36044,6 @@ All commands provide feedback to let you know about their success or failure.
<BODY>
<H1>S/MIME: Commands that Manage Private Keys</H1>
-UNIX Alpine only.
<P>
This screen allows you to manage your private key.
<P>
@@ -36108,7 +36090,6 @@ All commands provide feedback to let you know about their success or failure.
<BODY>
<H1>S/MIME: Commands that Manage Certificate Authorities</H1>
-UNIX Alpine only.
<P>
This screen allows you to manage your collection of certificates that you
trust.
diff --git a/pith/smime.c b/pith/smime.c
index 90aa8321..78596b3b 100644
--- a/pith/smime.c
+++ b/pith/smime.c
@@ -120,6 +120,11 @@ get_smime_sparep_data(void *s)
#ifdef PASSFILE
/*
+ * This code does not work in Windows, because of the PASSFILE thing, so
+ * I did not try to fix it. If you think it does need to be applied to
+ * the Windows version of alpine, there are more changes that are needed
+ * than fixing this function in this module. E. Chappa 09/28/17.
+ *
* load key from pathkeydir and cert from pathcertdir. It chooses the first
* key/certificate pair that matches. Delete pairs that you do not want used,
* if you do not want them selected. All parameters must be non-null.
@@ -312,11 +317,11 @@ setup_pwdcert(void **pwdcert)
if((t = strstr(s+strlen(tmp), EMAILADDRLEADER)) != NULL){
c = *t;
*t = '\0';
- pc->keytext = cpystr(s + strlen(tmp) + 1); /* 1 = strlen("\n") */
+ pc->keytext = cpystr(s + strlen(tmp) + strlen(NEWLINE));
*t = c;
}
else
- pc->keytext = cpystr(s + strlen(tmp) + 1); /* 1 = strlen("\n") */
+ pc->keytext = cpystr(s + strlen(tmp) + strlen(NEWLINE));
}
}
}
@@ -1309,21 +1314,38 @@ PERSONAL_CERT *
get_personal_certs(char *path)
{
PERSONAL_CERT *result = NULL;
- char buf2[MAXPATH];
+ char buf2[MAXPATH], *fname;
+ X509 *cert;
+ size_t ll;
+#ifndef _WINDOWS
struct dirent *d;
DIR *dirp;
+#else /* _WINDOWS */
+ struct _finddata_t dbuf;
+ char buf[_MAX_PATH + 4];
+ long findrv;
+#endif /* _WINDOWS */
ps_global->smime->privatepath = cpystr(path);
+
+#ifndef _WINDOWS
dirp = opendir(path);
if(dirp){
while((d=readdir(dirp)) != NULL){
- X509 *cert;
- size_t ll;
-
- if((ll=strlen(d->d_name)) && ll > 4 && !strcmp(d->d_name+ll-4, ".key")){
+ fname = d->d_name;
+#else /* _WINDOWS */
+ snprintf(buf, sizeof(buf), "%s%s*.*", path, (path[strlen(path)-1] == '\\') ? "" : "\\");
+ buf[sizeof(buf)-1] = '\0';
+ if((findrv = _findfirst(buf, &dbuf)) < 0)
+ return(NULL);
+
+ do {
+ fname = fname_to_utf8(dbuf.name);
+#endif
+ if((ll=strlen(fname)) && ll > 4 && !strcmp(fname+ll-4, ".key")){
/* copy file name to temp buffer */
- strncpy(buf2, d->d_name, sizeof(buf2)-1);
+ strncpy(buf2, fname, sizeof(buf2)-1);
buf2[sizeof(buf2)-1] = '\0';
/* chop off ".key" trailier */
buf2[strlen(buf2)-4] = '\0';
@@ -1348,9 +1370,14 @@ get_personal_certs(char *path)
result = pc;
}
}
+#ifndef _WINDOWS
}
closedir(dirp);
}
+#else /* _WINDOWS */
+ } while(_findnext(findrv, &dbuf) == 0);
+ _findclose(findrv);
+#endif /* !_WINDOWS */
return result;
}
@@ -1637,17 +1664,20 @@ add_file_to_container(WhichCerts ctype, char *fpath, char *altname)
goto endadd;
if(content){
- fs_resize((void **)&content, strlen(content) + strlen(sep) + strlen(name) + sbuf.st_size + 3); /* 2 = \n + \n + \0*/
+ fs_resize((void **)&content, strlen(content) + strlen(sep) + strlen(name) + sbuf.st_size + 2*strlen(NEWLINE) + 1); /* 1 = \0*/
s = content;
content += strlen(content);
}
else{
- s = content = fs_get(strlen(sep) + strlen(name) + sbuf.st_size + 1); /* 2 = \n + \0 */
+ s = content = fs_get(strlen(sep) + strlen(name) + sbuf.st_size + strlen(NEWLINE) + 1); /* 1 = \0 */
*content = '\0';
}
strncat(content, sep, strlen(sep));
strncat(content, name, strlen(name));
content += strlen(content);
+#ifdef _WINDOWS
+ *content++ = '\r';
+#endif /* _WINDOWS */
*content++ = '\n';
while(so_readc(&c, in))
@@ -1683,9 +1713,16 @@ copy_dir_to_container(WhichCerts which, char *contents)
int ret = 0, container = 0;
BIO *bio_out = NULL, *bio_in = NULL;
char srcpath[MAXPATH+1], dstpath[MAXPATH+1], emailaddr[MAXPATH], file[MAXPATH], line[4096];
- char *tempfile = NULL, fpath[MAXPATH+1];
+ char *tempfile = NULL, fpath[MAXPATH+1], *fname;
+ size_t ll;
+#ifndef _WINDOWS
DIR *dirp;
struct dirent *d;
+#else /* _WINDOWS */
+ struct _finddata_t dbuf;
+ char buf[_MAX_PATH + 4];
+ long findrv;
+#endif /* _WINDOWS */
REMDATA_S *rd = NULL;
char *configdir = NULL;
char *configpath = NULL;
@@ -1827,15 +1864,24 @@ copy_dir_to_container(WhichCerts which, char *contents)
ret = -1;
}
else {
+#ifndef _WINDOWS
if((dirp = opendir(srcpath)) != NULL){
while((d=readdir(dirp)) && !ret){
- size_t ll;
-
- if((ll=strlen(d->d_name)) && ll > 4 && !strcmp(d->d_name+ll-4, filesuffix)){
+ fname = d->d_name;
+#else /* _WINDOWS */
+ snprintf(buf, sizeof(buf), "%s%s*.*", srcpath, (srcpath[strlen(srcpath)-1] == '\\') ? "" : "\\");
+ buf[sizeof(buf)-1] = '\0';
+ if((findrv = _findfirst(buf, &dbuf)) < 0)
+ return -1;
+
+ do{
+ fname = fname_to_utf8(dbuf.name);
+#endif /* ! _WINDOWS */
+ if((ll=strlen(fname)) && ll > 4 && !strcmp(fname+ll-4, filesuffix)){
/* copy file name to temp buffer */
- strncpy(emailaddr, d->d_name, sizeof(emailaddr)-1);
+ strncpy(emailaddr, fname, sizeof(emailaddr)-1);
emailaddr[sizeof(emailaddr)-1] = '\0';
/* chop off suffix trailier */
emailaddr[strlen(emailaddr)-4] = 0;
@@ -1847,18 +1893,18 @@ copy_dir_to_container(WhichCerts which, char *contents)
if(which == CACert){
if(!((BIO_puts(bio_out, CACERTSTORELEADER) > 0)
&& (BIO_puts(bio_out, emailaddr) > 0)
- && (BIO_puts(bio_out, "\n") > 0)))
+ && (BIO_puts(bio_out, NEWLINE) > 0)))
ret = -1;
}
else{
if(!((BIO_puts(bio_out, EMAILADDRLEADER) > 0)
&& (BIO_puts(bio_out, emailaddr) > 0)
- && (BIO_puts(bio_out, "\n") > 0)))
+ && (BIO_puts(bio_out, NEWLINE) > 0)))
ret = -1;
}
/* read then write contents of file */
- build_path(file, srcpath, d->d_name, sizeof(file));
+ build_path(file, srcpath, fname, sizeof(file));
if(!(bio_in = BIO_new_file(file, "r")))
ret = -1;
@@ -1879,10 +1925,14 @@ copy_dir_to_container(WhichCerts which, char *contents)
BIO_free(bio_in);
}
+#ifndef _WINDOWS
}
-
closedir(dirp);
}
+#else /* _WINDOWS */
+ } while (_findnext(findrv, &dbuf) == 0);
+ _findclose(findrv);
+#endif /* ! _WINDOWS */
}
BIO_free(bio_out);
diff --git a/pith/smkeys.c b/pith/smkeys.c
index 9fde7b08..2f849244 100644
--- a/pith/smkeys.c
+++ b/pith/smkeys.c
@@ -297,13 +297,19 @@ setup_certs_backup_by_type(WhichCerts ctype)
int rv = 0; /* assume success */
int len;
int i, done;
- char *d;
+ char *d, *fname;
char p[MAXPATH+1]; /* path to where the backup is */
char buf[MAXPATH+1], buf2[MAXPATH+1];
struct stat sbuf;
CertList *data, *cl;
+#ifndef _WINDOWS
DIR *dirp;
struct dirent *df; /* file in the directory */
+#else /* _WINDOWS */
+ struct _finddata_t dbuf;
+ char bufn[_MAX_PATH + 4];
+ long findrv;
+#endif /* !_WINDOWS */
CertList *cert, *cl2;
X509 *x;
BIO *in;
@@ -407,64 +413,76 @@ setup_certs_backup_by_type(WhichCerts ctype)
/* Here is the plan: read the backup directory (in the variable "p")
* and attempt to add it. If already there, skip it; otherwise continue
*/
+#ifndef _WINDOWS
+ if ((dirp = opendir(p)) != NULL) {
+ while ((df = readdir(dirp)) != NULL) {
+ fname = df->d_name;
+
+ if (fname && *fname == '.') /* no hidden files here */
+ continue;
+#else
+ snprintf(bufn, sizeof(bufn), "%s%s*.*", p, (p[strlen(p) - 1] == '\\') ? "" : "\\");
+ bufn[sizeof(bufn) - 1] = '\0';
+ if ((findrv = _findfirst(bufn, &dbuf)) >= 0) {
+ do {
+ fname = fname_to_utf8(dbuf.name);
+#endif /* ! _WINDOWS */
+ /* make sure that we have a file */
+ snprintf(buf2, sizeof(buf2), "%s%s%s", p, S_FILESEP, fname);
+ buf2[sizeof(buf2) - 1] = '\0';
+ if (our_stat(buf2, &sbuf) == 0
+ && (sbuf.st_mode & S_IFMT) != S_IFREG)
+ continue;
+
+ /* make sure it is not already in the list */
+ for (cl = data; cl; cl = cl->next)
+ if (strcmp(cl->name, fname) == 0)
+ break;
+ if (cl != NULL)
+ continue;
+
+ /* ok, if it is not in the list, and it is a certificate. Add it */
+ switch (ctype) {
+ case Public:
+ case CACert:
+ if ((in = BIO_new_file(buf2, "r")) != 0) {
+ x = PEM_read_bio_X509(in, NULL, NULL, NULL);
+ if (x) { /* for now copy this information */
+ cert = smime_X509_to_cert_info(x, fname);
+ /* we will use the cert->data.md5 variable to find a backup
+ certificate, not the name */
+ cert->next = data;
+ data = cert;
+ }
+ BIO_free(in);
+ }
+ break;
- if((dirp = opendir(p)) != NULL){
- while((df=readdir(dirp)) != NULL){
- if(df->d_name && *df->d_name == '.') /* no hidden files here */
- continue;
-
- /* make sure that we have a file */
- snprintf(buf2, sizeof(buf2), "%s%s%s", p, S_FILESEP, df->d_name);
- buf2[sizeof(buf2)-1] = '\0';
- if(our_stat(buf2, &sbuf) == 0
- && (sbuf.st_mode & S_IFMT) != S_IFREG)
- continue;
-
- /* make sure it is not already in the list */
- for(cl = data; cl; cl = cl->next)
- if(strcmp(cl->name, df->d_name) == 0)
- break;
- if(cl != NULL)
- continue;
-
- /* ok, if it is not in the list, and it is a certificate. Add it */
- switch(ctype){
- case Public:
- case CACert:
- if((in = BIO_new_file(buf2, "r"))!=0){
- x = PEM_read_bio_X509(in, NULL, NULL, NULL);
- if(x){ /* for now copy this information */
- cert = smime_X509_to_cert_info(x, df->d_name);
- /* we will use the cert->data.md5 variable to find a backup
- certificate, not the name */
- cert->next = data;
- data = cert;
- }
- BIO_free(in);
- }
- break;
-
- case Private:
- /* here we must check it is a key of some cert....*/
- break;
-
- default: alpine_panic("Bad ctype (1)");
- } /* end switch */
- }
- closedir(dirp);
- }
+ case Private:
+ /* here we must check it is a key of some cert....*/
+ break;
+ default: alpine_panic("Bad ctype (1)");
+ } /* end switch */
+#ifndef _WINDOWS
+ }
+ closedir(dirp);
+#else /* _WINDOWS */
+ } while (_findnext(findrv, &dbuf) == 0);
+ _findclose(findrv);
+#endif /* ! _WINDOWS */
+ }
/* Now that we are here, we have all the information in the backup
* directory
*/
- switch(ctype){
- case Public : ps_global->smime->backuppubliccertlist = data; break;
- case Private: ps_global->smime->backupprivatecertlist = data; break;
- case CACert : ps_global->smime->backupcacertlist = data; break;
- default : alpine_panic("Bad ctype (n)");
+ switch (ctype) {
+ case Public: ps_global->smime->backuppubliccertlist = data; break;
+ case Private: ps_global->smime->backupprivatecertlist = data; break;
+ case CACert: ps_global->smime->backupcacertlist = data; break;
+ default: alpine_panic("Bad ctype (n)");
+ }
}
- }
} else if(SMHOLDERTYPE(ctype) == Container){
} /* else APPLEKEYCHAIN */
@@ -669,17 +687,32 @@ smime_get_date(const ASN1_TIME *tm)
int
add_certs_in_dir(X509_LOOKUP *lookup, char *path, char *ext, CertList **cdata)
{
- char buf[MAXPATH];
+ char buf[MAXPATH], *fname;
+#ifndef _WINDOWS
struct direct *d;
- DIR *dirp;
+ DIR *dirp;
+#else /* _WINDOWS */
+ struct _finddata_t dbuf;
+ char bufn[_MAX_PATH + 4];
+ long findrv;
+#endif /* !_WINDOWS */
CertList *cert, *cl;
int ret = 0, nfiles = 0, nerr = 0;
+#ifndef _WINDOWS
if((dirp = opendir(path)) != NULL){
- while(!ret && (d=readdir(dirp)) != NULL){
- if(srchrstr(d->d_name, ext)){
- nfiles++;
- build_path(buf, path, d->d_name, sizeof(buf));
+ while(!ret && (d=readdir(dirp)) != NULL){
+ fname = d->d_name;
+#else /* _WINDOWS */
+ snprintf(bufn, sizeof(bufn), "%s%s*.*", path, (path[strlen(path)-1] == '\\') ? "" : "\\");
+ bufn[sizeof(bufn)-1] = '\0';
+ if((findrv = _findfirst(bufn, &dbuf)) >= 0){
+ do{
+ fname = fname_to_utf8(dbuf.name);
+#endif /* ! _WINDOWS */
+ if(srchrstr(fname, ext)){
+ nfiles++;
+ build_path(buf, path, fname, sizeof(buf));
if(!X509_LOOKUP_load_file(lookup, buf, X509_FILETYPE_PEM)){
q_status_message1(SM_ORDER, 3, 3, _("Error loading file %s"), buf);
@@ -691,7 +724,7 @@ add_certs_in_dir(X509_LOOKUP *lookup, char *path, char *ext, CertList **cdata)
cert = fs_get(sizeof(CertList));
memset((void *)cert, 0, sizeof(CertList));
- cert->name = cpystr(d->d_name);
+ cert->name = cpystr(fname);
/* read buf into a bio and fill the CertData structure */
if((in = BIO_new_file(buf, "r"))!=0){
if((x = PEM_read_bio_X509(in, NULL, NULL, NULL)) != NULL){
@@ -715,9 +748,13 @@ add_certs_in_dir(X509_LOOKUP *lookup, char *path, char *ext, CertList **cdata)
}
}
- }
-
- closedir(dirp);
+#ifndef _WINDOWS
+ }
+ closedir(dirp);
+#else /* _WINDOWS */
+ } while(_findnext(findrv, &dbuf) == 0);
+ _findclose(findrv);
+#endif /* ! _WINDOWS */
}
/* if all certificates fail to load */
@@ -1210,7 +1247,7 @@ get_cert_for(char *email, WhichCerts ctype, int tolower)
build_path(certfilename, PATHCERTDIR(ctype), emailaddr, sizeof(certfilename));
strncat(certfilename, EXTCERT(ctype), sizeof(certfilename)-1-strlen(certfilename));
certfilename[sizeof(certfilename)-1] = 0;
-
+
if((in = BIO_new_file(certfilename, "r"))!=0){
cert = PEM_read_bio_X509(in, NULL, NULL, NULL);
@@ -1221,6 +1258,7 @@ get_cert_for(char *email, WhichCerts ctype, int tolower)
BIO_free(in);
}
+
}
return cert;
@@ -1236,26 +1274,40 @@ get_cert_for(char *email, WhichCerts ctype, int tolower)
int
load_cert_for_key(char *pathdir, EVP_PKEY *pkey, char **certfile, X509 **pcert)
{
+#ifndef _WINDOWS
DIR *dirp;
struct dirent *d;
+#else /* _WINDOWS */
+ struct _finddata_t dbuf;
+ char bufn[_MAX_PATH + 4];
+ long findrv;
+#endif /* ! _WINDOWS */
+ size_t ll;
int rv = 0;
BIO *in;
X509 *x;
- char buf[MAXPATH+1], pathcert[MAXPATH+1];
+ char buf[MAXPATH+1], pathcert[MAXPATH+1], *fname;
if(pathdir == NULL || pkey == NULL)
return 0;
if(certfile) *certfile = NULL;
if(pcert) *pcert = NULL;
-
+
+#ifndef _WINDOWS
if((dirp = opendir(pathdir)) != NULL){
while(rv == 0 && (d=readdir(dirp)) != NULL){
- size_t ll;
-
- if((ll=strlen(d->d_name)) && ll > 4){
- if(!strcmp(d->d_name+ll-4, ".crt")){
- strncpy(buf, d->d_name, sizeof(buf));
+ fname = d->d_name;
+#else
+ snprintf(bufn, sizeof(bufn), "%s%s*.*", pathdir, (pathdir[strlen(pathdir)-1] == '\\') ? "" : "\\");
+ bufn[sizeof(bufn)-1] = '\0';
+ if((findrv = _findfirst(bufn, &dbuf)) >= 0){
+ do{
+ fname = fname_to_utf8(dbuf.name);
+#endif /* ! _WINDOWS */
+ if((ll=strlen(fname)) && ll > 4){
+ if(!strcmp(fname+ll-4, ".crt")){
+ strncpy(buf, fname, sizeof(buf));
buf[sizeof(buf)-1] = '\0';
build_path(pathcert, pathdir, buf, sizeof(pathcert));
if((in = BIO_new_file(pathcert, "r")) != NULL){
@@ -1272,8 +1324,13 @@ load_cert_for_key(char *pathdir, EVP_PKEY *pkey, char **certfile, X509 **pcert)
}
}
}
+#ifndef _WINDOWS
}
closedir(dirp);
+#else /* _WINDOWS */
+ } while(_findnext(findrv, &dbuf) == 0);
+ _findclose(findrv);
+#endif
}
return rv;
}