diff options
Diffstat (limited to 'contrib/lukemftpd/src/ftpcmd.y')
-rw-r--r-- | contrib/lukemftpd/src/ftpcmd.y | 39 |
1 files changed, 31 insertions, 8 deletions
diff --git a/contrib/lukemftpd/src/ftpcmd.y b/contrib/lukemftpd/src/ftpcmd.y index 804a26b..3f3e950 100644 --- a/contrib/lukemftpd/src/ftpcmd.y +++ b/contrib/lukemftpd/src/ftpcmd.y @@ -1363,8 +1363,12 @@ lookup(struct tab *p, const char *cmd) /* * getline - a hacked up version of fgets to ignore TELNET escape codes. + * `s' is the buffer to read into. + * `n' is the 1 less than the size of the buffer, to allow trailing NUL + * `iop' is the FILE to read from. + * Returns 0 on success, -1 on EOF, -2 if the command was too long. */ -char * +int getline(char *s, int n, FILE *iop) { int c; @@ -1379,7 +1383,7 @@ getline(char *s, int n, FILE *iop) if (ftpd_debug) syslog(LOG_DEBUG, "command: %s", s); tmpline[0] = '\0'; - return(s); + return(0); } if (c == 0) tmpline[0] = '\0'; @@ -1418,11 +1422,25 @@ getline(char *s, int n, FILE *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. + */ + if (ftpd_debug) + syslog(LOG_DEBUG, + "command too long, last char: %d", c); + while (c != '\n' && (c = getc(iop)) != EOF) + continue; + return (-2); + } + if (c == '\n') break; } if (c == EOF && cs == s) - return (NULL); + return (-1); *cs++ = '\0'; if (ftpd_debug) { if ((curclass.type != CLASS_GUEST && @@ -1444,7 +1462,7 @@ getline(char *s, int n, FILE *iop) syslog(LOG_DEBUG, "command: %.*s", len, s); } } - return (s); + return (0); } void @@ -1458,15 +1476,20 @@ ftp_handle_line(char *cp) void ftp_loop(void) { + int ret; while (1) { (void) alarm(curclass.timeout); - if (getline(cbuf, sizeof(cbuf)-1, stdin) == NULL) { + ret = getline(cbuf, sizeof(cbuf)-1, stdin); + (void) alarm(0); + if (ret == -1) { reply(221, "You could at least say goodbye."); dologout(0); + } else if (ret == -2) { + reply(500, "Command too long."); + } else { + ftp_handle_line(cbuf); } - (void) alarm(0); - ftp_handle_line(cbuf); } /*NOTREACHED*/ } |