Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/libexec/ftpd Add two new ftpd.conf(5) directives:
details: https://anonhg.NetBSD.org/src/rev/50643daa8823
branches: trunk
changeset: 518698:50643daa8823
user: lukem <lukem%NetBSD.org@localhost>
date: Tue Dec 04 13:54:12 2001 +0000
description:
Add two new ftpd.conf(5) directives:
- 'denyquick'; deny a connection so tagged by ftpusers(5) after the USER
command instead of the PASS command. whilst this might provide some
info leakage of accounts names if you have some `real' or `chroot'
users enabled and not others, it does prevent accidental entering of
such passwords if you have all such users denied. This option is
strongly recommended on anonymous-only servers.
Functionality requested by Rob Windsor in [bin/12602]
- 'private'; don't display class related information in the output of STAT.
For paranoid admins.
diffstat:
libexec/ftpd/conf.c | 12 ++-
libexec/ftpd/extern.h | 12 +-
libexec/ftpd/ftpd.c | 181 ++++++++++++++++++++++++++++------------------
libexec/ftpd/ftpd.conf.5 | 49 +++++++++++-
libexec/ftpd/version.h | 4 +-
5 files changed, 172 insertions(+), 86 deletions(-)
diffs (truncated from 480 to 300 lines):
diff -r 2b27b4e26b5a -r 50643daa8823 libexec/ftpd/conf.c
--- a/libexec/ftpd/conf.c Tue Dec 04 13:12:23 2001 +0000
+++ b/libexec/ftpd/conf.c Tue Dec 04 13:54:12 2001 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: conf.c,v 1.45 2001/12/01 10:25:29 lukem Exp $ */
+/* $NetBSD: conf.c,v 1.46 2001/12/04 13:54:12 lukem Exp $ */
/*-
* Copyright (c) 1997-2001 The NetBSD Foundation, Inc.
@@ -38,7 +38,7 @@
#include <sys/cdefs.h>
#ifndef lint
-__RCSID("$NetBSD: conf.c,v 1.45 2001/12/01 10:25:29 lukem Exp $");
+__RCSID("$NetBSD: conf.c,v 1.46 2001/12/04 13:54:12 lukem Exp $");
#endif /* not lint */
#include <sys/types.h>
@@ -121,8 +121,10 @@
curclass.umask = DEFAULT_UMASK;
CURCLASS_FLAGS_SET(checkportcmd);
+ CURCLASS_FLAGS_CLR(denyquick);
CURCLASS_FLAGS_SET(modify);
CURCLASS_FLAGS_SET(passive);
+ CURCLASS_FLAGS_CLR(private);
CURCLASS_FLAGS_CLR(sanenames);
CURCLASS_FLAGS_SET(upload);
}
@@ -330,6 +332,9 @@
REASSIGN(conv->disable, disable);
REASSIGN(conv->command, convcmd);
+ } else if (strcasecmp(word, "denyquick") == 0) {
+ CONF_FLAG(denyquick);
+
} else if (strcasecmp(word, "display") == 0) {
CONF_STRING(display);
@@ -446,6 +451,9 @@
curclass.portmin = minport;
curclass.portmax = maxport;
+ } else if (strcasecmp(word, "private") == 0) {
+ CONF_FLAG(private);
+
} else if (strcasecmp(word, "rateget") == 0) {
curclass.maxrateget = 0;
curclass.rateget = 0;
diff -r 2b27b4e26b5a -r 50643daa8823 libexec/ftpd/extern.h
--- a/libexec/ftpd/extern.h Tue Dec 04 13:12:23 2001 +0000
+++ b/libexec/ftpd/extern.h Tue Dec 04 13:54:12 2001 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: extern.h,v 1.42 2001/07/13 05:37:49 lukem Exp $ */
+/* $NetBSD: extern.h,v 1.43 2001/12/04 13:54:12 lukem Exp $ */
/*-
* Copyright (c) 1992, 1993
@@ -239,11 +239,13 @@
typedef enum {
FLAG_checkportcmd = 1<<0, /* Check port commands */
- FLAG_modify = 1<<1, /* Allow CHMOD, DELE, MKD, RMD, RNFR,
+ FLAG_denyquick = 1<<1, /* Check ftpusers(5) before PASS */
+ FLAG_modify = 1<<2, /* Allow CHMOD, DELE, MKD, RMD, RNFR,
UMASK */
- FLAG_passive = 1<<2, /* Allow PASV mode */
- FLAG_sanenames = 1<<3, /* Restrict names of uploaded files */
- FLAG_upload = 1<<4 /* As per modify, but also allow
+ FLAG_passive = 1<<3, /* Allow PASV mode */
+ FLAG_private = 1<<4, /* Don't publish class info in STAT */
+ FLAG_sanenames = 1<<5, /* Restrict names of uploaded files */
+ FLAG_upload = 1<<6, /* As per modify, but also allow
APPE, STOR, STOU */
} classflag_t;
diff -r 2b27b4e26b5a -r 50643daa8823 libexec/ftpd/ftpd.c
--- a/libexec/ftpd/ftpd.c Tue Dec 04 13:12:23 2001 +0000
+++ b/libexec/ftpd/ftpd.c Tue Dec 04 13:54:12 2001 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: ftpd.c,v 1.132 2001/12/01 10:25:30 lukem Exp $ */
+/* $NetBSD: ftpd.c,v 1.133 2001/12/04 13:54:12 lukem Exp $ */
/*
* Copyright (c) 1997-2001 The NetBSD Foundation, Inc.
@@ -109,7 +109,7 @@
#if 0
static char sccsid[] = "@(#)ftpd.c 8.5 (Berkeley) 4/28/95";
#else
-__RCSID("$NetBSD: ftpd.c,v 1.132 2001/12/01 10:25:30 lukem Exp $");
+__RCSID("$NetBSD: ftpd.c,v 1.133 2001/12/04 13:54:12 lukem Exp $");
#endif
#endif /* not lint */
@@ -561,7 +561,8 @@
}
static int login_attempts; /* number of failed login attempts */
-static int askpasswd; /* had user command, ask for passwd */
+static int askpasswd; /* had USER command, ask for PASSwd */
+static int permitted; /* USER permitted */
static char curname[10]; /* current USER name */
/*
@@ -578,6 +579,9 @@
void
user(const char *name)
{
+ char *class;
+
+ class = NULL;
if (logged_in) {
switch (curclass.type) {
case CLASS_GUEST:
@@ -606,6 +610,9 @@
#endif
curclass.type = CLASS_REAL;
+ askpasswd = 0;
+ permitted = 0;
+
if (strcmp(name, "ftp") == 0 || strcmp(name, "anonymous") == 0) {
/* need `pw' setup for checkaccess() and checkuser () */
if ((pw = sgetpwnam("ftp")) == NULL)
@@ -618,34 +625,106 @@
reply(331,
"Guest login ok, type your name as password.");
}
- if (!askpasswd && logging)
- syslog(LOG_NOTICE,
- "ANONYMOUS FTP LOGIN REFUSED FROM %s", remotehost);
- return;
- }
+ if (!askpasswd) {
+ if (logging)
+ syslog(LOG_NOTICE,
+ "ANONYMOUS FTP LOGIN REFUSED FROM %s",
+ remotehost);
+ end_login();
+ goto cleanup_user;
+ }
+ name = "ftp";
+ } else
+ pw = sgetpwnam(name);
- pw = sgetpwnam(name);
if (logging)
strlcpy(curname, name, sizeof(curname));
-#ifdef SKEY
- if (skey_haskey(name) == 0) {
- const char *myskey;
+ /* check user in /etc/ftpusers, and setup class */
+ permitted = checkuser(_PATH_FTPUSERS, curname, 1, 0, &class);
- myskey = skey_keyinfo(name);
- reply(331, "Password [%s] required for %s.",
- myskey ? myskey : "error getting challenge", name);
- } else
+ /* check user in /etc/ftpchroot */
+ if (checkuser(_PATH_FTPCHROOT, curname, 0, 0, NULL)) {
+ if (curclass.type == CLASS_GUEST) {
+ syslog(LOG_NOTICE,
+ "Can't change guest user to chroot class; remove entry in %s",
+ _PATH_FTPCHROOT);
+ exit(1);
+ }
+ curclass.type = CLASS_CHROOT;
+ }
+ /* determine default class */
+ if (class == NULL) {
+ switch (curclass.type) {
+ case CLASS_GUEST:
+ class = xstrdup("guest");
+ break;
+ case CLASS_CHROOT:
+ class = xstrdup("chroot");
+ break;
+ case CLASS_REAL:
+ class = xstrdup("real");
+ break;
+ default:
+ syslog(LOG_ERR, "unknown curclass.type %d; aborting",
+ curclass.type);
+ abort();
+ }
+ }
+ /* parse ftpd.conf, setting up various parameters */
+ parse_conf(class);
+ /* if not guest user, check for valid shell */
+ if (pw == NULL)
+ permitted = 0;
+ else {
+ const char *cp, *shell;
+
+ if ((shell = pw->pw_shell) == NULL || *shell == 0)
+ shell = _PATH_BSHELL;
+ while ((cp = getusershell()) != NULL)
+ if (strcmp(cp, shell) == 0)
+ break;
+ endusershell();
+ if (cp == NULL && curclass.type != CLASS_GUEST)
+ permitted = 0;
+ }
+
+ /* deny quickly (after USER not PASS) if requested */
+ if (CURCLASS_FLAGS_ISSET(denyquick) && !permitted) {
+ reply(530, "User %s may not use FTP.", curname);
+ if (logging)
+ syslog(LOG_NOTICE, "FTP LOGIN REFUSED FROM %s, %s",
+ remotehost, curname);
+ end_login();
+ goto cleanup_user;
+ }
+
+ /* if haven't asked yet (i.e, not anon), ask now */
+ if (!askpasswd) {
+ askpasswd = 1;
+#ifdef SKEY
+ if (skey_haskey(curname) == 0) {
+ const char *myskey;
+
+ myskey = skey_keyinfo(curname);
+ reply(331, "Password [%s] required for %s.",
+ myskey ? myskey : "error getting challenge",
+ curname);
+ } else
#endif
- reply(331, "Password required for %s.", name);
+ reply(331, "Password required for %s.", curname);
+ }
- askpasswd = 1;
+ cleanup_user:
/*
* Delay before reading passwd after first failed
* attempt to slow down passwd-guessing programs.
*/
if (login_attempts)
sleep((unsigned) login_attempts);
+
+ if (class)
+ free(class);
}
/*
@@ -740,6 +819,8 @@
gid_t *groups, *ng;
int gsize, i, found;
+ if (pw == NULL)
+ continue; /* no match for unknown user */
*p++ = '\0';
groups = NULL;
gsize = 16;
@@ -823,6 +904,8 @@
memset(pw->pw_passwd, 0, strlen(pw->pw_passwd));
pw = NULL;
logged_in = 0;
+ askpasswd = 0;
+ permitted = 0;
quietmessages = 0;
gidcount = 0;
curclass.type = CLASS_REAL;
@@ -833,10 +916,8 @@
pass(const char *passwd)
{
int rval;
- const char *cp, *shell;
- char *class, root[MAXPATHLEN];
+ char root[MAXPATHLEN];
- class = NULL;
if (logged_in || askpasswd == 0) {
reply(503, "Login with USER first.");
return;
@@ -907,22 +988,8 @@
}
}
- /* password ok; see if anything else prevents login */
- if (! checkuser(_PATH_FTPUSERS, pw->pw_name, 1, 0, &class)) {
- reply(530, "User %s may not use FTP.", pw->pw_name);
- if (logging)
- syslog(LOG_NOTICE, "FTP LOGIN REFUSED FROM %s, %s",
- remotehost, pw->pw_name);
- goto bad;
- }
- /* if not guest user, check for valid shell */
- if ((shell = pw->pw_shell) == NULL || *shell == 0)
- shell = _PATH_BSHELL;
- while ((cp = getusershell()) != NULL)
- if (strcmp(cp, shell) == 0)
- break;
- endusershell();
- if (cp == NULL && curclass.type != CLASS_GUEST) {
+ /* password ok; check if anything else prevents login */
+ if (! permitted) {
reply(530, "User %s may not use FTP.", pw->pw_name);
if (logging)
Home |
Main Index |
Thread Index |
Old Index