From 59f9b53799063574462dae2a34ebf34a89bc8bbf Mon Sep 17 00:00:00 2001
From: "Eric S. Raymond" <esr@thyrsus.com>
Date: Sat, 3 Mar 2001 21:04:30 +0000
Subject: Added sslproto.

svn path=/trunk/; revision=3183
---
 NEWS          |  2 ++
 conf.c        |  1 +
 driver.c      |  2 +-
 fetchmail.c   |  1 +
 fetchmail.h   |  1 +
 fetchmail.man |  8 ++++++++
 fetchmailconf |  7 +++++--
 options.c     | 11 +++++++++--
 rcfile_l.l    |  1 +
 rcfile_y.y    |  3 ++-
 socket.c      | 18 ++++++++++++++++--
 11 files changed, 47 insertions(+), 8 deletions(-)

diff --git a/NEWS b/NEWS
index 3e734e10..a124ee6f 100644
--- a/NEWS
+++ b/NEWS
@@ -4,6 +4,8 @@
 
 * Restore ability to build with NLS.
 * FreeBSD port fixes.
+* Man page polished and updated.
+* Added --sslproto option from Peter Hedwig.
 
 ------------------------------------------------------------------------------
 fetchmail-5.7.0 (Thu Mar  1 18:00:08 EST 2001), 20131 lines:
diff --git a/conf.c b/conf.c
index b627daba..ac88c513 100644
--- a/conf.c
+++ b/conf.c
@@ -374,6 +374,7 @@ void dump_config(struct runctl *runp, struct query *querylist)
 	booldump("ssl", ctl->use_ssl);
 	stringdump("sslkey", ctl->sslkey);
 	stringdump("sslcert", ctl->sslcert);
+	stringdump("sslproto", ctl->sslproto);
 #endif /* SSL_ENABLE */
 	numdump("expunge", ctl->expunge);
 	stringdump("properties", ctl->properties);
diff --git a/driver.c b/driver.c
index 60e03ffe..1fbd992a 100644
--- a/driver.c
+++ b/driver.c
@@ -1769,7 +1769,7 @@ const int maxfetch;		/* maximum number of messages to fetch */
 	/* perform initial SSL handshake on open connection */
 	/* Note:  We pass the realhost name over for certificate
 		verification.  We may want to make this configurable */
-	if (ctl->use_ssl && SSLOpen(mailserver_socket,ctl->sslkey,ctl->sslcert,realhost) == -1) 
+	if (ctl->use_ssl && SSLOpen(mailserver_socket,ctl->sslkey,ctl->sslcert,ctl->sslproto,realhost) == -1) 
 	{
 	    report(stderr, _("SSL connection failed.\n"));
 	    goto closeUp;
diff --git a/fetchmail.c b/fetchmail.c
index 07a73b9a..ffe0ca23 100644
--- a/fetchmail.c
+++ b/fetchmail.c
@@ -916,6 +916,7 @@ static void optmerge(struct query *h2, struct query *h1, int force)
     FLAG_MERGE(use_ssl);
     FLAG_MERGE(sslkey);
     FLAG_MERGE(sslcert);
+    FLAG_MERGE(sslproto);
 #endif
     FLAG_MERGE(expunge);
 
diff --git a/fetchmail.h b/fetchmail.h
index a044473e..dff81d18 100644
--- a/fetchmail.h
+++ b/fetchmail.h
@@ -289,6 +289,7 @@ struct query
     flag use_ssl;		/* use SSL encrypted session */
     char *sslkey;		/* optional SSL private key file */
     char *sslcert;		/* optional SSL certificate file */
+	char *sslproto;		/* force usage of protocol (ssl2|ssl3|tls1) - defaults to ssl23 */
     char *properties;		/* passthrough properties for extensions */
 
     /* internal use -- per-poll state */
diff --git a/fetchmail.man b/fetchmail.man
index bf1239bf..8663c872 100644
--- a/fetchmail.man
+++ b/fetchmail.man
@@ -296,6 +296,11 @@ as the public key (combined key and certificate file) but this is not
 recommended.  If a password is required to unlock the key, it will be
 prompted for at the time just prior to establishing the session to the
 server.  This can cause some complications in daemon mode.
+.TP
+.B \--sslproto <name>
+(Keyword: sslproto)
+Forces an ssl protocol. Possible values are \&`\fBssl2\fR', `\fBssl3\fR' and
+`\fBtls1\fR'. Try this if the default handshake does not work for your server.
 .SS Delivery Control Options
 .TP
 .B \-S <hosts>, --smtphost <hosts>
@@ -1244,6 +1249,9 @@ T}
 sslkey    		T{
 Specify file for client side private SSL key
 T}
+sslproto   		T{
+Force ssl protocol for connection
+T}
 folder  	-r	T{
 Specify remote folder to query
 T}
diff --git a/fetchmailconf b/fetchmailconf
index b86f62d5..af436531 100755
--- a/fetchmailconf
+++ b/fetchmailconf
@@ -4,7 +4,7 @@
 # by Eric S. Raymond, <esr@snark.thyrsus.com>.
 # Requires Python with Tkinter, and the following OS-dependent services:
 #	posix, posixpath, socket
-version = "1.37"
+version = "1.38"
 
 from Tkinter import *
 from Dialog import *
@@ -237,6 +237,7 @@ class User:
         self.ssl = 0			# Enable Seccure Socket Layer
         self.sslkey = None		# SSL key filename
         self.sslcert = None		# SSL certificate filename
+        self.sslproto = None		# Force SSL?
         self.properties = None		# Extension properties
 	User.typemap = (
 	    ('remote',      'String'),
@@ -330,6 +331,8 @@ class User:
 	    res = res + " sslkey " + `self.sslkey`
 	if self.sslcert and self.sslcert != UserDefaults.sslcert:
 	    res = res + " sslcert " + `self.sslcert`
+        if self.sslproto and self.sslcert != UserDefaults.sslproto:
+            res = res + " sslproto " + `self.sslcert`
 	if self.expunge != UserDefaults.expunge:
 	    res = res + " expunge " + `self.expunge`
         res = res + "\n"
@@ -1791,7 +1794,7 @@ def copy_instance(toclass, fromdict):
 # present in the dictionary.
     optional = ('interface', 'monitor',
                 'netsec',
-                'ssl', 'sslkey', 'sslcert',
+                'ssl', 'sslkey', 'sslcert', 'sslproto',
                 'showdots')
     class_sig = setdiff(toclass.__dict__.keys(), optional)
     class_sig.sort()
diff --git a/options.c b/options.c
index 88366aae..a817e541 100644
--- a/options.c
+++ b/options.c
@@ -76,10 +76,11 @@
 #define LA_SSL		50
 #define LA_SSLKEY	51
 #define LA_SSLCERT	52
+#define LA_SSLPROTO 53
 #endif
 
-#define LA_SHOWDOTS	53
-#define LA_PRINCIPAL	54
+#define LA_SHOWDOTS	54
+#define LA_PRINCIPAL	55
 
 /* options still left: CDgGhHjJoORwWxXYz */
 static const char *shortoptions = 
@@ -146,6 +147,7 @@ static const struct option longoptions[] = {
   {"ssl",       no_argument,       (int *) 0, LA_SSL        },
   {"sslkey",    required_argument, (int *) 0, LA_SSLKEY     },
   {"sslcert",   required_argument, (int *) 0, LA_SSLCERT    },
+  {"sslproto",   required_argument, (int *) 0, LA_SSLPROTO    },
 #endif
 
   {"principal", required_argument, (int *) 0, LA_PRINCIPAL },
@@ -548,6 +550,10 @@ struct query *ctl;	/* option record to be initialized */
 	case LA_SSLCERT:
 	    ctl->sslcert = xstrdup(optarg);
 	    break;
+
+	case LA_SSLPROTO:
+	    ctl->sslproto = xstrdup(optarg);
+	    break;
 #endif
 
 	case LA_PRINCIPAL:
@@ -613,6 +619,7 @@ struct query *ctl;	/* option record to be initialized */
 	P(_("      --ssl         enable ssl encrypted session\n"));
 	P(_("      --sslkey      ssl private key file\n"));
 	P(_("      --sslcert     ssl client certificate\n"));
+	P(_("      --sslproto    force ssl protocol (ssl2/ssl3/tls1)\n"));
 #endif
 	P(_("      --plugin      specify external command to open connection\n"));
 	P(_("      --plugout     specify external command to open smtp connection\n"));
diff --git a/rcfile_l.l b/rcfile_l.l
index b2a76027..f4fc26c0 100644
--- a/rcfile_l.l
+++ b/rcfile_l.l
@@ -164,6 +164,7 @@ uidl		{ return UIDL; }
 ssl		{ return SSL; }
 sslkey		{ return SSLKEY; }
 sslcert		{ return SSLCERT; }
+sslproto	{ return SSLPROTO; }
 checkalias	{ return CHECKALIAS; }
 
 limit		{ return LIMIT; }
diff --git a/rcfile_y.y b/rcfile_y.y
index 92a4b11c..fd8194cf 100644
--- a/rcfile_y.y
+++ b/rcfile_y.y
@@ -73,7 +73,7 @@ extern char * yytext;
 %token NO KEEP FLUSH FETCHALL REWRITE FORCECR STRIPCR PASS8BITS 
 %token DROPSTATUS DROPDELIVERED
 %token DNS SERVICE PORT UIDL INTERVAL MIMEDECODE IDLE CHECKALIAS 
-%token SSL SSLKEY SSLCERT
+%token SSL SSLKEY SSLCERT SSLPROTO
 %token PRINCIPAL
 
 %%
@@ -330,6 +330,7 @@ user_option	: TO localnames HERE
 		| SSL 	                {current.use_ssl = FLAG_TRUE;}
 		| SSLKEY STRING		{current.sslkey = xstrdup($2);}
 		| SSLCERT STRING	{current.sslcert = xstrdup($2);}
+		| SSLPROTO STRING	{current.sslproto = xstrdup($2);}
 
 		| NO KEEP		{current.keep        = FLAG_FALSE;}
 		| NO FLUSH		{current.flush       = FLAG_FALSE;}
diff --git a/socket.c b/socket.c
index 7d1a78e2..67f6953f 100644
--- a/socket.c
+++ b/socket.c
@@ -753,7 +753,7 @@ int SSL_verify_callback( int ok_return, X509_STORE_CTX *ctx )
  * uses SSL *ssl global variable, which is currently defined
  * in this file
  */
-int SSLOpen(int sock, char *mycert, char *mykey, char *servercname )
+int SSLOpen(int sock, char *mycert, char *mykey, char *myproto, char *servercname )
 {
 	SSL_load_error_strings();
 	SSLeay_add_ssl_algorithms();
@@ -766,7 +766,21 @@ int SSLOpen(int sock, char *mycert, char *mykey, char *servercname )
 	if( ! _ctx ) {
 		/* Be picky and make sure the memory is cleared */
 		memset( _ssl_context, 0, sizeof( _ssl_context ) );
-		_ctx = SSL_CTX_new(SSLv23_client_method());
+		if(myproto) {
+			if(!strcmp("ssl2",myproto)) {
+				_ctx = SSL_CTX_new(SSLv2_client_method());
+			} else if(!strcmp("ssl3",myproto)) {
+				_ctx = SSL_CTX_new(SSLv3_client_method());
+			} else if(!strcmp("tls1",myproto)) {
+				_ctx = SSL_CTX_new(TLSv1_client_method());
+			} else {
+				fprintf(stderr,_("Invalid SSL protocol '%s' specified, using default (SSLv23).\n"), myproto);
+				myproto = NULL;
+			}
+		}
+		if(!myproto) {
+			_ctx = SSL_CTX_new(SSLv23_client_method());
+		}
 		if(_ctx == NULL) {
 			ERR_print_errors_fp(stderr);
 			return(-1);
-- 
cgit v1.2.3