1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
|
diff -Nwaur tftp-hpa-5.2/tftpd/tftpd.c a/tftpd/tftpd.c
--- tftp-hpa-5.2/tftpd/tftpd.c 2011-12-11 23:13:52.000000000 +0100
+++ a/tftpd/tftpd.c 2016-02-25 16:36:45.924132163 +0100
@@ -112,6 +112,9 @@
static struct rule *rewrite_rules = NULL;
#endif
+static int selfdestruct_if_ipv4addr_in_hex_matches_filename = 0;
+static int selfdestruct(const char *filename);
+
int tftp(struct tftphdr *, int);
static void nak(int, const char *);
static void timer(int);
@@ -180,6 +183,25 @@
}
#endif
+static int selfdestruct(const char *filename)
+{
+ /* not IPv4 */
+ if (from.sa.sa_family != AF_INET) {
+ return 0;
+ }
+
+ char ip_str[9];
+ snprintf(ip_str, sizeof ip_str, "%08lX",
+ (unsigned long)ntohl(from.si.sin_addr.s_addr));
+
+ const char *tmp = strrchr(filename, '/');
+ if (tmp) {
+ filename = tmp + 1;
+ }
+
+ return !strcasecmp(filename, ip_str);
+}
+
/*
* Rules for locking files; return 0 on success, -1 on failure
*/
@@ -324,6 +346,7 @@
enum long_only_options {
OPT_VERBOSITY = 256,
+ OPT_SELFDESTRUCT,
};
static struct option long_options[] = {
@@ -347,6 +370,8 @@
{ "port-range", 1, NULL, 'R' },
{ "map-file", 1, NULL, 'm' },
{ "pidfile", 1, NULL, 'P' },
+ { "selfdestruct-if-ipv4addr-in-hex-matches-filename",
+ 0, NULL, OPT_SELFDESTRUCT },
{ NULL, 0, NULL, 0 }
};
static const char short_options[] = "46cspvVlLa:B:u:U:r:t:T:R:m:P:";
@@ -494,6 +519,9 @@
rewrite_file = optarg;
break;
#endif
+ case OPT_SELFDESTRUCT:
+ selfdestruct_if_ipv4addr_in_hex_matches_filename = 1;
+ break;
case 'v':
verbosity++;
break;
@@ -1498,6 +1526,15 @@
}
}
+ if (mode == RRQ && selfdestruct_if_ipv4addr_in_hex_matches_filename &&
+ selfdestruct(filename)) {
+ syslog(LOG_NOTICE, "unlinking file \"%s\"\n", filename);
+ if (unlink(filename)) {
+ syslog(LOG_WARNING, "error unlinking \"%s\": %s\n",
+ filename, strerror(errno));
+ }
+ }
+
if (fstat(fd, &stbuf) < 0)
exit(EX_OSERR); /* This shouldn't happen */
|