Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/libexec/ftpd dual-stack ftpd. run this from inetd, like:
details: https://anonhg.NetBSD.org/src/rev/0c15e2577c0a
branches: trunk
changeset: 474240:0c15e2577c0a
user: itojun <itojun%NetBSD.org@localhost>
date: Fri Jul 02 05:52:14 1999 +0000
description:
dual-stack ftpd. run this from inetd, like:
>>ftp stream tcp6 nowait root /usr/libexec/ftpd ftpd -ll
diffstat:
libexec/ftpd/Makefile | 3 +-
libexec/ftpd/extern.h | 51 ++++++-
libexec/ftpd/ftpcmd.y | 235 ++++++++++++++++++++++++++++-
libexec/ftpd/ftpd.8 | 18 ++-
libexec/ftpd/ftpd.c | 392 +++++++++++++++++++++++++++++++++++++++++--------
5 files changed, 617 insertions(+), 82 deletions(-)
diffs (truncated from 1075 to 300 lines):
diff -r b83bbc0e1cba -r 0c15e2577c0a libexec/ftpd/Makefile
--- a/libexec/ftpd/Makefile Fri Jul 02 05:41:45 1999 +0000
+++ b/libexec/ftpd/Makefile Fri Jul 02 05:52:14 1999 +0000
@@ -1,4 +1,4 @@
-# $NetBSD: Makefile,v 1.32 1999/06/26 20:01:55 danw Exp $
+# $NetBSD: Makefile,v 1.33 1999/07/02 05:52:14 itojun Exp $
# @(#)Makefile 8.2 (Berkeley) 4/4/94
PROG= ftpd
@@ -13,6 +13,7 @@
SRCS+= ls.c cmp.c print.c stat_flags.c util.c
.PATH: ${.CURDIR}/../../bin/ls
+CPPFLAGS+=-DINET6
.include <bsd.own.mk>
.ifdef SKEY
diff -r b83bbc0e1cba -r 0c15e2577c0a libexec/ftpd/extern.h
--- a/libexec/ftpd/extern.h Fri Jul 02 05:41:45 1999 +0000
+++ b/libexec/ftpd/extern.h Fri Jul 02 05:52:14 1999 +0000
@@ -1,4 +1,33 @@
-/* $NetBSD: extern.h,v 1.18 1999/05/24 21:54:42 ross Exp $ */
+/* $NetBSD: extern.h,v 1.19 1999/07/02 05:52:14 itojun Exp $ */
+
+/*
+ * Copyright (C) 1997 and 1998 WIDE 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.
+ * 3. Neither the name of the project nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE PROJECT 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 PROJECT 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.
+ */
/*-
* Copyright (c) 1992, 1993
@@ -54,6 +83,7 @@
void parse_conf __P((char *));
void pass __P((const char *));
void passive __P((void));
+void long_passive __P((char *, int));
void perror_reply __P((int, const char *));
void pwd __P((void));
void removedir __P((const char *));
@@ -98,16 +128,31 @@
mode_t umask; /* Umask to use */
};
+#include <netinet/in.h>
+
+union sockunion {
+ struct sockinet {
+ u_char si_len;
+ u_char si_family;
+ u_short si_port;
+ } su_si;
+ struct sockaddr_in su_sin;
+ struct sockaddr_in6 su_sin6;
+};
+#define su_len su_si.si_len
+#define su_family su_si.si_family
+#define su_port su_si.si_port
+
extern int yyparse __P((void));
extern char cbuf[];
extern struct ftpclass curclass;
-extern struct sockaddr_in data_dest;
+extern union sockunion data_dest;
extern int debug;
extern int form;
extern int guest;
extern int hasyyerrored;
-extern struct sockaddr_in his_addr;
+extern union sockunion his_addr;
extern char hostname[];
#ifdef KERBEROS5
extern krb5_context kcontext;
diff -r b83bbc0e1cba -r 0c15e2577c0a libexec/ftpd/ftpcmd.y
--- a/libexec/ftpd/ftpcmd.y Fri Jul 02 05:41:45 1999 +0000
+++ b/libexec/ftpd/ftpcmd.y Fri Jul 02 05:52:14 1999 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: ftpcmd.y,v 1.31 1999/05/26 13:30:10 lukem Exp $ */
+/* $NetBSD: ftpcmd.y,v 1.32 1999/07/02 05:52:14 itojun Exp $ */
/*
* Copyright (c) 1985, 1988, 1993, 1994
@@ -47,7 +47,7 @@
#if 0
static char sccsid[] = "@(#)ftpcmd.y 8.3 (Berkeley) 4/6/94";
#else
-__RCSID("$NetBSD: ftpcmd.y,v 1.31 1999/05/26 13:30:10 lukem Exp $");
+__RCSID("$NetBSD: ftpcmd.y,v 1.32 1999/07/02 05:52:14 itojun Exp $");
#endif
#endif /* not lint */
@@ -72,6 +72,7 @@
#include <time.h>
#include <tzfile.h>
#include <unistd.h>
+#include <netdb.h>
#ifdef KERBEROS5
#include <krb5.h>
@@ -100,6 +101,7 @@
%token
A B C E F I
L N P R S T
+ ALL
SP CRLF COMMA
@@ -117,6 +119,8 @@
SIZE MDTM
+ LPRT LPSV EPRT EPSV
+
MAIL MLFL MRCP MRSQ MSAM MSND
MSOM
@@ -125,6 +129,7 @@
LEXERR
%token <s> STRING
+%token <s> ALL
%token <i> NUMBER
%type <i> check_login check_modify octal_number byte_size
@@ -218,11 +223,14 @@
if ($2) {
/* be paranoid, if told so */
if (curclass.checkportcmd &&
- ((ntohs(data_dest.sin_port) < IPPORT_RESERVED) ||
- memcmp(&data_dest.sin_addr, &his_addr.sin_addr,
- sizeof(data_dest.sin_addr)) != 0)) {
+ ((ntohs(data_dest.su_port) < IPPORT_RESERVED) ||
+ memcmp(&data_dest.su_sin.sin_addr,
+ &his_addr.su_sin.sin_addr,
+ sizeof(data_dest.su_sin.sin_addr)) != 0)) {
reply(500,
"Illegal PORT command rejected");
+ } else if (epsvall) {
+ reply(501, "PORT disallowed after EPSV ALL");
} else {
usedefault = 0;
if (pdata >= 0) {
@@ -231,9 +239,142 @@
}
reply(200, "PORT command successful.");
}
+
}
}
+ | LPRT check_login SP host_long_port CRLF
+ {
+ /* be paranoid, if told so */
+ if (curclass.checkportcmd &&
+ ((ntohs(data_dest.su_port) <
+ IPPORT_RESERVED) ||
+ memcmp(&data_dest.su_sin6.sin6_addr,
+ &his_addr.su_sin6.sin6_addr,
+ sizeof(data_dest.su_sin6.sin6_addr)) != 0)) {
+ reply(500, "Illegal LPRT command rejected");
+ return (NULL);
+ }
+ if (epsvall)
+ reply(501, "LPRT disallowed after EPSV ALL");
+ else {
+ usedefault = 0;
+ if (pdata >= 0) {
+ (void) close(pdata);
+ pdata = -1;
+ }
+ reply(200, "LPRT command successful.");
+ }
+ }
+
+ | EPRT check_login SP STRING CRLF
+ {
+ char *tmp = NULL;
+ char *result[3];
+ char *p, *q;
+ char delim;
+ struct addrinfo hints;
+ struct addrinfo *res;
+ int i;
+
+ if (epsvall) {
+ reply(501, "EPRT disallowed after EPSV ALL");
+ goto eprt_done;
+ }
+ usedefault = 0;
+ if (pdata >= 0) {
+ (void) close(pdata);
+ pdata = -1;
+ }
+
+ /*XXX checks for login */
+
+ tmp = strdup($4);
+ if (!tmp) {
+ fatal("not enough core.");
+ /*NOTREACHED*/
+ }
+ p = tmp;
+ delim = p[0];
+ p++;
+ memset(result, 0, sizeof(result));
+ for (i = 0; i < 3; i++) {
+ q = strchr(p, delim);
+ if (!q || *q != delim) {
+ parsefail:
+ reply(500, "Invalid argument, rejected.");
+ if (tmp)
+ free(tmp);
+ usedefault = 1;
+ goto eprt_done;
+ }
+ *q++ = '\0';
+ result[i] = p;
+ p = q;
+ }
+
+ /* some more sanity check */
+ p = result[0];
+ while (*p) {
+ if (!isdigit(*p))
+ goto parsefail;
+ p++;
+ }
+ p = result[2];
+ while (*p) {
+ if (!isdigit(*p))
+ goto parsefail;
+ p++;
+ }
+
+ memset(&hints, 0, sizeof(hints));
+ if (atoi(result[0]) == 1)
+ hints.ai_family = PF_INET;
+ if (atoi(result[0]) == 2)
+ hints.ai_family = PF_INET6;
+ else
+ hints.ai_family = PF_UNSPEC; /*XXX*/
+ hints.ai_socktype = SOCK_STREAM;
+ if (getaddrinfo(result[1], result[2], &hints, &res))
+ goto parsefail;
+ memcpy(&data_dest, res->ai_addr, res->ai_addrlen);
+ /* be paranoid, if told so */
+ if (curclass.checkportcmd) {
+ int fail;
+ fail = 0;
+ if (ntohs(data_dest.su_port) < IPPORT_RESERVED)
+ fail++;
+ if (data_dest.su_family != his_addr.su_family)
+ fail++;
+ if (data_dest.su_len != his_addr.su_len)
+ fail++;
+ switch (data_dest.su_family) {
+ case AF_INET:
+ fail += memcmp(&data_dest.su_sin.sin_addr,
+ &his_addr.su_sin.sin_addr,
+ sizeof(data_dest.su_sin.sin_addr));
+ break;
+ case AF_INET6:
+ fail += memcmp(&data_dest.su_sin6.sin6_addr,
+ &his_addr.su_sin6.sin6_addr,
+ sizeof(data_dest.su_sin6.sin6_addr));
+ break;
+ default:
+ fail++;
+ }
+ if (fail) {
+ reply(500,
+ "Illegal EPRT command rejected");
+ return (NULL);
+ }
+ }
+ free(tmp);
Home |
Main Index |
Thread Index |
Old Index