forked from mirrors/tftp-hpa-google
tftpd: handle rule filter flags more cleanly
Instead of a bunch of ad hoc tests, keep a bitmask of flags that would keep this rule from being executed. This also removes the ugly hack of converting the request mode between opcode and character encodings for really no good reason. Signed-off-by: H. Peter Anvin <hpa@zytor.com>
This commit is contained in:
parent
6f96fcd1b6
commit
351907e3f0
3 changed files with 22 additions and 21 deletions
|
@ -35,12 +35,13 @@
|
||||||
#define RULE_IPV6 0x80 /* IPv6 only */
|
#define RULE_IPV6 0x80 /* IPv6 only */
|
||||||
|
|
||||||
#define RULE_HASFILE 0x100 /* Valid if rule results in a valid filename */
|
#define RULE_HASFILE 0x100 /* Valid if rule results in a valid filename */
|
||||||
|
#define RULE_RRQ 0x200 /* Get (read) only */
|
||||||
|
#define RULE_WRQ 0x400 /* Put (write) only */
|
||||||
|
|
||||||
struct rule {
|
struct rule {
|
||||||
struct rule *next;
|
struct rule *next;
|
||||||
int nrule;
|
int nrule;
|
||||||
int rule_flags;
|
unsigned int rule_flags;
|
||||||
char rule_mode;
|
|
||||||
regex_t rx;
|
regex_t rx;
|
||||||
const char *pattern;
|
const char *pattern;
|
||||||
};
|
};
|
||||||
|
@ -164,7 +165,7 @@ static int readescstring(char *buf, char **str)
|
||||||
int wasbs = 0, len = 0;
|
int wasbs = 0, len = 0;
|
||||||
|
|
||||||
while (*p && isspace(*p))
|
while (*p && isspace(*p))
|
||||||
p++;
|
p++;
|
||||||
|
|
||||||
if (!*p) {
|
if (!*p) {
|
||||||
*buf = '\0';
|
*buf = '\0';
|
||||||
|
@ -237,9 +238,11 @@ static int parseline(char *line, struct rule *r, int lineno)
|
||||||
r->rule_flags |= RULE_IPV6;
|
r->rule_flags |= RULE_IPV6;
|
||||||
break;
|
break;
|
||||||
case 'G':
|
case 'G':
|
||||||
|
r->rule_flags |= RULE_RRQ;
|
||||||
|
break;
|
||||||
case 'P':
|
case 'P':
|
||||||
r->rule_mode = *p;
|
r->rule_flags |= RULE_WRQ;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
syslog(LOG_ERR,
|
syslog(LOG_ERR,
|
||||||
"Remap command \"%s\" on line %d contains invalid char \"%c\"",
|
"Remap command \"%s\" on line %d contains invalid char \"%c\"",
|
||||||
|
@ -346,7 +349,7 @@ 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 struct formats *pf,
|
char *rewrite_string(const struct formats *pf,
|
||||||
const char *input, const struct rule *rules,
|
const char *input, const struct rule *rules,
|
||||||
char mode, int af, match_pattern_callback macrosub,
|
int mode, int af, match_pattern_callback macrosub,
|
||||||
const char **errmsg)
|
const char **errmsg)
|
||||||
{
|
{
|
||||||
char *current = tfstrdup(input);
|
char *current = tfstrdup(input);
|
||||||
|
@ -357,6 +360,7 @@ char *rewrite_string(const struct formats *pf,
|
||||||
int len;
|
int len;
|
||||||
int was_match = 0;
|
int was_match = 0;
|
||||||
int deadman = DEADMAN_MAX_STEPS;
|
int deadman = DEADMAN_MAX_STEPS;
|
||||||
|
unsigned int bad_flags;
|
||||||
|
|
||||||
/* Default error */
|
/* Default error */
|
||||||
*errmsg = "Remap table failure";
|
*errmsg = "Remap table failure";
|
||||||
|
@ -365,15 +369,15 @@ char *rewrite_string(const struct formats *pf,
|
||||||
syslog(LOG_INFO, "remap: input: %s", current);
|
syslog(LOG_INFO, "remap: input: %s", current);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bad_flags = 0;
|
||||||
|
if (mode != RRQ) bad_flags |= RULE_RRQ;
|
||||||
|
if (mode != WRQ) bad_flags |= RULE_WRQ;
|
||||||
|
if (af != AF_INET) bad_flags |= RULE_IPV4;
|
||||||
|
if (af != AF_INET6) bad_flags |= RULE_IPV6;
|
||||||
|
|
||||||
for (ruleptr = rules; ruleptr; ruleptr = ruleptr->next) {
|
for (ruleptr = rules; ruleptr; ruleptr = ruleptr->next) {
|
||||||
if (ruleptr->rule_mode && ruleptr->rule_mode != mode)
|
if (ruleptr->rule_flags & bad_flags)
|
||||||
continue; /* Rule not applicable, try next */
|
continue; /* This rule is excluded by flags */
|
||||||
|
|
||||||
if ((ruleptr->rule_flags & RULE_IPV4) && (af != AF_INET))
|
|
||||||
continue; /* Rule not applicable, try next */
|
|
||||||
|
|
||||||
if ((ruleptr->rule_flags & RULE_IPV6) && (af != AF_INET6))
|
|
||||||
continue; /* Rule not applicable, try next */
|
|
||||||
|
|
||||||
if (!deadman--) {
|
if (!deadman--) {
|
||||||
syslog(LOG_WARNING,
|
syslog(LOG_WARNING,
|
||||||
|
@ -424,8 +428,7 @@ char *rewrite_string(const struct formats *pf,
|
||||||
genmatchstring(newstr, ruleptr->pattern, current,
|
genmatchstring(newstr, ruleptr->pattern, current,
|
||||||
pmatch, macrosub);
|
pmatch, macrosub);
|
||||||
if ((ruleptr->rule_flags & RULE_HASFILE) &&
|
if ((ruleptr->rule_flags & RULE_HASFILE) &&
|
||||||
pf->f_validate(newstr, mode == 'G' ? RRQ : WRQ,
|
pf->f_validate(newstr, mode, pf, &accerr)) {
|
||||||
pf, &accerr)) {
|
|
||||||
if (verbosity >= 3) {
|
if (verbosity >= 3) {
|
||||||
syslog(LOG_INFO, "remap: rule %d: ignored rewrite (%s): %s",
|
syslog(LOG_INFO, "remap: rule %d: ignored rewrite (%s): %s",
|
||||||
ruleptr->nrule, accerr, newstr);
|
ruleptr->nrule, accerr, newstr);
|
||||||
|
@ -441,8 +444,7 @@ char *rewrite_string(const struct formats *pf,
|
||||||
ruleptr->nrule, current);
|
ruleptr->nrule, current);
|
||||||
}
|
}
|
||||||
} else if (ruleptr->rule_flags & RULE_HASFILE) {
|
} else if (ruleptr->rule_flags & RULE_HASFILE) {
|
||||||
if (pf->f_validate(current, mode == 'G' ? RRQ : WRQ,
|
if (pf->f_validate(current, mode, pf, &accerr)) {
|
||||||
pf, &accerr)) {
|
|
||||||
if (verbosity >= 3) {
|
if (verbosity >= 3) {
|
||||||
syslog(LOG_INFO, "remap: rule %d: not exiting (%s)\n",
|
syslog(LOG_INFO, "remap: rule %d: not exiting (%s)\n",
|
||||||
ruleptr->nrule, accerr);
|
ruleptr->nrule, accerr);
|
||||||
|
|
|
@ -37,7 +37,7 @@ 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. */
|
||||||
struct formats;
|
struct formats;
|
||||||
char *rewrite_string(const struct formats *, const char *,
|
char *rewrite_string(const struct formats *, const char *,
|
||||||
const struct rule *, char, int,
|
const struct rule *, int, int,
|
||||||
match_pattern_callback, const char **);
|
match_pattern_callback, const char **);
|
||||||
|
|
||||||
#endif /* WITH_REGEX */
|
#endif /* WITH_REGEX */
|
||||||
|
|
|
@ -1417,8 +1417,7 @@ static char *rewrite_access(const struct formats *pf, char *filename,
|
||||||
{
|
{
|
||||||
if (rewrite_rules) {
|
if (rewrite_rules) {
|
||||||
char *newname =
|
char *newname =
|
||||||
rewrite_string(pf, filename, rewrite_rules,
|
rewrite_string(pf, filename, rewrite_rules, mode, af,
|
||||||
mode != RRQ ? 'P' : 'G', af,
|
|
||||||
rewrite_macros, msg);
|
rewrite_macros, msg);
|
||||||
filename = newname;
|
filename = newname;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue