summaryrefslogtreecommitdiff
path: root/libexec
diff options
context:
space:
mode:
authorMoritz Jodeit <moritz@cvs.openbsd.org>2008-09-12 16:12:09 +0000
committerMoritz Jodeit <moritz@cvs.openbsd.org>2008-09-12 16:12:09 +0000
commitd5cfbc6d062d7c933a09bffc7788c32e6f24977e (patch)
tree972ce88dc630addff1ce7ba9145c1bda80e9bfdd /libexec
parent1ad9ccc3c48070cfac084feb70111a7a1d16fdb0 (diff)
Don't split large commands into multiple commands on a 512-byte
boundary but just fail on them. This prevents CSRF-like attacks, when a web browser is used to access an ftp server. Reported by Maksymilian Arciemowicz <cxib@securityreason.com>. ok millert@ martynas@
Diffstat (limited to 'libexec')
-rw-r--r--libexec/ftpd/extern.h4
-rw-r--r--libexec/ftpd/ftpcmd.y31
-rw-r--r--libexec/ftpd/ftpd.c11
3 files changed, 33 insertions, 13 deletions
diff --git a/libexec/ftpd/extern.h b/libexec/ftpd/extern.h
index a4d2ba08c2e..7268cdaaadb 100644
--- a/libexec/ftpd/extern.h
+++ b/libexec/ftpd/extern.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: extern.h,v 1.16 2006/04/21 17:42:50 deraadt Exp $ */
+/* $OpenBSD: extern.h,v 1.17 2008/09/12 16:12:08 moritz Exp $ */
/* $NetBSD: extern.h,v 1.2 1995/04/11 02:44:49 cgd Exp $ */
/*
@@ -69,7 +69,7 @@ void dologout(int);
void fatal(char *);
int ftpd_pclose(FILE *);
FILE *ftpd_popen(char *, char *);
-char *getline(char *, int, FILE *);
+int getline(char *, int, FILE *);
void ftpdlogwtmp(char *, char *, char *);
void lreply(int, const char *, ...);
void makedir(char *);
diff --git a/libexec/ftpd/ftpcmd.y b/libexec/ftpd/ftpcmd.y
index 3fe95bbc392..1fda0525032 100644
--- a/libexec/ftpd/ftpcmd.y
+++ b/libexec/ftpd/ftpcmd.y
@@ -1,4 +1,4 @@
-/* $OpenBSD: ftpcmd.y,v 1.50 2008/06/30 12:03:51 ragge Exp $ */
+/* $OpenBSD: ftpcmd.y,v 1.51 2008/09/12 16:12:08 moritz Exp $ */
/* $NetBSD: ftpcmd.y,v 1.7 1996/04/08 19:03:11 jtc Exp $ */
/*
@@ -44,7 +44,7 @@
static const char sccsid[] = "@(#)ftpcmd.y 8.3 (Berkeley) 4/6/94";
#else
static const char rcsid[] =
- "$OpenBSD: ftpcmd.y,v 1.50 2008/06/30 12:03:51 ragge Exp $";
+ "$OpenBSD: ftpcmd.y,v 1.51 2008/09/12 16:12:08 moritz Exp $";
#endif
#endif /* not lint */
@@ -1088,7 +1088,7 @@ lookup(p, cmd)
/*
* getline - a hacked up version of fgets to ignore TELNET escape codes.
*/
-char *
+int
getline(s, n, iop)
char *s;
int n;
@@ -1106,7 +1106,7 @@ getline(s, n, iop)
if (debug)
syslog(LOG_DEBUG, "command: %s", s);
tmpline[0] = '\0';
- return(s);
+ return(0);
}
if (c == 0)
tmpline[0] = '\0';
@@ -1137,11 +1137,22 @@ getline(s, n, iop)
}
}
*cs++ = c;
- if (--n <= 0 || c == '\n')
+ if (--n <= 0) {
+ /*
+ * If command doesn't fit into buffer, discard the
+ * rest of the command and indicate truncation.
+ * This prevents the command to be split up into
+ * multiple commands.
+ */
+ while ((c = getc(iop)) != EOF && c != '\n')
+ ;
+ return (-2);
+ }
+ if (c == '\n')
break;
}
if (c == EOF && cs == s)
- return (NULL);
+ return (-1);
*cs++ = '\0';
if (debug) {
if (!guest && strncasecmp("pass ", s, 5) == 0) {
@@ -1161,7 +1172,7 @@ getline(s, n, iop)
syslog(LOG_DEBUG, "command: %.*s", len, s);
}
}
- return (s);
+ return (0);
}
/*ARGSUSED*/
@@ -1193,9 +1204,13 @@ yylex()
case CMD:
(void) alarm((unsigned) timeout);
- if (getline(cbuf, sizeof(cbuf)-1, stdin) == NULL) {
+ n = getline(cbuf, sizeof(cbuf)-1, stdin);
+ if (n == -1) {
reply(221, "You could at least say goodbye.");
dologout(0);
+ } else if (n == -2) {
+ /* Ignore truncated command */
+ break;
}
(void) alarm(0);
if ((cp = strchr(cbuf, '\r'))) {
diff --git a/libexec/ftpd/ftpd.c b/libexec/ftpd/ftpd.c
index ad1f3bcb7da..2385f824c4b 100644
--- a/libexec/ftpd/ftpd.c
+++ b/libexec/ftpd/ftpd.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ftpd.c,v 1.183 2008/06/30 12:03:51 ragge Exp $ */
+/* $OpenBSD: ftpd.c,v 1.184 2008/09/12 16:12:08 moritz Exp $ */
/* $NetBSD: ftpd.c,v 1.15 1995/06/03 22:46:47 mycroft Exp $ */
/*
@@ -70,7 +70,7 @@ static const char copyright[] =
static const char sccsid[] = "@(#)ftpd.c 8.4 (Berkeley) 4/16/94";
#else
static const char rcsid[] =
- "$OpenBSD: ftpd.c,v 1.183 2008/06/30 12:03:51 ragge Exp $";
+ "$OpenBSD: ftpd.c,v 1.184 2008/09/12 16:12:08 moritz Exp $";
#endif
#endif /* not lint */
@@ -2214,14 +2214,19 @@ static void
myoob(void)
{
char *cp;
+ int ret;
/* only process if transfer occurring */
if (!transflag)
return;
cp = tmpline;
- if (getline(cp, 7, stdin) == NULL) {
+ ret = getline(cp, 7, stdin);
+ if (ret == -1) {
reply(221, "You could at least say goodbye.");
dologout(0);
+ } else if (ret == -2) {
+ /* Ignore truncated command */
+ return;
}
upper(cp);
if (strcmp(cp, "ABOR\r\n") == 0) {