Actually integrate the regex rewriting stuff

This commit is contained in:
hpa 2001-07-10 06:14:20 +00:00
parent 7b993e8186
commit 428ecab386
2 changed files with 50 additions and 10 deletions

View file

@ -17,12 +17,17 @@
#include <stdlib.h> #include <stdlib.h>
#include <stdio.h> #include <stdio.h>
#include "../config.h"
/* Opaque type */ /* Opaque type */
struct rule; struct rule;
#ifdef WITH_REGEX
/* Read a rule file */ /* Read a rule file */
struct rule *parserulefile(FILE *); struct rule *parserulefile(FILE *);
/* 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, int is_put); char *rewrite_string(const char *, const struct rule *, int);
#endif

View file

@ -77,9 +77,7 @@ static const char *rcsid = "tftp-hpa $Id$";
#include "../config.h" #include "../config.h"
#include "tftpsubs.h" #include "tftpsubs.h"
#include "recvfrom.h" #include "recvfrom.h"
#ifdef WITH_REGEX
#include "remap.h" #include "remap.h"
#endif
#ifdef HAVE_TCPWRAPPERS #ifdef HAVE_TCPWRAPPERS
#include <tcpd.h> #include <tcpd.h>
@ -130,6 +128,7 @@ int secure = 0;
int cancreate = 0; int cancreate = 0;
struct formats; struct formats;
static struct rule *rewrite_rules = NULL;
int tftp(struct tftphdr *, int); int tftp(struct tftphdr *, int);
void nak(int); void nak(int);
@ -158,7 +157,7 @@ struct options {
static void static void
usage(void) usage(void)
{ {
syslog(LOG_ERR, "Usage: %s [-c] [-u user] [-t timeout] [-r option...] [-s] [directory ...]", syslog(LOG_ERR, "Usage: %s [-c] [-m mappings] [-u user] [-t timeout] [-r option...] [-s] [directory ...]",
__progname); __progname);
exit(1); exit(1);
} }
@ -183,7 +182,7 @@ main(int argc, char **argv)
openlog(__progname, LOG_PID | LOG_NDELAY, LOG_DAEMON); openlog(__progname, LOG_PID | LOG_NDELAY, LOG_DAEMON);
while ((c = getopt(argc, argv, "csu:r:t:")) != -1) while ((c = getopt(argc, argv, "csu:r:t:m:")) != -1)
switch (c) { switch (c) {
case 'c': case 'c':
cancreate = 1; cancreate = 1;
@ -209,7 +208,24 @@ main(int argc, char **argv)
exit(1); exit(1);
} }
break; break;
#ifdef WITH_REGEX
case 'm':
{
FILE *f;
if ( rewrite_rules ) {
syslog(LOG_ERR, "Multiple -m options");
exit(1);
}
f = fopen(optarg, "rt");
if ( !f ) {
syslog(LOG_ERR, "Cannot open map file: %s: %m", optarg);
exit(1);
}
rewrite_rules = parserulefile(f);
fclose(f);
}
break;
#endif
default: default:
usage(); usage();
break; break;
@ -372,20 +388,22 @@ main(int argc, char **argv)
exit(0); exit(0);
} }
char *rewrite_access(char *, int);
int validate_access(char *, int, struct formats *); int validate_access(char *, int, struct formats *);
void sendfile(struct formats *, struct tftphdr *, int); void sendfile(struct formats *, struct tftphdr *, int);
void recvfile(struct formats *, struct tftphdr *, int); void recvfile(struct formats *, struct tftphdr *, int);
struct formats { struct formats {
char *f_mode; char *f_mode;
char *(*f_rewrite)(char *, int);
int (*f_validate)(char *, int, struct formats *); int (*f_validate)(char *, int, struct formats *);
void (*f_send)(struct formats *, struct tftphdr *, int); void (*f_send)(struct formats *, struct tftphdr *, int);
void (*f_recv)(struct formats *, struct tftphdr *, int); void (*f_recv)(struct formats *, struct tftphdr *, int);
int f_convert; int f_convert;
} formats[] = { } formats[] = {
{ "netascii", validate_access, sendfile, recvfile, 1 }, { "netascii", rewrite_access, validate_access, sendfile, recvfile, 1 },
{ "octet", validate_access, sendfile, recvfile, 0 }, { "octet", rewrite_access, validate_access, sendfile, recvfile, 0 },
{ NULL, NULL, NULL, NULL, 0 } { NULL, NULL, NULL, NULL, NULL, 0 }
}; };
/* /*
@ -431,6 +449,10 @@ tftp(struct tftphdr *tp, int size)
nak(EBADOP); nak(EBADOP);
exit(0); exit(0);
} }
if ( !(filename = (*pf->f_rewrite)(filename, tp->th_opcode)) ) {
nak(EACCES); /* File denied by mapping rule */
exit(0);
}
ecode = (*pf->f_validate)(filename, tp->th_opcode, pf); ecode = (*pf->f_validate)(filename, tp->th_opcode, pf);
if (ecode) { if (ecode) {
nak(ecode); nak(ecode);
@ -599,9 +621,22 @@ do_opt(char *opt, char *val, char **ap)
return; return;
} }
/*
* Modify the filename, if applicable. If it returns NULL, deny the access.
*/
char *
rewrite_access(char *filename, int mode)
{
#ifdef WITH_REGEX
if ( rewrite_rules ) {
char *newname = rewrite_string(filename, rewrite_rules, mode != RRQ);
filename = newname;
}
#endif
return filename;
}
FILE *file; FILE *file;
/* /*
* Validate file access. Since we * Validate file access. Since we
* have no uid or gid, for now require * have no uid or gid, for now require