mirror of
https://kernel.googlesource.com/pub/scm/network/tftp/tftp-hpa
synced 2025-05-01 20:39:58 +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
|
* This program is free software available under the same license
|
||||||
* as the "OpenBSD" operating system, distributed at
|
* 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_RESTART 0x08 /* Restart at the top after matching this rule */
|
||||||
#define RULE_ABORT 0x10 /* Terminate processing with an error */
|
#define RULE_ABORT 0x10 /* Terminate processing with an error */
|
||||||
#define RULE_INVERSE 0x20 /* Execute if regex *doesn't* match */
|
#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 {
|
||||||
struct rule *next;
|
struct rule *next;
|
||||||
|
@ -223,6 +225,12 @@ static int parseline(char *line, struct rule *r, int lineno)
|
||||||
case '~':
|
case '~':
|
||||||
r->rule_flags |= RULE_INVERSE;
|
r->rule_flags |= RULE_INVERSE;
|
||||||
break;
|
break;
|
||||||
|
case '4':
|
||||||
|
r->rule_flags |= RULE_IPV4;
|
||||||
|
break;
|
||||||
|
case '6':
|
||||||
|
r->rule_flags |= RULE_IPV6;
|
||||||
|
break;
|
||||||
case 'G':
|
case 'G':
|
||||||
case 'P':
|
case 'P':
|
||||||
r->rule_mode = *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. */
|
/* Execute a rule set on a string; returns a malloc'd new string. */
|
||||||
char *rewrite_string(const char *input, const struct rule *rules,
|
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)
|
const char **errmsg)
|
||||||
{
|
{
|
||||||
char *current = tfstrdup(input);
|
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)
|
if (ruleptr->rule_mode && ruleptr->rule_mode != mode)
|
||||||
continue; /* Rule not applicable, try next */
|
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--) {
|
if (!deadman--) {
|
||||||
syslog(LOG_WARNING,
|
syslog(LOG_WARNING,
|
||||||
"remap: Breaking loop, input = %s, last = %s", input,
|
"remap: Breaking loop, input = %s, last = %s", input,
|
||||||
|
|
|
@ -35,7 +35,7 @@ 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 *, char,
|
char *rewrite_string(const char *, const struct rule *, char, int,
|
||||||
match_pattern_callback, const char **);
|
match_pattern_callback, const char **);
|
||||||
|
|
||||||
#endif /* WITH_REGEX */
|
#endif /* WITH_REGEX */
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 1983 Regents of the University of California.
|
* Copyright (c) 1983 Regents of the University of California.
|
||||||
* Copyright (c) 1999-2009 H. Peter Anvin
|
* 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.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
@ -1043,14 +1043,14 @@ int main(int argc, char **argv)
|
||||||
exit(0);
|
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 int validate_access(char *, int, const struct formats *, const char **);
|
||||||
static void tftp_sendfile(const struct formats *, struct tftphdr *, int);
|
static void tftp_sendfile(const struct formats *, struct tftphdr *, int);
|
||||||
static void tftp_recvfile(const struct formats *, struct tftphdr *, int);
|
static void tftp_recvfile(const struct formats *, struct tftphdr *, int);
|
||||||
|
|
||||||
struct formats {
|
struct formats {
|
||||||
const char *f_mode;
|
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 **);
|
int (*f_validate) (char *, int, const struct formats *, const char **);
|
||||||
void (*f_send) (const struct formats *, struct tftphdr *, int);
|
void (*f_send) (const struct formats *, struct tftphdr *, int);
|
||||||
void (*f_recv) (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");
|
nak(EBADOP, "Unknown mode");
|
||||||
exit(0);
|
exit(0);
|
||||||
}
|
}
|
||||||
if (!(filename =
|
if (!(filename = (*pf->f_rewrite)
|
||||||
(*pf->f_rewrite) (origfilename, tp_opcode,
|
(origfilename, tp_opcode, from.sa.sa_family, &errmsgptr))) {
|
||||||
&errmsgptr))) {
|
|
||||||
nak(EACCESS, errmsgptr); /* File denied by mapping rule */
|
nak(EACCESS, errmsgptr); /* File denied by mapping rule */
|
||||||
exit(0);
|
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.
|
* 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) {
|
if (rewrite_rules) {
|
||||||
char *newname =
|
char *newname =
|
||||||
rewrite_string(filename, rewrite_rules,
|
rewrite_string(filename, rewrite_rules,
|
||||||
mode != RRQ ? 'P' : 'G',
|
mode != RRQ ? 'P' : 'G', af,
|
||||||
rewrite_macros, msg);
|
rewrite_macros, msg);
|
||||||
filename = newname;
|
filename = newname;
|
||||||
}
|
}
|
||||||
|
@ -1411,10 +1411,11 @@ static char *rewrite_access(char *filename, int mode, const char **msg)
|
||||||
}
|
}
|
||||||
|
|
||||||
#else
|
#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)mode; /* Avoid warning */
|
||||||
(void)msg;
|
(void)msg;
|
||||||
|
(void)af;
|
||||||
return filename;
|
return filename;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue