mirror of
https://kernel.googlesource.com/pub/scm/network/tftp/tftp-hpa
synced 2025-04-26 01:49:52 +03:00
tftpd: allow IPv4/6-specific remapping rules
Allow remapping rules to be conditional on IPv4 vs IPv6. Signed-off-by: H. Peter Anvin <hpa@zytor.com>
This commit is contained in:
parent
c89a63a441
commit
18ee96a03f
3 changed files with 28 additions and 13 deletions
|
@ -1,6 +1,6 @@
|
|||
/* ----------------------------------------------------------------------- *
|
||||
*
|
||||
* Copyright 2001-2007 H. Peter Anvin - All Rights Reserved
|
||||
* Copyright 2001-2014 H. Peter Anvin - All Rights Reserved
|
||||
*
|
||||
* This program is free software available under the same license
|
||||
* as the "OpenBSD" operating system, distributed at
|
||||
|
@ -31,6 +31,8 @@
|
|||
#define RULE_RESTART 0x08 /* Restart at the top after matching this rule */
|
||||
#define RULE_ABORT 0x10 /* Terminate processing with an error */
|
||||
#define RULE_INVERSE 0x20 /* Execute if regex *doesn't* match */
|
||||
#define RULE_IPV4 0x40 /* IPv4 only */
|
||||
#define RULE_IPV6 0x80 /* IPv6 only */
|
||||
|
||||
struct rule {
|
||||
struct rule *next;
|
||||
|
@ -223,6 +225,12 @@ static int parseline(char *line, struct rule *r, int lineno)
|
|||
case '~':
|
||||
r->rule_flags |= RULE_INVERSE;
|
||||
break;
|
||||
case '4':
|
||||
r->rule_flags |= RULE_IPV4;
|
||||
break;
|
||||
case '6':
|
||||
r->rule_flags |= RULE_IPV6;
|
||||
break;
|
||||
case 'G':
|
||||
case 'P':
|
||||
r->rule_mode = *p;
|
||||
|
@ -326,7 +334,7 @@ void freerules(struct rule *r)
|
|||
|
||||
/* Execute a rule set on a string; returns a malloc'd new string. */
|
||||
char *rewrite_string(const char *input, const struct rule *rules,
|
||||
char mode, match_pattern_callback macrosub,
|
||||
char mode, int af, match_pattern_callback macrosub,
|
||||
const char **errmsg)
|
||||
{
|
||||
char *current = tfstrdup(input);
|
||||
|
@ -348,6 +356,12 @@ char *rewrite_string(const char *input, const struct rule *rules,
|
|||
if (ruleptr->rule_mode && ruleptr->rule_mode != mode)
|
||||
continue; /* Rule not applicable, try next */
|
||||
|
||||
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--) {
|
||||
syslog(LOG_WARNING,
|
||||
"remap: Breaking loop, input = %s, last = %s", input,
|
||||
|
|
|
@ -35,7 +35,7 @@ struct rule *parserulefile(FILE *);
|
|||
void freerules(struct rule *);
|
||||
|
||||
/* Execute a rule set on a string; returns a malloc'd new string. */
|
||||
char *rewrite_string(const char *, const struct rule *, char,
|
||||
char *rewrite_string(const char *, const struct rule *, char, int,
|
||||
match_pattern_callback, const char **);
|
||||
|
||||
#endif /* WITH_REGEX */
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
* Copyright (c) 1983 Regents of the University of California.
|
||||
* Copyright (c) 1999-2009 H. Peter Anvin
|
||||
* Copyright (c) 2011 Intel Corporation; author: H. Peter Anvin
|
||||
* Copyright (c) 2011-2014 Intel Corporation; author: H. Peter Anvin
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
|
@ -1039,18 +1039,18 @@ int main(int argc, char **argv)
|
|||
tp = (struct tftphdr *)buf;
|
||||
tp_opcode = ntohs(tp->th_opcode);
|
||||
if (tp_opcode == RRQ || tp_opcode == WRQ)
|
||||
tftp(tp, n);
|
||||
tftp(tp, n);
|
||||
exit(0);
|
||||
}
|
||||
|
||||
static char *rewrite_access(char *, int, const char **);
|
||||
static char *rewrite_access(char *, int, int, const char **);
|
||||
static int validate_access(char *, int, const struct formats *, const char **);
|
||||
static void tftp_sendfile(const struct formats *, struct tftphdr *, int);
|
||||
static void tftp_recvfile(const struct formats *, struct tftphdr *, int);
|
||||
|
||||
struct formats {
|
||||
const char *f_mode;
|
||||
char *(*f_rewrite) (char *, int, const char **);
|
||||
char *(*f_rewrite) (char *, int, int, const char **);
|
||||
int (*f_validate) (char *, int, const struct formats *, const char **);
|
||||
void (*f_send) (const struct formats *, struct tftphdr *, int);
|
||||
void (*f_recv) (const struct formats *, struct tftphdr *, int);
|
||||
|
@ -1112,9 +1112,8 @@ int tftp(struct tftphdr *tp, int size)
|
|||
nak(EBADOP, "Unknown mode");
|
||||
exit(0);
|
||||
}
|
||||
if (!(filename =
|
||||
(*pf->f_rewrite) (origfilename, tp_opcode,
|
||||
&errmsgptr))) {
|
||||
if (!(filename = (*pf->f_rewrite)
|
||||
(origfilename, tp_opcode, from.sa.sa_family, &errmsgptr))) {
|
||||
nak(EACCESS, errmsgptr); /* File denied by mapping rule */
|
||||
exit(0);
|
||||
}
|
||||
|
@ -1398,12 +1397,13 @@ static int rewrite_macros(char macro, char *output)
|
|||
/*
|
||||
* Modify the filename, if applicable. If it returns NULL, deny the access.
|
||||
*/
|
||||
static char *rewrite_access(char *filename, int mode, const char **msg)
|
||||
static char *rewrite_access(char *filename, int mode, int af,
|
||||
const char **msg)
|
||||
{
|
||||
if (rewrite_rules) {
|
||||
char *newname =
|
||||
rewrite_string(filename, rewrite_rules,
|
||||
mode != RRQ ? 'P' : 'G',
|
||||
mode != RRQ ? 'P' : 'G', af,
|
||||
rewrite_macros, msg);
|
||||
filename = newname;
|
||||
}
|
||||
|
@ -1411,10 +1411,11 @@ static char *rewrite_access(char *filename, int mode, const char **msg)
|
|||
}
|
||||
|
||||
#else
|
||||
static char *rewrite_access(char *filename, int mode, const char **msg)
|
||||
static char *rewrite_access(char *filename, int mode, int af, const char **msg)
|
||||
{
|
||||
(void)mode; /* Avoid warning */
|
||||
(void)msg;
|
||||
(void)af;
|
||||
return filename;
|
||||
}
|
||||
#endif
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue