Source-Changes-HG archive

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

[src/trunk]: src/usr.bin/ftp PR/47276: Add https support



details:   https://anonhg.NetBSD.org/src/rev/e2f92493619f
branches:  trunk
changeset: 783442:e2f92493619f
user:      christos <christos%NetBSD.org@localhost>
date:      Fri Dec 21 18:07:36 2012 +0000

description:
PR/47276: Add https support

diffstat:

 usr.bin/ftp/Makefile  |    8 +-
 usr.bin/ftp/fetch.c   |  123 +++++++--
 usr.bin/ftp/ftp_var.h |    6 +-
 usr.bin/ftp/main.c    |   10 +-
 usr.bin/ftp/ssl.c     |  604 ++++++++++++++++++++++++++++++++++++++++++++++++++
 usr.bin/ftp/ssl.h     |   62 +++++
 6 files changed, 773 insertions(+), 40 deletions(-)

diffs (truncated from 1113 to 300 lines):

diff -r 65b6cc92dc70 -r e2f92493619f usr.bin/ftp/Makefile
--- a/usr.bin/ftp/Makefile      Fri Dec 21 09:40:17 2012 +0000
+++ b/usr.bin/ftp/Makefile      Fri Dec 21 18:07:36 2012 +0000
@@ -1,4 +1,4 @@
-#      $NetBSD: Makefile,v 1.35 2011/08/14 12:58:15 christos Exp $
+#      $NetBSD: Makefile,v 1.36 2012/12/21 18:07:36 christos Exp $
 #      from: @(#)Makefile      8.2 (Berkeley) 4/3/94
 
 .include <bsd.own.mk>
@@ -18,6 +18,12 @@
 .else
 LDADD+=        -ledit -lterminfo
 DPADD+=        ${LIBEDIT} ${LIBTERMINFO}
+.if (${MKCRYPTO} != "no")
+CPPFLAGS+= -DWITH_SSL
+SRCS+=ssl.c
+LDADD+= -lssl -lcrypto
+DPADD+= ${LIBSSL} ${LIBCRYPTO}
+.endif
 .endif
 
 .if (!defined(SMALLPROG) || defined(SMALLPROG_INET6)) && (${USE_INET6} != "no")
diff -r 65b6cc92dc70 -r e2f92493619f usr.bin/ftp/fetch.c
--- a/usr.bin/ftp/fetch.c       Fri Dec 21 09:40:17 2012 +0000
+++ b/usr.bin/ftp/fetch.c       Fri Dec 21 18:07:36 2012 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: fetch.c,v 1.198 2012/07/04 06:09:37 is Exp $   */
+/*     $NetBSD: fetch.c,v 1.199 2012/12/21 18:07:36 christos Exp $     */
 
 /*-
  * Copyright (c) 1997-2009 The NetBSD Foundation, Inc.
@@ -34,7 +34,7 @@
 
 #include <sys/cdefs.h>
 #ifndef lint
-__RCSID("$NetBSD: fetch.c,v 1.198 2012/07/04 06:09:37 is Exp $");
+__RCSID("$NetBSD: fetch.c,v 1.199 2012/12/21 18:07:36 christos Exp $");
 #endif /* not lint */
 
 /*
@@ -64,12 +64,16 @@
 #include <unistd.h>
 #include <time.h>
 
+#include "ssl.h"
 #include "ftp_var.h"
 #include "version.h"
 
 typedef enum {
        UNKNOWN_URL_T=-1,
        HTTP_URL_T,
+#ifdef WITH_SSL
+       HTTPS_URL_T,
+#endif
        FTP_URL_T,
        FILE_URL_T,
        CLASSIC_URL_T
@@ -100,7 +104,15 @@
 #define        FILE_URL        "file://"       /* file URL prefix */
 #define        FTP_URL         "ftp://";        /* ftp URL prefix */
 #define        HTTP_URL        "http://";       /* http URL prefix */
+#ifdef WITH_SSL
+#define        HTTPS_URL       "https://";      /* https URL prefix */
 
+#define        IS_HTTP_TYPE(urltype) \
+       (((urltype) == HTTP_URL_T) || ((urltype) == HTTPS_URL_T))
+#else
+#define        IS_HTTP_TYPE(urltype) \
+       ((urltype) == HTTP_URL_T)
+#endif
 
 /*
  * Determine if token is the next word in buf (case insensitive).
@@ -346,6 +358,13 @@
        } else if (STRNEQUAL(url, FILE_URL)) {
                url += sizeof(FILE_URL) - 1;
                *utype = FILE_URL_T;
+#ifdef WITH_SSL
+       } else if (STRNEQUAL(url, HTTPS_URL)) {
+               url += sizeof(HTTPS_URL) - 1;
+               *utype = HTTPS_URL_T;
+               *portnum = HTTPS_PORT;
+               tport = httpsport;
+#endif
        } else {
                warnx("Invalid %s `%s'", desc, url);
  cleanup_parse_url:
@@ -498,17 +517,21 @@
        char                    *puser, *ppass, *useragent;
        off_t                   hashbytes, rangestart, rangeend, entitylen;
        int                     (*volatile closefunc)(FILE *);
-       FILE                    *volatile fin;
+       FETCH                   *volatile fin;
        FILE                    *volatile fout;
        time_t                  mtime;
        url_t                   urltype;
        in_port_t               portnum;
+#ifdef WITH_SSL
+       void                    *ssl;
+#endif
 
        DPRINTF("fetch_url: `%s' proxyenv `%s'\n", url, STRorNULL(proxyenv));
 
        oldintr = oldintp = NULL;
        closefunc = NULL;
-       fin = fout = NULL;
+       fin = NULL;
+       fout = NULL;
        s = -1;
        savefile = NULL;
        auth = location = message = NULL;
@@ -531,7 +554,7 @@
                        rval = fetch_ftp(url);
                        goto cleanup_fetch_url;
                }
-               if (urltype != HTTP_URL_T || outfile == NULL)  {
+               if (!IS_HTTP_TYPE(urltype) || outfile == NULL)  {
                        warnx("Invalid URL (no file after host) `%s'", url);
                        goto cleanup_fetch_url;
                }
@@ -571,17 +594,17 @@
        }
        if (urltype == FILE_URL_T) {            /* file:// URLs */
                direction = "copied";
-               fin = fopen(decodedpath, "r");
+               fin = fetch_open(decodedpath, "r");
                if (fin == NULL) {
                        warn("Can't open `%s'", decodedpath);
                        goto cleanup_fetch_url;
                }
-               if (fstat(fileno(fin), &sb) == 0) {
+               if (fstat(fetch_fileno(fin), &sb) == 0) {
                        mtime = sb.st_mtime;
                        filesize = sb.st_size;
                }
                if (restart_point) {
-                       if (lseek(fileno(fin), restart_point, SEEK_SET) < 0) {
+                       if (lseek(fetch_fileno(fin), restart_point, SEEK_SET) < 0) {
                                warn("Can't seek to restart `%s'",
                                    decodedpath);
                                goto cleanup_fetch_url;
@@ -594,12 +617,15 @@
                                    (LLT)restart_point);
                        fputs("\n", ttyout);
                }
+               if (0 == rcvbuf_size) {
+                       rcvbuf_size = 8 * 1024; /* XXX */
+               }
        } else {                                /* ftp:// or http:// URLs */
                const char *leading;
                int hasleading;
 
                if (proxyenv == NULL) {
-                       if (urltype == HTTP_URL_T)
+                       if (IS_HTTP_TYPE(urltype))
                                proxyenv = getoptionvalue("http_proxy");
                        else if (urltype == FTP_URL_T)
                                proxyenv = getoptionvalue("ftp_proxy");
@@ -660,7 +686,7 @@
                                    &ppath) == -1)
                                        goto cleanup_fetch_url;
 
-                               if ((purltype != HTTP_URL_T
+                               if ((!IS_HTTP_TYPE(purltype)
                                     && purltype != FTP_URL_T) ||
                                    EMPTYSTRING(phost) ||
                                    (! EMPTYSTRING(ppath)
@@ -690,6 +716,7 @@
                                FREEPTR(path);
                                path = ftp_strdup(url);
                                FREEPTR(ppath);
+                               urltype = purltype;
                        }
                } /* ! EMPTYSTRING(proxyenv) */
 
@@ -709,6 +736,9 @@
                        host = res0->ai_canonname;
 
                s = -1;
+#ifdef WITH_SSL
+               ssl = NULL;
+#endif
                for (res = res0; res; res = res->ai_next) {
                        char    hname[NI_MAXHOST], sname[NI_MAXSERV];
 
@@ -741,6 +771,16 @@
                                continue;
                        }
 
+#ifdef WITH_SSL
+                       if (urltype == HTTPS_URL_T) {
+                               if ((ssl = fetch_start_ssl(s)) == NULL) {
+                                       close(s);
+                                       s = -1;
+                                       continue;
+                               }
+                       }
+#endif
+
                        /* success */
                        break;
                }
@@ -750,7 +790,9 @@
                        goto cleanup_fetch_url;
                }
 
-               fin = fdopen(s, "r+");
+               fin = fetch_fdopen(s, "r+");
+               fetch_set_ssl(fin, ssl);
+
                /*
                 * Construct and send the request.
                 */
@@ -765,11 +807,11 @@
                                leading = ", ";
                                hasleading++;
                        }
-                       fprintf(fin, "GET %s HTTP/1.0\r\n", path);
+                       fetch_printf(fin, "GET %s HTTP/1.0\r\n", path);
                        if (flushcache)
-                               fprintf(fin, "Pragma: no-cache\r\n");
+                               fetch_printf(fin, "Pragma: no-cache\r\n");
                } else {
-                       fprintf(fin, "GET %s HTTP/1.1\r\n", path);
+                       fetch_printf(fin, "GET %s HTTP/1.1\r\n", path);
                        if (strchr(host, ':')) {
                                char *h, *p;
 
@@ -782,18 +824,23 @@
                                    (p = strchr(h, '%')) != NULL) {
                                        *p = '\0';
                                }
-                               fprintf(fin, "Host: [%s]", h);
+                               fetch_printf(fin, "Host: [%s]", h);
                                free(h);
                        } else
-                               fprintf(fin, "Host: %s", host);
+                               fetch_printf(fin, "Host: %s", host);
+#ifdef WITH_SSL
+                       if ((urltype == HTTP_URL_T && portnum != HTTP_PORT) ||
+                           (urltype == HTTPS_URL_T && portnum != HTTPS_PORT))
+#else
                        if (portnum != HTTP_PORT)
-                               fprintf(fin, ":%u", portnum);
-                       fprintf(fin, "\r\n");
-                       fprintf(fin, "Accept: */*\r\n");
-                       fprintf(fin, "Connection: close\r\n");
+#endif
+                               fetch_printf(fin, ":%u", portnum);
+                       fetch_printf(fin, "\r\n");
+                       fetch_printf(fin, "Accept: */*\r\n");
+                       fetch_printf(fin, "Connection: close\r\n");
                        if (restart_point) {
                                fputs(leading, ttyout);
-                               fprintf(fin, "Range: bytes=" LLF "-\r\n",
+                               fprintf(ttyout, "Range: bytes=" LLF "-\r\n",
                                    (LLT)restart_point);
                                fprintf(ttyout, "restarting at " LLF,
                                    (LLT)restart_point);
@@ -801,12 +848,12 @@
                                hasleading++;
                        }
                        if (flushcache)
-                               fprintf(fin, "Cache-Control: no-cache\r\n");
+                               fetch_printf(fin, "Cache-Control: no-cache\r\n");
                }
                if ((useragent=getenv("FTPUSERAGENT")) != NULL) {
-                       fprintf(fin, "User-Agent: %s\r\n", useragent);
+                       fetch_printf(fin, "User-Agent: %s\r\n", useragent);
                } else {
-                       fprintf(fin, "User-Agent: %s/%s\r\n",
+                       fetch_printf(fin, "User-Agent: %s/%s\r\n",
                            FTP_PRODUCT, FTP_VERSION);
                }
                if (wwwauth) {
@@ -816,7 +863,7 @@
                                leading = ", ";
                                hasleading++;
                        }
-                       fprintf(fin, "Authorization: %s\r\n", wwwauth);
+                       fetch_printf(fin, "Authorization: %s\r\n", wwwauth);
                }
                if (proxyauth) {
                        if (verbose) {
@@ -825,18 +872,18 @@
                                leading = ", ";
                                hasleading++;
                        }
-                       fprintf(fin, "Proxy-Authorization: %s\r\n", proxyauth);
+                       fetch_printf(fin, "Proxy-Authorization: %s\r\n", proxyauth);
                }
                if (verbose && hasleading)
                        fputs(")\n", ttyout);
-               fprintf(fin, "\r\n");
-               if (fflush(fin) == EOF) {
+               fetch_printf(fin, "\r\n");
+               if (fetch_flush(fin) == EOF) {
                        warn("Writing HTTP request");
                        goto cleanup_fetch_url;
                }



Home | Main Index | Thread Index | Old Index