forked from mirrors/tftp-hpa-google
Interpret the \i and \x escape sequences to insert the IP of the
requesting host
This commit is contained in:
parent
fc1a21c942
commit
57044bc5df
5 changed files with 108 additions and 26 deletions
5
CHANGES
5
CHANGES
|
@ -5,7 +5,10 @@ Changes in 0.27:
|
||||||
Alan Sundell for helping out with this platform!
|
Alan Sundell for helping out with this platform!
|
||||||
|
|
||||||
Make the AIX 4.3 platform work again. Thanks to Josef Siemes
|
Make the AIX 4.3 platform work again. Thanks to Josef Siemes
|
||||||
for helping me out with this platform!
|
for helping out with this platform!
|
||||||
|
|
||||||
|
Allow replacement patterns to include the IP address of the
|
||||||
|
requesting host (\i).
|
||||||
|
|
||||||
|
|
||||||
Changes in 0.26:
|
Changes in 0.26:
|
||||||
|
|
|
@ -43,7 +43,8 @@ struct rule {
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Do \-substitution. Call with string == NULL to get length only. */
|
/* Do \-substitution. Call with string == NULL to get length only. */
|
||||||
static int genmatchstring(char *string, const char *pattern, const char *input, const regmatch_t *pmatch)
|
static int genmatchstring(char *string, const char *pattern, const char *input,
|
||||||
|
const regmatch_t *pmatch, match_pattern_callback macrosub)
|
||||||
{
|
{
|
||||||
int len = 0;
|
int len = 0;
|
||||||
int n, mlen;
|
int n, mlen;
|
||||||
|
@ -60,11 +61,8 @@ static int genmatchstring(char *string, const char *pattern, const char *input,
|
||||||
/* Transform matched section */
|
/* Transform matched section */
|
||||||
while ( *pattern ) {
|
while ( *pattern ) {
|
||||||
if ( *pattern == '\\' && pattern[1] != '\0' ) {
|
if ( *pattern == '\\' && pattern[1] != '\0' ) {
|
||||||
if ( pattern[1] < '0' || pattern[1] > '9' ) {
|
char macro = pattern[1];
|
||||||
len++;
|
if ( macro >= '0' && macro <= '9' ) {
|
||||||
if ( string )
|
|
||||||
*string++ = pattern[1];
|
|
||||||
} else {
|
|
||||||
n = pattern[1] - '0';
|
n = pattern[1] - '0';
|
||||||
|
|
||||||
if ( pmatch[n].rm_so != -1 ) {
|
if ( pmatch[n].rm_so != -1 ) {
|
||||||
|
@ -75,6 +73,16 @@ static int genmatchstring(char *string, const char *pattern, const char *input,
|
||||||
string += mlen;
|
string += mlen;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
int sublen;
|
||||||
|
if ( macrosub &&
|
||||||
|
(sublen = macrosub(macro, string)) >= 0 ) {
|
||||||
|
len += sublen;
|
||||||
|
} else {
|
||||||
|
len++;
|
||||||
|
if ( string )
|
||||||
|
*string++ = pattern[1];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
pattern += 2;
|
pattern += 2;
|
||||||
} else {
|
} else {
|
||||||
|
@ -257,7 +265,8 @@ void freerules(struct rule *r)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Execute a rule set on a string; returns a malloc'd new string. */
|
/* Execute a rule set on a string; returns a malloc'd new string. */
|
||||||
char *rewrite_string(const char *input, const struct rule *rules, int is_put)
|
char *rewrite_string(const char *input, const struct rule *rules,
|
||||||
|
int is_put, match_pattern_callback macrosub)
|
||||||
{
|
{
|
||||||
char *current = tfstrdup(input);
|
char *current = tfstrdup(input);
|
||||||
char *newstr;
|
char *newstr;
|
||||||
|
@ -299,9 +308,11 @@ char *rewrite_string(const char *input, const struct rule *rules, int is_put)
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( ruleptr->rule_flags & RULE_REWRITE ) {
|
if ( ruleptr->rule_flags & RULE_REWRITE ) {
|
||||||
len = genmatchstring(NULL, ruleptr->pattern, current, pmatch);
|
len = genmatchstring(NULL, ruleptr->pattern, current,
|
||||||
|
pmatch, macrosub);
|
||||||
newstr = tfmalloc(len+1);
|
newstr = tfmalloc(len+1);
|
||||||
genmatchstring(newstr, ruleptr->pattern, current, pmatch);
|
genmatchstring(newstr, ruleptr->pattern, current,
|
||||||
|
pmatch, macrosub);
|
||||||
free(current);
|
free(current);
|
||||||
current = newstr;
|
current = newstr;
|
||||||
if ( verbosity >= 3 ) {
|
if ( verbosity >= 3 ) {
|
||||||
|
|
|
@ -18,15 +18,17 @@
|
||||||
#ifndef TFTPD_REMAP_H
|
#ifndef TFTPD_REMAP_H
|
||||||
#define TFTPD_REMAP_H
|
#define TFTPD_REMAP_H
|
||||||
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <stdio.h>
|
|
||||||
#include "../config.h"
|
|
||||||
|
|
||||||
/* Opaque type */
|
/* Opaque type */
|
||||||
struct rule;
|
struct rule;
|
||||||
|
|
||||||
#ifdef WITH_REGEX
|
#ifdef WITH_REGEX
|
||||||
|
|
||||||
|
/* This is called when we encounter a substitution like \i. The
|
||||||
|
macro character is passed as the first argument; the output buffer,
|
||||||
|
if any, is passed as the second argument. The function should return
|
||||||
|
the number of characters output, or -1 on failure. */
|
||||||
|
typedef int (*match_pattern_callback)(char, char *);
|
||||||
|
|
||||||
/* Read a rule file */
|
/* Read a rule file */
|
||||||
struct rule *parserulefile(FILE *);
|
struct rule *parserulefile(FILE *);
|
||||||
|
|
||||||
|
@ -34,7 +36,8 @@ struct rule *parserulefile(FILE *);
|
||||||
void freerules(struct rule *);
|
void freerules(struct rule *);
|
||||||
|
|
||||||
/* Execute a rule set on a string; returns a malloc'd new string. */
|
/* Execute a rule set on a string; returns a malloc'd new string. */
|
||||||
char *rewrite_string(const char *, const struct rule *, int);
|
char *rewrite_string(const char *, const struct rule *, int,
|
||||||
|
match_pattern_callback);
|
||||||
|
|
||||||
#endif /* WITH_REGEX */
|
#endif /* WITH_REGEX */
|
||||||
#endif /* TFTPD_REMAP_H */
|
#endif /* TFTPD_REMAP_H */
|
||||||
|
|
|
@ -177,12 +177,7 @@ Replace the substring matched by
|
||||||
.I regex
|
.I regex
|
||||||
by the
|
by the
|
||||||
.IR "replacement pattern" .
|
.IR "replacement pattern" .
|
||||||
The escape sequence
|
The replacement pattern may contain escape sequences; see below.
|
||||||
\\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.
|
|
||||||
.TP
|
.TP
|
||||||
.B g
|
.B g
|
||||||
Repeat this rule until it no longer matches. This is always used with
|
Repeat this rule until it no longer matches. This is always used with
|
||||||
|
@ -210,6 +205,35 @@ This rule applies to GET (RRQ) requests only.
|
||||||
.B P
|
.B P
|
||||||
This rule applies to PUT (WRQ) requests only.
|
This rule applies to PUT (WRQ) requests only.
|
||||||
.PP
|
.PP
|
||||||
|
The following escape sequences are recognized as part of the
|
||||||
|
.IR "replacement pattern" :
|
||||||
|
.TP
|
||||||
|
\fB\\0\fP
|
||||||
|
The entire string matched by the
|
||||||
|
.IR regex .
|
||||||
|
.TP
|
||||||
|
\fB\\1\fP to \fB\\9\fP
|
||||||
|
Match the first nine parentensized subexpressions, \\( ... \\) of the
|
||||||
|
.I regex
|
||||||
|
pattern.
|
||||||
|
.TP
|
||||||
|
\fB\\i\fP
|
||||||
|
The IP address of the requesting host, in dotted-quad notation
|
||||||
|
(e.g. 192.0.2.169).
|
||||||
|
.TP
|
||||||
|
\fB\\x\fP
|
||||||
|
The IP address of the requesting host, in hexadecimal notation
|
||||||
|
(e.g. C00002A9).
|
||||||
|
.TP
|
||||||
|
\fB\\\fP
|
||||||
|
Literal backslash.
|
||||||
|
.TP
|
||||||
|
\fB\\\fP\fIwhitespace\fP
|
||||||
|
Literal whitespace.
|
||||||
|
.TP
|
||||||
|
\fB\\#\fI
|
||||||
|
Literal hash mark.
|
||||||
|
.PP
|
||||||
If the mapping file is changed, you need to send
|
If the mapping file is changed, you need to send
|
||||||
.B SIGHUP
|
.B SIGHUP
|
||||||
to any outstanding
|
to any outstanding
|
||||||
|
|
|
@ -779,23 +779,64 @@ do_opt(char *opt, char *val, char **ap)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef WITH_REGEX
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This is called by the remap engine when it encounters macros such
|
||||||
|
* as \i. It should write the output in "output" if non-NULL, and
|
||||||
|
* return the length of the output (generated or not).
|
||||||
|
*
|
||||||
|
* Return -1 on failure.
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
rewrite_macros(char macro, char *output);
|
||||||
|
|
||||||
|
int
|
||||||
|
rewrite_macros(char macro, char *output)
|
||||||
|
{
|
||||||
|
char *p;
|
||||||
|
|
||||||
|
switch (macro) {
|
||||||
|
case 'i':
|
||||||
|
p = inet_ntoa(from.sin_addr);
|
||||||
|
if ( output )
|
||||||
|
strcpy(output, p);
|
||||||
|
return strlen(p);
|
||||||
|
|
||||||
|
case 'x':
|
||||||
|
if ( output )
|
||||||
|
sprintf(output, "%08X",
|
||||||
|
ntohl(from.sin_addr.s_addr));
|
||||||
|
return 8;
|
||||||
|
|
||||||
|
default:
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Modify the filename, if applicable. If it returns NULL, deny the access.
|
* Modify the filename, if applicable. If it returns NULL, deny the access.
|
||||||
*/
|
*/
|
||||||
char *
|
char *
|
||||||
rewrite_access(char *filename, int mode)
|
rewrite_access(char *filename, int mode)
|
||||||
{
|
{
|
||||||
#ifdef WITH_REGEX
|
|
||||||
if ( rewrite_rules ) {
|
if ( rewrite_rules ) {
|
||||||
char *newname = rewrite_string(filename, rewrite_rules, mode != RRQ);
|
char *newname = rewrite_string(filename, rewrite_rules,
|
||||||
|
mode != RRQ, rewrite_macros);
|
||||||
filename = newname;
|
filename = newname;
|
||||||
}
|
}
|
||||||
#else
|
|
||||||
(void)mode; /* Suppress unused warning */
|
|
||||||
#endif
|
|
||||||
return filename;
|
return filename;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#else
|
||||||
|
char *
|
||||||
|
rewrite_access(char *filename, int mode)
|
||||||
|
{
|
||||||
|
(void)mode; /* Avoid warning */
|
||||||
|
return filename;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
FILE *file;
|
FILE *file;
|
||||||
/*
|
/*
|
||||||
* Validate file access. Since we
|
* Validate file access. Since we
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue