On Fri, Sep 12, 2014 at 12:38:07AM -0700, Doug Hogan wrote:
> Hmm this doesn't look right to me.  ressl_config is not allocated the
> same way as the other variables.  The other variables such as ssl,
> sslhost, etc are local to that function and allocated there.
> ressl_config is a global and only allocated in main.c.  It is allocated
> once and configured using getopt/getsubopt().
> 
> If you free it, you would need to reallocate it each time or set it to
> NULL so libressl will revert back and discard the user's changes.
> I think either way is wrong.  The SSL configuration should be retained
> even if a single url_get() fails (which isn't fatal).
> 
> The above code is from url_get() which is called in a loop inside
> auto_fetch().  I think the above change would use the getsubopt()
> configuration for the first HTTPS URL argument and then try to use freed
> memory for the others.

Of course, you're right.  Is there any reason why ressl_config must be
global?  It's only used in url_get.  It should be harmless to create a
new one each time as long as we always free it.

Here's a diff for that:

Index: fetch.c
===================================================================
RCS file: /work/cvsroot/src/usr.bin/ftp/fetch.c,v
retrieving revision 1.129
diff -p -u -r1.129 fetch.c
--- fetch.c     25 Aug 2014 15:36:00 -0000      1.129
+++ fetch.c     12 Sep 2014 14:23:51 -0000
@@ -192,6 +192,7 @@ url_get(const char *origline, const char
        char *locbase, *full_host = NULL;
        const char *scheme;
        int ishttpurl = 0, ishttpsurl = 0;
+       struct ressl_config *ressl_config = NULL;
 #endif /* !SMALL */
        struct ressl *ssl = NULL;
        int status;
@@ -605,6 +606,26 @@ again:
                        fprintf(ttyout, "failed to create SSL client\n");
                        goto cleanup_url_get;
                }
+               if ((ressl_config = ressl_config_new()) == NULL) {
+                       fprintf(ttyout, "failed to create ReSSL config\n");
+                       goto cleanup_url_get;
+               }
+
+               if (ssl_cafile != NULL)
+                       ressl_config_set_ca_file(ressl_config, ssl_cafile);
+               if (ssl_capath != NULL)
+                       ressl_config_set_ca_path(ressl_config, ssl_capath);
+               if (ssl_ciphers != NULL)
+                       ressl_config_set_ciphers(ressl_config, ssl_ciphers);
+
+               if (ssl_verify)
+                       ressl_config_verify(ressl_config);
+               else
+                       ressl_config_insecure_no_verify(ressl_config);
+
+               if (ssl_verify_depth)
+                       ressl_config_set_verify_depth(ressl_config, 
ssl_verify_depth);
+
                if (ressl_configure(ssl, ressl_config) != 0) {
                        fprintf(ttyout, "SSL configuration failure: %s\n",
                            ressl_error(ssl));
@@ -978,6 +999,7 @@ cleanup_url_get:
 #ifndef SMALL
        if (ssl != NULL) {
                ressl_close(ssl);
+               ressl_config_free(ressl_config);
                ressl_free(ssl);
        }
        free(full_host);
Index: ftp_var.h
===================================================================
RCS file: /work/cvsroot/src/usr.bin/ftp/ftp_var.h,v
retrieving revision 1.35
diff -p -u -r1.35 ftp_var.h
--- ftp_var.h   14 Jul 2014 09:26:27 -0000      1.35
+++ ftp_var.h   12 Sep 2014 13:19:34 -0000
@@ -234,5 +234,9 @@ FILE        *ttyout;                /* stdout or stderr, 
depe
 extern struct cmd cmdtab[];
 
 #ifndef SMALL
-extern struct ressl_config *ressl_config;
+char   *ssl_cafile;
+char   *ssl_capath;
+char   *ssl_ciphers;
+int     ssl_verify;
+int     ssl_verify_depth;
 #endif /* !SMALL */
Index: main.c
===================================================================
RCS file: /work/cvsroot/src/usr.bin/ftp/main.c,v
retrieving revision 1.92
diff -p -u -r1.92 main.c
--- main.c      16 Jul 2014 04:52:43 -0000      1.92
+++ main.c      12 Sep 2014 13:38:02 -0000
@@ -76,8 +76,6 @@
 #include <string.h>
 #include <unistd.h>
 
-#include <ressl.h>
-
 #include "cmds.h"
 #include "ftp_var.h"
 
@@ -97,8 +95,6 @@ char * const ssl_verify_opts[] = {
        "depth",
        NULL
 };
-
-struct ressl_config *ressl_config;
 #endif /* !SMALL */
 
 int family = PF_UNSPEC;
@@ -309,12 +305,6 @@ main(volatile int argc, char *argv[])
 
                case 'S':
 #ifndef SMALL
-                       if (ressl_config == NULL) {
-                               ressl_config = ressl_config_new();
-                               if (ressl_config == NULL)
-                                       errx(1, "ressl config failed");
-                       }
-
                        cp = optarg;
                        while (*cp) {
                                char    *str;
@@ -322,28 +312,24 @@ main(volatile int argc, char *argv[])
                                case SSL_CAFILE:
                                        if (str == NULL)
                                                errx(1, "missing CA file");
-                                       ressl_config_set_ca_file(ressl_config,
-                                           str);
+                                       ssl_cafile = str;
                                        break;
                                case SSL_CAPATH:
                                        if (str == NULL)
                                                errx(1, "missing CA directory"
                                                    " path");
-                                       ressl_config_set_ca_path(ressl_config,
-                                           str);
+                                       ssl_capath = str;
                                        break;
                                case SSL_CIPHERS:
                                        if (str == NULL)
                                                errx(1, "missing cipher list");
-                                       ressl_config_set_ciphers(ressl_config,
-                                           str);
+                                       ssl_ciphers = str;
                                        break;
                                case SSL_DONTVERIFY:
-                                       ressl_config_insecure_no_verify(
-                                           ressl_config);
+                                       ssl_verify = 0;
                                        break;
                                case SSL_DOVERIFY:
-                                       ressl_config_verify(ressl_config);
+                                       ssl_verify = 1;
                                        break;
                                case SSL_VERIFYDEPTH:
                                        if (str == NULL)
@@ -354,8 +340,7 @@ main(volatile int argc, char *argv[])
                                                errx(1, "certificate "
                                                    "validation depth is %s",
                                                    errstr);
-                                       ressl_config_set_verify_depth(
-                                           ressl_config, (int)depth);
+                                       ssl_verify_depth = (int)depth;
                                        break;
                                default:
                                        errx(1, "unknown -S suboption `%s'",

Reply via email to