[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Bug#797901: lynx: No client certificate support



-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA512

Package: lynx
Version: 2.8.9dev6-3
Tags: patch
Control: block -1 by 797059
X-Debbugs-CC: debian-accessibility@lists.debian.org

Dear Maintainer,

lynx has currently no support for client certificates, which, due to
the recent introduction of client certificate usage for Debian SSO,
renders websites protected by this system unusable for lynx users.

The attached patch adds the following features to lynx:

* Support for 1 client certificate and 1 key file
* Configurable via:
	- /etc/lynx-cur/lynx.cfg, variables SSL_CLIENT_CERT_FILE and
	  SSL_CLIENT_KEY_FILE
	- Environment variables: SSL_CLIENT_CERT_FILE and
	  SSL_CLIENT_KEY_FILE
	- Built-In Option Menu (Options "SSL client certificate
	  file","SSL client key file")


This patch was reviewed by a long time lynx user, trying out
http://contributors.debian.net.


Please note that you need to apply this patch [1] (Bug 797059 [2]) first.


Cheers,

Simon



[1]
https://bugs.debian.org/cgi-bin/bugreport.cgi?msg=15;att=1;filename=gnutls_add_rehandshake_support.diff;bug=797059

[2] https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=797059
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v2

iQIcBAEBCgAGBQJV6FB8AAoJEBy08PeN7K/pwPkQALdiJvKX+7hBz27dD8Uat/gF
+f8mopJegp6ezgTzPfZ9EPJT/UPoDLHu3HpAM/iSU1W33qVgfZQIed9gp8mcm87S
7f83ly0JkmyYa4niHWPTfZUIW2KvaeNyf1bsUN5iITKoARUPi/sOyrVayEXINYB0
IN5ZSgAJ/oBXDeHQCxcroO0mUrdQyUZil+oVwaZWzfxaNi8rccjzILg35ZQfUSdy
uyzkHElj4bj6GAD0VWOLVoiSPCjAuW5RMkFJzYz6ypCZTGXNT/L40bvoHaOojBe5
Mrp102tPOFIcQgCZO4AC8M+3M10qr2k/AgH1BvedNVlhZ7ACeJsbcHbiUZDogzYs
g3AwRBDrHZDTx5vu/2hKeOeekD3izwjmIEJcmdVgHZfkJPu7NubeJ2qIJcL0EfHO
T0eS8RSg1IBpdysCEQA9vXDzuNtL/qWoWjeAoJ388PfB6zHzR6M7b+KegI5WItba
L8xV/C3+4i0vPkp1Eca4VPEzPEyQB9dwC5pDNeByGngIaGhReZx+QCpAuIhuUD+W
yd/kmLt7cpL7IAOSDFJwL+tbLw+DgC3/bujAPhx4NAd8MOy2XN9GTGlkuBzSKmso
o8mqsE4oEjalbu/KQ7bIUWWaHbjwgG1UhwBxJahfbEgVfOgP3cBEQimpT65XYlkJ
rR/2KpZbFRl00tdiba5J
=bmnH
-----END PGP SIGNATURE-----
Description: Add client certificate support
 This feature is neccessary to enable lynx to use Debian SSO
 infrastructure, which now relies on client certificates.
 .
 Currently, client certificates and their corresponding key files
 must be in PEM format.
Author: Simon Kainz <skainz@debian.org>

---
Origin: other
Forwarded: no
Reviewed-By: Mario Lang <mlang@debian.org>
Last-Update: 2015-09-03

--- lynx-cur-2.8.9dev6.orig/WWW/Library/Implementation/HTTP.c
+++ lynx-cur-2.8.9dev6/WWW/Library/Implementation/HTTP.c
@@ -162,6 +162,9 @@ SSL *HTGetSSLHandle(void)
 {
 #ifdef USE_GNUTLS_INCL
     static char *certfile = NULL;
+    static char *client_keyfile = NULL;
+    static char *client_certfile = NULL;
+    
 #endif
 
     if (ssl_ctx == NULL) {
@@ -204,6 +207,9 @@ SSL *HTGetSSLHandle(void)
 	}
 #endif
 #ifdef USE_GNUTLS_INCL
+
+
+	
 	if ((certfile = LYGetEnv("SSL_CERT_FILE")) != NULL) {
 	    CTRACE((tfp,
 		    "HTGetSSLHandle: certfile is set to %s by SSL_CERT_FILE\n",
@@ -225,10 +231,40 @@ SSL *HTGetSSLHandle(void)
 	}
 #endif
 	atexit(free_ssl_ctx);
+
     }
 #ifdef USE_GNUTLS_INCL
+
+
+	 if (non_empty(SSL_client_key_file))
+	    {
+	    client_keyfile=SSL_client_key_file;
+		CTRACE((tfp,
+			"HTGetSSLHandle: client key file is set to %s by config SSL_CLIENT_KEY_FILE\n",
+			client_keyfile));
+	    }
+	
+	
+
+	 if (non_empty(SSL_client_cert_file))
+	    {
+	    client_certfile=SSL_client_cert_file;
+		CTRACE((tfp,
+			"HTGetSSLHandle: client cert file is set to %s by config SSL_CLIENT_CERT_FILE\n",
+			client_certfile));
+	    }
+	
+	
+
+
+    
     ssl_ctx->certfile = certfile;
     ssl_ctx->certfile_type = GNUTLS_X509_FMT_PEM;
+    ssl_ctx->client_keyfile = client_keyfile;
+    ssl_ctx->client_keyfile_type = GNUTLS_X509_FMT_PEM;
+    ssl_ctx->client_certfile = client_certfile;
+    ssl_ctx->client_certfile_type = GNUTLS_X509_FMT_PEM;
+
 #endif
     ssl_okay = 0;
     return (SSL_new(ssl_ctx));
--- lynx-cur-2.8.9dev6.orig/WWW/Library/Implementation/tidy_tls.h
+++ lynx-cur-2.8.9dev6/WWW/Library/Implementation/tidy_tls.h
@@ -78,6 +78,11 @@ typedef struct _SSL_CTX {
     int (*verify_callback) (int, X509_STORE_CTX *);
     int verify_mode;
 
+    char *client_certfile;
+    int client_certfile_type;
+    char *client_keyfile;
+    int client_keyfile_type;
+
 } SSL_CTX;
 
 struct _SSL {
--- lynx-cur-2.8.9dev6.orig/lynx.cfg
+++ lynx-cur-2.8.9dev6/lynx.cfg
@@ -3561,6 +3561,20 @@ NESTED_TABLES: false
 SSL_CERT_FILE:/etc/ssl/certs/ca-certificates.crt
 #SSL_CERT_FILE:NULL
 
+.h2 SSL_CLIENT_CERT_FILE
+# Set SSL_CLIENT_CERT_FILE to the file that contains a client certificate
+# (in PEM format) in case the $SSL_CLIENT_CERT_FILE environment variable is 
+# not set, e.g.,
+#
+#SSL_CLIENT_CERT_FILE:/home/qux/certs/cert.crt
+
+.h2 SSL_CLIENT_KEY_FILE
+# Set SSL_CLIENT_KEY_FILE to the file that contains a client certificate
+# key (in PEM format), in case the $SSL_CLIENT_KEY_FILE environment variable 
+# is not set, e.g.,
+#
+#SSL_CLIENT_KEY_FILE:/home/qux/certs/cert.key
+
 .h1 Appearance
 
 .h2 SCREEN_SIZE
--- lynx-cur-2.8.9dev6.orig/src/LYGlobalDefs.h
+++ lynx-cur-2.8.9dev6/src/LYGlobalDefs.h
@@ -536,6 +536,8 @@ extern "C" {
     extern int LYHiddenLinks;
 
     extern char *SSL_cert_file;	/* Default CA CERT file */
+    extern char *SSL_client_cert_file;	/* Default client CERT file */
+    extern char *SSL_client_key_file;	/* Default client key file */
 
     extern int Old_DTD;
 
--- lynx-cur-2.8.9dev6.orig/src/LYMain.c
+++ lynx-cur-2.8.9dev6/src/LYMain.c
@@ -553,7 +553,9 @@ char *XLoadImageCommand = NULL;	/* Defau
 BOOLEAN LYNoISMAPifUSEMAP = FALSE;	/* Omit ISMAP link if MAP present? */
 int LYHiddenLinks = HIDDENLINKS_SEPARATE;	/* Show hidden links? */
 
-char *SSL_cert_file = NULL;	/* Default CA CERT file */
+char *SSL_cert_file = NULL;	/*y Default CA CERT file */
+char *SSL_client_cert_file = NULL;
+char * SSL_client_key_file = NULL;
 
 int Old_DTD = NO;
 static BOOLEAN DTD_recovery = NO;
@@ -1579,6 +1581,27 @@ int main(int argc,
      */
     read_cfg(lynx_cfg_file, "main program", 1, (FILE *) 0);
 
+    static char *client_keyfile = NULL;
+    static char *client_certfile = NULL;
+
+        if ((client_keyfile = LYGetEnv("SSL_CLIENT_KEY_FILE")) != NULL) {
+            CTRACE((tfp,
+                    "HTGetSSLHandle: client keyfile is set to %s by SSL_CLIENT_KEY_FILE\n",
+                    client_keyfile));
+            StrAllocCopy(SSL_client_key_file,client_keyfile);
+ 
+        }
+ 
+        if ((client_certfile = LYGetEnv("SSL_CLIENT_CERT_FILE")) != NULL) {
+            CTRACE((tfp,
+                    "HTGetSSLHandle: client certfile is set to %s by SSL_CLIENT_CERT_FILE\n",
+                    client_certfile));
+            StrAllocCopy(SSL_client_cert_file,client_certfile);
+        }
+
+
+
+
 #if defined(USE_COLOR_STYLE)
     if (!dump_output_immediately) {
 	init_color_styles(&lynx_lss_file2, default_color_styles);
--- lynx-cur-2.8.9dev6.orig/src/LYOptions.c
+++ lynx-cur-2.8.9dev6/src/LYOptions.c
@@ -2444,6 +2444,9 @@ static const char *preferred_doc_lang_st
 static const char *send_user_agent_string = RC_SEND_USERAGENT;
 static const char *user_agent_string = RC_USERAGENT;
 
+static const char *ssl_client_certificate_file = RC_SSL_CLIENT_CERT_FILE;
+static const char *ssl_client_key_file = RC_SSL_CLIENT_KEY_FILE;
+
 #define PutHeader(fp, Name) \
 	fprintf(fp, "\n%s<em>%s</em>\n", MARGIN_STR, LYEntifyTitle(&buffer, Name));
 
@@ -3260,6 +3263,18 @@ int postoptions(DocInfo *newdoc)
 	    LYSendUserAgent = (BOOLEAN) !strcasecomp(data[i].value, "ON");
 	}
 
+	if (!strcmp(data[i].tag,ssl_client_certificate_file))
+	    {
+	    FREE(SSL_client_cert_file);
+	    StrAllocCopy(SSL_client_cert_file,data[i].value);
+	    }
+
+	if (!strcmp(data[i].tag,ssl_client_key_file))
+	    {
+	    FREE(SSL_client_key_file);
+	    StrAllocCopy(SSL_client_key_file,data[i].value);
+	    }
+
 	/* User Agent: INPUT */
 	if (!strcmp(data[i].tag, user_agent_string) && (!no_useragent)) {
 	    if (strcmp(LYUserAgent, data[i].value)) {
@@ -3729,6 +3744,15 @@ static int gen_options(char **newfile)
     BeginSelect(fp0, ssl_prompt_string);
     PutOptValues(fp0, ssl_noprompt, prompt_values);
     EndSelect(fp0);
+    
+    PutLabel(fp0, gettext("SSL client certificate file"), ssl_client_certificate_file);
+    PutTextInput(fp0, ssl_client_certificate_file,
+    NonNull(SSL_client_cert_file), text_len, "");
+
+    PutLabel(fp0, gettext("SSL client key file"), ssl_client_key_file);
+    PutTextInput(fp0, ssl_client_key_file,
+    NonNull(SSL_client_key_file), text_len, "");
+    
 #endif
 
     PutHeader(fp0, gettext("Keyboard Input"));
--- lynx-cur-2.8.9dev6.orig/src/LYReadCFG.c
+++ lynx-cur-2.8.9dev6/src/LYReadCFG.c
@@ -1719,6 +1719,8 @@ static Config_Type Config_Table [] =
      PARSE_ENU(RC_SOURCE_CACHE_FOR_ABORTED, LYCacheSourceForAborted, tbl_abort_source_cache),
 #endif
      PARSE_STR(RC_SSL_CERT_FILE,        SSL_cert_file),
+     PARSE_STR(RC_SSL_CLIENT_CERT_FILE,        SSL_client_cert_file),
+     PARSE_STR(RC_SSL_CLIENT_KEY_FILE,        SSL_client_key_file),
      PARSE_FUN(RC_STARTFILE,            startfile_fun),
      PARSE_FUN(RC_STATUS_BUFFER_SIZE,   status_buffer_size_fun),
      PARSE_SET(RC_STRIP_DOTDOT_URLS,    LYStripDotDotURLs),
--- lynx-cur-2.8.9dev6.orig/src/LYrcFile.h
+++ lynx-cur-2.8.9dev6/src/LYrcFile.h
@@ -234,6 +234,8 @@
 #define RC_SOURCE_CACHE                 "source_cache"
 #define RC_SOURCE_CACHE_FOR_ABORTED     "source_cache_for_aborted"
 #define RC_SSL_CERT_FILE                "ssl_cert_file"
+#define RC_SSL_CLIENT_CERT_FILE         "ssl_client_cert_file"
+#define RC_SSL_CLIENT_KEY_FILE          "ssl_client_key_file"
 #define RC_STARTFILE                    "startfile"
 #define RC_STATUS_BUFFER_SIZE           "status_buffer_size"
 #define RC_STRIP_DOTDOT_URLS            "strip_dotdot_urls"
--- lynx-cur-2.8.9dev6.orig/src/tidy_tls.c
+++ lynx-cur-2.8.9dev6/src/tidy_tls.c
@@ -549,11 +549,11 @@ SSL *SSL_new(SSL_CTX * ctx)
 		gnutls_certificate_set_x509_trust_file(ssl->gnutls_cred,
 						       ctx->certfile,
 						       ctx->certfile_type);
-	    if (ctx->keyfile)
+	    if (ctx->client_keyfile)
 		gnutls_certificate_set_x509_key_file(ssl->gnutls_cred,
-						     ctx->certfile,
-						     ctx->keyfile,
-						     ctx->keyfile_type);
+						     ctx->client_certfile,
+						     ctx->client_keyfile,
+						     ctx->client_keyfile_type);
 	    ssl->verify_mode = ctx->verify_mode;
 	    ssl->verify_callback = ctx->verify_callback;
 


Reply to: