Add option -E to disable EPSV which throws certain stateful firewalls
into confusion. Add option -r to make ftpd support only read-only operations. Submitted by: Flemming (F3) Jacobsen <fj@batmule.dk> Reviewed by: phk
This commit is contained in:
parent
ae1abfb706
commit
a4b77a2aaa
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=70102
@ -90,6 +90,8 @@ extern char proctitle[];
|
||||
extern int usedefault;
|
||||
extern int transflag;
|
||||
extern char tmpline[];
|
||||
extern int readonly;
|
||||
extern int noepsv;
|
||||
|
||||
off_t restart_point;
|
||||
|
||||
@ -132,6 +134,8 @@ extern int epsvall;
|
||||
%token <i> NUMBER
|
||||
|
||||
%type <i> check_login octal_number byte_size
|
||||
%type <i> check_login_ro octal_number byte_size
|
||||
%type <i> check_login_epsv octal_number byte_size
|
||||
%type <i> struct_code mode_code type_code form_code
|
||||
%type <s> pathstring pathname password username ext_arg
|
||||
%type <s> ALL
|
||||
@ -318,7 +322,7 @@ cmd
|
||||
else if ($2)
|
||||
long_passive("LPSV", PF_UNSPEC);
|
||||
}
|
||||
| EPSV check_login SP NUMBER CRLF
|
||||
| EPSV check_login_epsv SP NUMBER CRLF
|
||||
{
|
||||
if ($2) {
|
||||
int pf;
|
||||
@ -338,7 +342,7 @@ cmd
|
||||
long_passive("EPSV", pf);
|
||||
}
|
||||
}
|
||||
| EPSV check_login SP ALL CRLF
|
||||
| EPSV check_login_epsv SP ALL CRLF
|
||||
{
|
||||
if ($2) {
|
||||
reply(200,
|
||||
@ -346,7 +350,7 @@ cmd
|
||||
epsvall++;
|
||||
}
|
||||
}
|
||||
| EPSV check_login CRLF
|
||||
| EPSV check_login_epsv CRLF
|
||||
{
|
||||
if ($2)
|
||||
long_passive("EPSV", PF_UNSPEC);
|
||||
@ -425,14 +429,14 @@ cmd
|
||||
if ($4 != NULL)
|
||||
free($4);
|
||||
}
|
||||
| STOR check_login SP pathname CRLF
|
||||
| STOR check_login_ro SP pathname CRLF
|
||||
{
|
||||
if ($2 && $4 != NULL)
|
||||
store($4, "w", 0);
|
||||
if ($4 != NULL)
|
||||
free($4);
|
||||
}
|
||||
| APPE check_login SP pathname CRLF
|
||||
| APPE check_login_ro SP pathname CRLF
|
||||
{
|
||||
if ($2 && $4 != NULL)
|
||||
store($4, "a", 0);
|
||||
@ -474,14 +478,14 @@ cmd
|
||||
{
|
||||
statcmd();
|
||||
}
|
||||
| DELE check_login SP pathname CRLF
|
||||
| DELE check_login_ro SP pathname CRLF
|
||||
{
|
||||
if ($2 && $4 != NULL)
|
||||
delete($4);
|
||||
if ($4 != NULL)
|
||||
free($4);
|
||||
}
|
||||
| RNTO check_login SP pathname CRLF
|
||||
| RNTO check_login_ro SP pathname CRLF
|
||||
{
|
||||
if ($2) {
|
||||
if (fromname) {
|
||||
@ -537,14 +541,14 @@ cmd
|
||||
{
|
||||
reply(200, "NOOP command successful.");
|
||||
}
|
||||
| MKD check_login SP pathname CRLF
|
||||
| MKD check_login_ro SP pathname CRLF
|
||||
{
|
||||
if ($2 && $4 != NULL)
|
||||
makedir($4);
|
||||
if ($4 != NULL)
|
||||
free($4);
|
||||
}
|
||||
| RMD check_login SP pathname CRLF
|
||||
| RMD check_login_ro SP pathname CRLF
|
||||
{
|
||||
if ($2 && $4 != NULL)
|
||||
removedir($4);
|
||||
@ -594,7 +598,7 @@ cmd
|
||||
}
|
||||
}
|
||||
}
|
||||
| SITE SP CHMOD check_login SP octal_number SP pathname CRLF
|
||||
| SITE SP CHMOD check_login_ro SP octal_number SP pathname CRLF
|
||||
{
|
||||
if ($4 && ($8 != NULL)) {
|
||||
if ($6 > 0777)
|
||||
@ -628,7 +632,7 @@ cmd
|
||||
timeout);
|
||||
}
|
||||
}
|
||||
| STOU check_login SP pathname CRLF
|
||||
| STOU check_login_ro SP pathname CRLF
|
||||
{
|
||||
if ($2 && $4 != NULL)
|
||||
store($4, "w", 1);
|
||||
@ -706,7 +710,7 @@ cmd
|
||||
}
|
||||
;
|
||||
rcmd
|
||||
: RNFR check_login SP pathname CRLF
|
||||
: RNFR check_login_ro SP pathname CRLF
|
||||
{
|
||||
char *renamefrom();
|
||||
|
||||
@ -954,12 +958,31 @@ octal_number
|
||||
check_login
|
||||
: /* empty */
|
||||
{
|
||||
if (logged_in)
|
||||
$$ = 1;
|
||||
else {
|
||||
reply(530, "Please login with USER and PASS.");
|
||||
$$ = 0;
|
||||
}
|
||||
$$ = check_login1();
|
||||
}
|
||||
;
|
||||
|
||||
check_login_epsv
|
||||
: /* empty */
|
||||
{
|
||||
if (noepsv) {
|
||||
reply(500, "EPSV command disabled");
|
||||
$$ = 0;
|
||||
}
|
||||
else
|
||||
$$ = check_login1();
|
||||
}
|
||||
;
|
||||
|
||||
check_login_ro
|
||||
: /* empty */
|
||||
{
|
||||
if (readonly) {
|
||||
reply(202, "Command ignored. Server is in readonly mode.");
|
||||
$$ = 0;
|
||||
}
|
||||
else
|
||||
$$ = check_login1();
|
||||
}
|
||||
;
|
||||
|
||||
@ -1558,6 +1581,17 @@ port_check(pcmd)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
check_login1()
|
||||
{
|
||||
if (logged_in)
|
||||
return 1;
|
||||
else {
|
||||
reply(530, "Please login with USER and PASS.");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef INET6
|
||||
/* Return 1, if port check is done. Return 0, if not yet. */
|
||||
static int
|
||||
|
@ -50,6 +50,8 @@ Internet File Transfer Protocol server
|
||||
.Op Fl R
|
||||
.Op Fl S
|
||||
.Op Fl U
|
||||
.Op Fl r
|
||||
.Op Fl E
|
||||
.Op Fl T Ar maxtimeout
|
||||
.Op Fl t Ar timeout
|
||||
.Op Fl a Ar address
|
||||
@ -153,6 +155,11 @@ When
|
||||
is not specified, accept IPv4 connection via AF_INET socket.
|
||||
.It Fl A
|
||||
Allow only anonymous ftp access.
|
||||
.It Fl r
|
||||
Put server in read-only mode. All commands which may modify the local
|
||||
filesystem is disabled.
|
||||
.It Fl E
|
||||
Disable the EPSV command. This is usefull for servers behind older FireWalls.
|
||||
.El
|
||||
.Pp
|
||||
The file
|
||||
@ -178,20 +185,27 @@ relative to the login environment. This means the one in
|
||||
in the anonymous user's case.
|
||||
.Pp
|
||||
The ftp server currently supports the following ftp requests.
|
||||
The case of the requests is ignored.
|
||||
The case of the requests is ignored. Requests marked [RW] are
|
||||
disabled if
|
||||
.Fl r
|
||||
is specified.
|
||||
.Bl -column "Request" -offset indent
|
||||
.It Sy Request Ta Sy "Description"
|
||||
.It ABOR Ta "abort previous command"
|
||||
.It ACCT Ta "specify account (ignored)"
|
||||
.It ALLO Ta "allocate storage (vacuously)"
|
||||
.It APPE Ta "append to a file"
|
||||
.It APPE Ta "append to a file [RW]"
|
||||
.It CDUP Ta "change to parent of current working directory"
|
||||
.It CWD Ta "change working directory"
|
||||
.It DELE Ta "delete a file"
|
||||
.It DELE Ta "delete a file [RW]"
|
||||
.It EPRT Ta "specify data connection port, multiprotocol"
|
||||
.It EPSV Ta "prepare for server-to-server transfer, multiprotocol"
|
||||
.It HELP Ta "give help information"
|
||||
.It LIST Ta "give list files in a directory" Pq Dq Li "ls -lgA"
|
||||
.It MKD Ta "make a directory"
|
||||
.It LPRT Ta "specify data connection port, multiprotocol"
|
||||
.It LPSV Ta "prepare for server-to-server transfer, multiprotocol"
|
||||
.It MDTM Ta "show last modification time of file"
|
||||
.It MKD Ta "make a directory [RW]"
|
||||
.It MODE Ta "specify data transfer" Em mode
|
||||
.It NLST Ta "give name list of files in directory"
|
||||
.It NOOP Ta "do nothing"
|
||||
@ -202,27 +216,23 @@ The case of the requests is ignored.
|
||||
.It QUIT Ta "terminate session"
|
||||
.It REST Ta "restart incomplete transfer"
|
||||
.It RETR Ta "retrieve a file"
|
||||
.It RMD Ta "remove a directory"
|
||||
.It RNFR Ta "specify rename-from file name"
|
||||
.It RNTO Ta "specify rename-to file name"
|
||||
.It RMD Ta "remove a directory [RW]"
|
||||
.It RNFR Ta "specify rename-from file name [RW]"
|
||||
.It RNTO Ta "specify rename-to file name [RW]"
|
||||
.It SITE Ta "non-standard commands (see next section)"
|
||||
.It SIZE Ta "return size of file"
|
||||
.It STAT Ta "return status of server"
|
||||
.It STOR Ta "store a file"
|
||||
.It STOU Ta "store a file with a unique name"
|
||||
.It STOR Ta "store a file [RW]"
|
||||
.It STOU Ta "store a file with a unique name [RW]"
|
||||
.It STRU Ta "specify data transfer" Em structure
|
||||
.It SYST Ta "show operating system type of server system"
|
||||
.It TYPE Ta "specify data transfer" Em type
|
||||
.It USER Ta "specify user name"
|
||||
.It XCUP Ta "change to parent of current working directory (deprecated)"
|
||||
.It XCWD Ta "change working directory (deprecated)"
|
||||
.It XMKD Ta "make a directory (deprecated)"
|
||||
.It XMKD Ta "make a directory (deprecated) [RW]"
|
||||
.It XPWD Ta "print the current working directory (deprecated)"
|
||||
.It XRMD Ta "remove a directory (deprecated)"
|
||||
.It LPSV Ta "prepare for server-to-server transfer, multiprotocol"
|
||||
.It LPRT Ta "specify data connection port, multiprotocol"
|
||||
.It EPSV Ta "prepare for server-to-server transfer, multiprotocol"
|
||||
.It EPRT Ta "specify data connection port, multiprotocol"
|
||||
.It XRMD Ta "remove a directory (deprecated) [RW]"
|
||||
.El
|
||||
.Pp
|
||||
The following non-standard or
|
||||
@ -235,7 +245,7 @@ SITE request.
|
||||
.It Sy Request Ta Sy Description
|
||||
.It UMASK Ta change umask, e.g. ``SITE UMASK 002''
|
||||
.It IDLE Ta set idle-timer, e.g. ``SITE IDLE 60''
|
||||
.It CHMOD Ta "change mode of a file, e.g. ``SITE CHMOD 755 filename''"
|
||||
.It CHMOD Ta "change mode of a file [RW], e.g. ``SITE CHMOD 755 filename'' "
|
||||
.It HELP Ta give help information
|
||||
.El
|
||||
.Pp
|
||||
|
@ -148,6 +148,8 @@ int stru; /* avoid C keyword */
|
||||
int mode;
|
||||
int usedefault = 1; /* for data transfers */
|
||||
int pdata = -1; /* for passive mode */
|
||||
int readonly=0; /* Server is in readonly mode. */
|
||||
int noepsv=0; /* EPSV command is disabled. */
|
||||
sig_atomic_t transflag;
|
||||
off_t file_size;
|
||||
off_t byte_count;
|
||||
@ -290,7 +292,7 @@ main(argc, argv, envp)
|
||||
#endif /* OLD_SETPROCTITLE */
|
||||
|
||||
|
||||
while ((ch = getopt(argc, argv, "AdlDSURt:T:u:va:p:46")) != -1) {
|
||||
while ((ch = getopt(argc, argv, "AdlDESURrt:T:u:va:p:46")) != -1) {
|
||||
switch (ch) {
|
||||
case 'D':
|
||||
daemon_mode++;
|
||||
@ -300,10 +302,18 @@ main(argc, argv, envp)
|
||||
debug++;
|
||||
break;
|
||||
|
||||
case 'E':
|
||||
noepsv = 1;
|
||||
break;
|
||||
|
||||
case 'l':
|
||||
logging++; /* > 1 == extra logging */
|
||||
break;
|
||||
|
||||
case 'r':
|
||||
readonly = 1;
|
||||
break;
|
||||
|
||||
case 'R':
|
||||
paranoid = 0;
|
||||
break;
|
||||
|
Loading…
Reference in New Issue
Block a user