aboutsummaryrefslogtreecommitdiff
path: root/libexec/ftpd
diff options
context:
space:
mode:
authorPaul Traina <pst@FreeBSD.org>1996-08-04 22:40:35 +0000
committerPaul Traina <pst@FreeBSD.org>1996-08-04 22:40:35 +0000
commit61f891a6df91ffd4a29eeb5d3c12752d5e36122f (patch)
treebde4d9e34ad3fdece4e0e3d55f3c74a42b3711fa /libexec/ftpd
parent7b2dfbf801af43312d4620bd6447c09637d0dea4 (diff)
Notes
Diffstat (limited to 'libexec/ftpd')
-rw-r--r--libexec/ftpd/Makefile2
-rw-r--r--libexec/ftpd/extern.h4
-rw-r--r--libexec/ftpd/ftpcmd.y53
-rw-r--r--libexec/ftpd/ftpd.c65
4 files changed, 74 insertions, 50 deletions
diff --git a/libexec/ftpd/Makefile b/libexec/ftpd/Makefile
index a3065e72793f..0780113196d1 100644
--- a/libexec/ftpd/Makefile
+++ b/libexec/ftpd/Makefile
@@ -4,7 +4,7 @@ PROG= ftpd
MAN8= ftpd.8
SRCS= ftpd.c ftpcmd.c logwtmp.c popen.c skey-stuff.c
-CFLAGS+=-DSETPROCTITLE -DSKEY -DSTATS
+CFLAGS+=-DSETPROCTITLE -DSKEY -DSTATS -DPARANOID
LDADD= -lskey -lmd -lcrypt -lutil
DPADD= ${LIBSKEY} ${LIBMD} ${LIBCRYPT} ${LIBUTIL}
diff --git a/libexec/ftpd/extern.h b/libexec/ftpd/extern.h
index fe784c89f25f..9805cabc5013 100644
--- a/libexec/ftpd/extern.h
+++ b/libexec/ftpd/extern.h
@@ -65,3 +65,7 @@ void store __P((char *, char *, int));
void upper __P((char *));
void user __P((char *));
void yyerror __P((char *));
+int yyparse __P((void));
+#if defined(SKEY) && defined(_PWD_H_) /* XXX evil */
+char *skey_challenge __P((char *, struct passwd *, int));
+#endif
diff --git a/libexec/ftpd/ftpcmd.y b/libexec/ftpd/ftpcmd.y
index 4473b154df46..aa0a67d76179 100644
--- a/libexec/ftpd/ftpcmd.y
+++ b/libexec/ftpd/ftpcmd.y
@@ -67,7 +67,7 @@ static char sccsid[] = "@(#)ftpcmd.y 8.3 (Berkeley) 4/6/94";
#include "extern.h"
-extern struct sockaddr_in data_dest;
+extern struct sockaddr_in data_dest, his_addr;
extern int logged_in;
extern struct passwd *pw;
extern int guest;
@@ -149,18 +149,35 @@ cmd
pass($3);
free($3);
}
- | PORT SP host_port CRLF
+ | PORT check_login SP host_port CRLF
{
- usedefault = 0;
- if (pdata >= 0) {
- (void) close(pdata);
- pdata = -1;
+ if ($2) {
+#ifdef PARANOID
+ if ((ntohs(data_dest.sin_port) <
+ IPPORT_RESERVED) ||
+ memcmp(&data_dest.sin_addr,
+ &his_addr.sin_addr,
+ sizeof(data_dest.sin_addr)))
+ {
+ usedefault = 1;
+ reply(500,
+ "Illegal PORT range rejected.");
+ } else
+#endif
+ {
+ usedefault = 0;
+ if (pdata >= 0) {
+ (void) close(pdata);
+ pdata = -1;
+ }
+ reply(200, "PORT command successful.");
+ }
}
- reply(200, "PORT command successful.");
}
- | PASV CRLF
+ | PASV check_login CRLF
{
- passive();
+ if ($2)
+ passive();
}
| TYPE SP type_code CRLF
{
@@ -292,16 +309,18 @@ cmd
if ($4 != NULL)
free($4);
}
- | RNTO SP pathname CRLF
+ | RNTO check_login SP pathname CRLF
{
- if (fromname) {
- renamecmd(fromname, $3);
- free(fromname);
- fromname = (char *) 0;
- } else {
- reply(503, "Bad sequence of commands.");
+ if ($2) {
+ if (fromname) {
+ renamecmd(fromname, $4);
+ free(fromname);
+ fromname = (char *) 0;
+ } else {
+ reply(503, "Bad sequence of commands.");
+ }
}
- free($3);
+ free($4);
}
| ABOR CRLF
{
diff --git a/libexec/ftpd/ftpd.c b/libexec/ftpd/ftpd.c
index e91c51354ebd..cb4b12536d2c 100644
--- a/libexec/ftpd/ftpd.c
+++ b/libexec/ftpd/ftpd.c
@@ -30,7 +30,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $Id: ftpd.c,v 1.16 1996/04/11 10:22:16 davidg Exp $
+ * $Id: ftpd.c,v 1.17 1996/05/31 03:10:25 peter Exp $
*/
#ifndef lint
@@ -202,6 +202,9 @@ static struct passwd *
sgetpwnam __P((char *));
static char *sgetsave __P((char *));
static void reapchild __P((int));
+#ifdef STATS
+static void logxfer __P((char *, long, long));
+#endif
static char *
curdir()
@@ -380,7 +383,7 @@ main(argc, argv, envp)
syslog(LOG_ERR, "signal: %m");
#ifdef SKEY
- strcpy(addr_string, inet_ntoa(his_addr.sin_addr));
+ strncpy(addr_string, inet_ntoa(his_addr.sin_addr), sizeof(addr_string));
#endif
addrlen = sizeof(ctrl_addr);
if (getsockname(0, (struct sockaddr *)&ctrl_addr, &addrlen) < 0) {
@@ -739,7 +742,10 @@ pass(passwd)
if (ident != NULL)
free(ident);
- ident = (char *) copy(passwd);
+ ident = strdup(passwd);
+ if (ident == NULL)
+ fatal("Ran out of memory.");
+
#endif
reply(230, "Guest login ok, access restrictions apply.");
#ifdef SETPROCTITLE
@@ -836,7 +842,7 @@ retrieve(cmd, name)
restart_point == 0 && cmd == 0 && S_ISREG(st.st_mode));
#ifdef STATS
if (cmd == 0 && guest && stats)
- logxfer( name, st.st_size, start);
+ logxfer(name, st.st_size, start);
#endif
(void) fclose(dout);
data = -1;
@@ -856,7 +862,7 @@ store(name, mode, unique)
struct stat st;
int (*closefunc) __P((FILE *));
- if (unique && stat(name, &st) == 0 &&
+ if ((unique || guest) && stat(name, &st) == 0 &&
(name = gunique(name)) == NULL) {
LOGCMD(*mode == 'w' ? "put" : "append", name);
return;
@@ -1181,7 +1187,7 @@ receive_data(instr, outstr)
FILE *instr, *outstr;
{
int c;
- int cnt, bare_lfs = 0;
+ int cnt, bare_lfs;
char buf[BUFSIZ];
transflag++;
@@ -1189,6 +1195,9 @@ receive_data(instr, outstr)
transflag = 0;
return (-1);
}
+
+ bare_lfs = 0;
+
switch (type) {
case TYPE_I:
@@ -1521,8 +1530,15 @@ void
renamecmd(from, to)
char *from, *to;
{
+ struct stat st;
LOGCMD2("rename", from, to);
+
+ if (guest && (stat(to, &st) == 0)) {
+ reply(550, "%s: permission denied", to);
+ return;
+ }
+
if (rename(from, to) < 0)
perror_reply(550, "rename");
else
@@ -1607,35 +1623,31 @@ void
passive()
{
int len, on;
- u_short port;
char *p, *a;
- if (pw == NULL) {
- reply(530, "Please login with USER and PASS");
- return;
- }
+ if (pdata >= 0) /* close old port if one set */
+ close(pdata);
+
pdata = socket(AF_INET, SOCK_STREAM, 0);
if (pdata < 0) {
perror_reply(425, "Can't open passive connection");
return;
}
- on = restricted_data_ports ? IP_PORTRANGE_HIGH : IP_PORTRANGE_DEFAULT;
(void) seteuid((uid_t)0);
+
+ on = restricted_data_ports ? IP_PORTRANGE_HIGH : IP_PORTRANGE_DEFAULT;
if (setsockopt(pdata, IPPROTO_IP, IP_PORTRANGE,
(char *)&on, sizeof(on)) < 0) {
- (void) seteuid((uid_t)pw->pw_uid);
goto pasv_error;
}
pasv_addr = ctrl_addr;
pasv_addr.sin_port = 0;
- (void) seteuid((uid_t)0);
if (bind(pdata, (struct sockaddr *)&pasv_addr,
- sizeof(pasv_addr)) < 0) {
- (void) seteuid((uid_t)pw->pw_uid);
+ sizeof(pasv_addr)) < 0)
goto pasv_error;
- }
+
(void) seteuid((uid_t)pw->pw_uid);
len = sizeof(pasv_addr);
@@ -1653,6 +1665,7 @@ passive()
return;
pasv_error:
+ (void) seteuid((uid_t)pw->pw_uid);
(void) close(pdata);
pdata = -1;
perror_reply(425, "Can't open passive connection");
@@ -1682,7 +1695,7 @@ gunique(local)
}
if (cp)
*cp = '/';
- (void) strcpy(new, local);
+ (void) snprintf(new, sizeof(new), "%s", local);
cp = new + strlen(new);
*cp++ = '.';
for (count = 1; count < 100; count++) {
@@ -1894,6 +1907,7 @@ setproctitle(fmt, va_alist)
#endif /* OLD_SETPROCTITLE */
#ifdef STATS
+static void
logxfer(name, size, start)
char *name;
long size;
@@ -1905,23 +1919,10 @@ logxfer(name, size, start)
if (statfd >= 0 && getwd(path) != NULL) {
time(&now);
- sprintf(buf, "%.20s!%s!%s!%s/%s!%ld!%ld\n",
+ snprintf(buf, sizeof(buf), "%.20s!%s!%s!%s/%s!%ld!%ld\n",
ctime(&now)+4, ident, remotehost,
path, name, size, now - start + (now == start));
write(statfd, buf, strlen(buf));
}
}
-
-char *
-copy(s)
- char *s;
-{
- char *p;
-
- p = malloc((unsigned) strlen(s) + 1);
- if (p == NULL)
- fatal("Ran out of memory.");
- (void) strcpy(p, s);
- return (p);
-}
#endif