ftpd(8): Decouple from libmd.
authorzrj <rimvydas.jasinskas@gmail.com>
Wed, 17 Apr 2019 02:11:48 +0000 (05:11 +0300)
committerzrj <zrj@dragonflybsd.org>
Wed, 24 Apr 2019 17:18:10 +0000 (20:18 +0300)
Reimplement site command "md5" using LibreSSL MD5 API.

libexec/ftpd/Makefile
libexec/ftpd/extern.h
libexec/ftpd/ftpcmd.y
libexec/ftpd/site_md5.c [new file with mode: 0644]

index ca49712..d7cdcfd 100644 (file)
@@ -14,9 +14,6 @@ WFORMAT=0
 DPADD= ${LIBUTIL} ${LIBCRYPT}
 LDADD= -lutil -lcrypt
 
-DPADD+=        ${LIBMD}
-LDADD+=        -lmd
-
 LSDIR= ../../bin/ls
 .PATH: ${.CURDIR}/${LSDIR}
 SRCS+= ls.c cmp.c print.c util.c
@@ -24,9 +21,6 @@ CFLAGS+=-Dmain=ls_main -I${.CURDIR}/${LSDIR}
 DPADD+=        ${LIBM}
 LDADD+=        -lm
 
-# XXX sys/md5.h shim errata for bootstrap REMOVE_OPENSSL_FILES
-CFLAGS+= -I${_SHLIBDIRPREFIX}/usr/include/priv
-
 .if !defined(NO_INET6)
 CFLAGS+=-DINET6
 .endif
@@ -38,4 +32,14 @@ LDADD+= ${MINUSLPAM}
 LDFLAGS+= ${LDFLAGSPAM}
 .endif
 
+.if defined(NOMD5)
+CFLAGS+= -DNOMD5
+.else
+SRCS+= site_md5.c
+CFLAGS+=       ${PRIVATELIB_CFLAGS}
+DPADD+=                ${LIBCRYPTO}
+LDADD+=                -lprivate_crypto
+LDFLAGS+=      ${PRIVATELIB_LDFLAGS}
+.endif
+
 .include <bsd.prog.mk>
index f1e80ce..4d69429 100644 (file)
@@ -65,6 +65,9 @@ void  user(char *);
 void   yyerror(char *);
 int    yyparse(void);
 int    ls_main(int, char **);
+#ifndef NOMD5
+char *sitemd5(const char *, char * const);
+#endif
 
 struct sockaddr_in;
 struct sockaddr_in6;
index 944debb..f0a5dc1 100644 (file)
@@ -28,7 +28,6 @@
  *
  * @(#)ftpcmd.y        8.3 (Berkeley) 4/6/94
  * $FreeBSD: src/libexec/ftpd/ftpcmd.y,v 1.67 2008/12/23 01:23:09 cperciva Exp $
- * $DragonFly: src/libexec/ftpd/ftpcmd.y,v 1.4 2004/06/19 20:36:04 joerg Exp $
  */
 
 /*
@@ -50,7 +49,6 @@
 #include <glob.h>
 #include <libutil.h>
 #include <limits.h>
-#include <md5.h>
 #include <netdb.h>
 #include <pwd.h>
 #include <signal.h>
@@ -597,10 +595,11 @@ cmd
                }
        | SITE SP MDFIVE check_login SP pathname CRLF
                {
+#ifndef NOMD5
                        char p[64], *q;
 
                        if ($4 && $6) {
-                               q = MD5File($6, p);
+                               q = sitemd5($6, p);
                                if (q != NULL)
                                        reply(200, "MD5(%s) = %s", $6, p);
                                else
@@ -608,6 +607,9 @@ cmd
                        }
                        if ($6)
                                free($6);
+#else
+                       reply(202, "md5 command disabled.");
+#endif
                }
        | SITE SP UMASK check_login CRLF
                {
diff --git a/libexec/ftpd/site_md5.c b/libexec/ftpd/site_md5.c
new file mode 100644 (file)
index 0000000..15ea77b
--- /dev/null
@@ -0,0 +1,90 @@
+/*
+ * Copyright (c) 2019 The DragonFly 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * ``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
+ * COPYRIGHT HOLDERS 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.
+ */
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <openssl/md5.h>
+
+#include <stdio.h>             /* for FILE in extern.h */
+#include <netinet/in.h>                /* for struct sockaddr_in */
+#include "extern.h"
+
+char *
+sitemd5(const char *filename, char * const buf)
+{
+       unsigned char digest[MD5_DIGEST_LENGTH];
+       static const char hex[]="0123456789abcdef";
+       MD5_CTX ctx;
+       unsigned char buffer[4096];
+       struct stat st;
+       off_t size;
+       int fd, bytes, i, saved_errno;
+
+       if (!buf)
+               return NULL;
+
+       fd = open(filename, O_RDONLY);
+       if (fd < 0)
+               return NULL;
+       if (fstat(fd, &st) < 0) {
+               bytes = -1;
+               goto err;
+       }
+
+       MD5_Init(&ctx);
+       size = st.st_size;
+       bytes = 0;
+       while (size > 0) {
+               if ((size_t)size > sizeof(buffer))
+                       bytes = read(fd, buffer, sizeof(buffer));
+               else
+                       bytes = read(fd, buffer, size);
+               if (bytes < 0)
+                       break;
+               MD5_Update(&ctx, buffer, bytes);
+               size -= bytes;
+       }
+
+err:
+       saved_errno = errno;
+       close(fd);
+       errno = saved_errno;
+
+       if (bytes < 0)
+               return NULL;
+
+       MD5_Final(digest, &ctx);
+       for (i = 0; i < MD5_DIGEST_LENGTH; i++) {
+               buf[2*i] = hex[digest[i] >> 4];
+               buf[2*i+1] = hex[digest[i] & 0x0f];
+       }
+       buf[MD5_DIGEST_LENGTH * 2] = '\0';
+
+       return buf;
+}