forked from mirrors/tftp-hpa-google
		
	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 | ||||||
|  | @ -1039,18 +1039,18 @@ int main(int argc, char **argv) | ||||||
|     tp = (struct tftphdr *)buf; |     tp = (struct tftphdr *)buf; | ||||||
|     tp_opcode = ntohs(tp->th_opcode); |     tp_opcode = ntohs(tp->th_opcode); | ||||||
|     if (tp_opcode == RRQ || tp_opcode == WRQ) |     if (tp_opcode == RRQ || tp_opcode == WRQ) | ||||||
|         tftp(tp, n); | 	tftp(tp, n); | ||||||
|     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
	
	 H. Peter Anvin
						H. Peter Anvin