forked from mirrors/tftp-hpa-google
Add documentation for matching options; more verbose logging.
This commit is contained in:
parent
baf8364f1a
commit
acf458d957
2 changed files with 112 additions and 8 deletions
|
@ -44,7 +44,9 @@
|
||||||
IPv4 Trivial File Transfer Protocol server
|
IPv4 Trivial File Transfer Protocol server
|
||||||
.Sh SYNOPSIS
|
.Sh SYNOPSIS
|
||||||
.Nm in.tftpd
|
.Nm in.tftpd
|
||||||
|
.Op Fl v
|
||||||
.Op Fl c
|
.Op Fl c
|
||||||
|
.Op Fl m Ar mapfile
|
||||||
.Op Fl u Ar userid
|
.Op Fl u Ar userid
|
||||||
.Op Fl r Ar option...
|
.Op Fl r Ar option...
|
||||||
.Op Fl s
|
.Op Fl s
|
||||||
|
@ -118,6 +120,16 @@ flag can be used to specify a user ID which
|
||||||
.Nm
|
.Nm
|
||||||
will run as; the default is ``nobody''.
|
will run as; the default is ``nobody''.
|
||||||
.Pp
|
.Pp
|
||||||
|
The
|
||||||
|
.Fl m
|
||||||
|
flag specifies a file which contains filename remapping rules.
|
||||||
|
.Pp
|
||||||
|
The
|
||||||
|
.Fl v
|
||||||
|
flag increases the logging verbosity of
|
||||||
|
.Nm tftpd ,
|
||||||
|
it can be specified multiple times.
|
||||||
|
.Pp
|
||||||
This version of
|
This version of
|
||||||
.Nm
|
.Nm
|
||||||
supports RFC 2347 option negotiation; the current version supports the
|
supports RFC 2347 option negotiation; the current version supports the
|
||||||
|
@ -130,8 +142,73 @@ supports RFC 2347 option negotiation; the current version supports the
|
||||||
.Fl r
|
.Fl r
|
||||||
flag can be used to disable options individually; this may allow
|
flag can be used to disable options individually; this may allow
|
||||||
working around client bugs.
|
working around client bugs.
|
||||||
|
.Sh FILENAME REMAPPING
|
||||||
|
The
|
||||||
|
.Fl m
|
||||||
|
option specifies a file which contains filename remapping rules. Each
|
||||||
|
non-comment line (comments begin with hash marks, #) contains an
|
||||||
|
.Ar operation ,
|
||||||
|
a
|
||||||
|
.Ar regex ,
|
||||||
|
a regular expression in the style of
|
||||||
|
.Xr egrep 1 ,
|
||||||
|
and optionally a
|
||||||
|
.Ar "replacement pattern" .
|
||||||
|
The operation indicated by
|
||||||
|
.Ar operation
|
||||||
|
is performed if the
|
||||||
|
.Ar regex
|
||||||
|
matches all or part of the filename. Rules are processed from the top
|
||||||
|
down, and by default, all rules are processed even if there is a
|
||||||
|
match.
|
||||||
|
.Pp
|
||||||
|
The
|
||||||
|
.Ar operation
|
||||||
|
can be any combination of the following letters:
|
||||||
|
.Pp
|
||||||
|
.Bl -tag -width verbose -compact
|
||||||
|
.It Ic r
|
||||||
|
Replace the substring matched by
|
||||||
|
.Ar regex
|
||||||
|
by the
|
||||||
|
.Ar "replacement pattern" .
|
||||||
|
The escape sequence
|
||||||
|
\\0
|
||||||
|
can be used to copy the entire matched string, and the sequences
|
||||||
|
\\1 to \\9
|
||||||
|
copies parenthesized subexpressions. To specify a backslash, white
|
||||||
|
space or hash mark, you need to \\-escape it.
|
||||||
|
.Pp
|
||||||
|
.It Ic g
|
||||||
|
Repeat this rule until it no longer matches. This is always used with
|
||||||
|
.Ic r .
|
||||||
|
.Pp
|
||||||
|
.It Ic i
|
||||||
|
Match the
|
||||||
|
.Ar regex
|
||||||
|
case-insensitively. By default it is case sensitive.
|
||||||
|
.Pp
|
||||||
|
.It Ic e
|
||||||
|
If this rule matches, end rule processing after executing the rule.
|
||||||
|
.Pp
|
||||||
|
.It Ic s
|
||||||
|
If this rule matches, start rule processing over from the very first
|
||||||
|
rule after executing this rule.
|
||||||
|
.Pp
|
||||||
|
.It Ic a
|
||||||
|
If this rule matches, refuse the request and send an access denied
|
||||||
|
error to the client.
|
||||||
|
.Pp
|
||||||
|
.It Ic G
|
||||||
|
This rule applies to GET (RRQ) requests only.
|
||||||
|
.Pp
|
||||||
|
.It Ic P
|
||||||
|
This rule applies to PUT (WRQ) requests only.
|
||||||
|
.El
|
||||||
.Sh SEE ALSO
|
.Sh SEE ALSO
|
||||||
.Xr tftp 1 ,
|
.Xr tftp 1 ,
|
||||||
|
.Xr egrep 1 ,
|
||||||
|
.Xr regex 7 ,
|
||||||
.Xr inetd 8
|
.Xr inetd 8
|
||||||
.Sh HISTORY
|
.Sh HISTORY
|
||||||
The
|
The
|
||||||
|
@ -153,5 +230,9 @@ flag and RFC 2347 options were added by H. Peter Anvin based on
|
||||||
patches by Markus Gutschke and Gero Kulhman.
|
patches by Markus Gutschke and Gero Kulhman.
|
||||||
.Pp
|
.Pp
|
||||||
The
|
The
|
||||||
.Fl u
|
.Fl u ,
|
||||||
flag was added by H. Peter Anvin.
|
.Fl v
|
||||||
|
and
|
||||||
|
.Fl m
|
||||||
|
flags were added by H. Peter Anvin.
|
||||||
|
|
||||||
|
|
|
@ -85,6 +85,8 @@ static const char *rcsid = "tftp-hpa $Id$";
|
||||||
int deny_severity = LOG_WARNING;
|
int deny_severity = LOG_WARNING;
|
||||||
int allow_severity = -1; /* Don't log at all */
|
int allow_severity = -1; /* Don't log at all */
|
||||||
|
|
||||||
|
int verbosity = 0;
|
||||||
|
|
||||||
struct request_info wrap_request;
|
struct request_info wrap_request;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -157,7 +159,7 @@ struct options {
|
||||||
static void
|
static void
|
||||||
usage(void)
|
usage(void)
|
||||||
{
|
{
|
||||||
syslog(LOG_ERR, "Usage: %s [-c] [-m mappings] [-u user] [-t timeout] [-r option...] [-s] [directory ...]",
|
syslog(LOG_ERR, "Usage: %s [-vc][-m mappings][-u user][-t timeout][-r option...] [-s] [directory ...]",
|
||||||
__progname);
|
__progname);
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
@ -182,7 +184,7 @@ main(int argc, char **argv)
|
||||||
|
|
||||||
openlog(__progname, LOG_PID | LOG_NDELAY, LOG_DAEMON);
|
openlog(__progname, LOG_PID | LOG_NDELAY, LOG_DAEMON);
|
||||||
|
|
||||||
while ((c = getopt(argc, argv, "csu:r:t:m:")) != -1)
|
while ((c = getopt(argc, argv, "csvu:r:t:m:")) != -1)
|
||||||
switch (c) {
|
switch (c) {
|
||||||
case 'c':
|
case 'c':
|
||||||
cancreate = 1;
|
cancreate = 1;
|
||||||
|
@ -226,6 +228,9 @@ main(int argc, char **argv)
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
#endif
|
#endif
|
||||||
|
case 'v':
|
||||||
|
verbosity++;
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
usage();
|
usage();
|
||||||
break;
|
break;
|
||||||
|
@ -415,6 +420,7 @@ tftp(struct tftphdr *tp, int size)
|
||||||
char *cp;
|
char *cp;
|
||||||
int argn, ecode;
|
int argn, ecode;
|
||||||
struct formats *pf = NULL;
|
struct formats *pf = NULL;
|
||||||
|
char *origfilename;
|
||||||
char *filename, *mode = NULL;
|
char *filename, *mode = NULL;
|
||||||
|
|
||||||
char *val = NULL, *opt = NULL;
|
char *val = NULL, *opt = NULL;
|
||||||
|
@ -422,7 +428,7 @@ tftp(struct tftphdr *tp, int size)
|
||||||
|
|
||||||
((struct tftphdr *)ackbuf)->th_opcode = ntohs(OACK);
|
((struct tftphdr *)ackbuf)->th_opcode = ntohs(OACK);
|
||||||
|
|
||||||
filename = cp = tp->th_stuff;
|
origfilename = cp = tp->th_stuff;
|
||||||
argn = 0;
|
argn = 0;
|
||||||
|
|
||||||
while ( cp < buf + size && *cp ) {
|
while ( cp < buf + size && *cp ) {
|
||||||
|
@ -449,7 +455,7 @@ tftp(struct tftphdr *tp, int size)
|
||||||
nak(EBADOP);
|
nak(EBADOP);
|
||||||
exit(0);
|
exit(0);
|
||||||
}
|
}
|
||||||
if ( !(filename = (*pf->f_rewrite)(filename, tp->th_opcode)) ) {
|
if ( !(filename = (*pf->f_rewrite)(origfilename, tp->th_opcode)) ) {
|
||||||
nak(EACCES); /* File denied by mapping rule */
|
nak(EACCES); /* File denied by mapping rule */
|
||||||
exit(0);
|
exit(0);
|
||||||
}
|
}
|
||||||
|
@ -472,6 +478,17 @@ tftp(struct tftphdr *tp, int size)
|
||||||
exit(0);
|
exit(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ( verbosity >= 1 ) {
|
||||||
|
if ( filename == origfilename || !strcmp(filename, origfilename) )
|
||||||
|
syslog(LOG_NOTICE, "%s from %s filename %s\n",
|
||||||
|
opcode[tp->th_opcode] == WRQ ? "WRQ" : "RRQ",
|
||||||
|
inet_ntoa(from.sin_addr), filename);
|
||||||
|
else
|
||||||
|
syslog(LOG_NOTICE, "%s from %s filename %s remapped to %s\n",
|
||||||
|
opcode[tp->th_opcode] == WRQ ? "WRQ" : "RRQ",
|
||||||
|
inet_ntoa(from.sin_addr), origfilename, filename);
|
||||||
|
}
|
||||||
|
|
||||||
if ( ap != (ackbuf+2) ) {
|
if ( ap != (ackbuf+2) ) {
|
||||||
if ( tp->th_opcode == WRQ )
|
if ( tp->th_opcode == WRQ )
|
||||||
(*pf->f_recv)(pf, ackbuf, ap-ackbuf);
|
(*pf->f_recv)(pf, ackbuf, ap-ackbuf);
|
||||||
|
@ -966,6 +983,12 @@ nak(int error)
|
||||||
length = strlen(pe->e_msg);
|
length = strlen(pe->e_msg);
|
||||||
tp->th_msg[length] = '\0';
|
tp->th_msg[length] = '\0';
|
||||||
length += 5;
|
length += 5;
|
||||||
|
|
||||||
|
if ( verbosity >= 2 ) {
|
||||||
|
syslog(LOG_INFO, "sending NAK (%d, %s) to %s",
|
||||||
|
error, tp->th_msg, inet_ntoa(from.sin_addr));
|
||||||
|
}
|
||||||
|
|
||||||
if (send(peer, buf, length, 0) != length)
|
if (send(peer, buf, length, 0) != length)
|
||||||
syslog(LOG_ERR, "nak: %m");
|
syslog(LOG_ERR, "nak: %m");
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue