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 | ||||
|  *   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
	
	 H. Peter Anvin
						H. Peter Anvin