Package: atftpd
Version: 0.7.dfsg-6
Severity: wishlist
Tags: patch
Hello!
The attached patch adds the possibility of adding the IP address of
the tftp client to the file path on the server side using $I.
With this extension it is possible, that each client sees only it's
own directory and files. So it is impossible that one client fetches
files that are dedicated to another client.
Example: The line
^(\S+)$ $I/$0
allows that each client has access to exactly the one well defined
directory (base dir appended with the client's IP address).
Regards
Andreas Florath
-- System Information:
Debian Release: 5.0
APT prefers unstable
APT policy: (500, 'unstable')
Architecture: i386 (x86_64)
Kernel: Linux 2.6.26-1-amd64 (SMP w/2 CPU cores)
Locale: LANG=en_US.UTF-8, LC_CTYPE=en_US.UTF-8 (charmap=UTF-8)
Shell: /bin/sh linked to /bin/bash
Versions of packages atftpd depends on:
ii debconf [debconf-2.0] 1.5.24 Debian configuration
management sy
ii libc6 2.7-16 GNU C Library: Shared libraries
ii libpcre3 7.8-2 Perl 5 Compatible Regular
Expressi
ii libwrap0 7.6.q-16 Wietse Venema's TCP
wrappers libra
ii openbsd-inetd [inet-superse 0.20080125-2 The OpenBSD Internet
Superserver
atftpd recommends no packages.
Versions of packages atftpd suggests:
ii logrotate 3.7.7-2 Log rotation utility
-- debconf information excluded
diff -ru atftp-0.7.dfsg-6_orig/test/pcre_pattern.txt
atftp-0.7.dfsg-6/test/pcre_pattern.txt
--- atftp-0.7.dfsg-6_orig/test/pcre_pattern.txt 2003-02-21
06:46:04.000000000 +0100
+++ atftp-0.7.dfsg-6/test/pcre_pattern.txt 2008-12-22
14:34:10.000000000 +0100
@@ -6,3 +6,4 @@
str$ replaced3
repl(ace) m$1
^\w*\.conf$ master.conf
+^iptest/(\S+)$ $I/$1
diff -ru atftp-0.7.dfsg-6_orig/tftpd.c atftp-0.7.dfsg-6/tftpd.c
--- atftp-0.7.dfsg-6_orig/tftpd.c 2008-12-22 14:59:32.000000000 +0100
+++ atftp-0.7.dfsg-6/tftpd.c 2008-12-22 12:11:35.000000000 +0100
@@ -962,7 +962,7 @@
/* remove \n from input */
string[strlen(string) - 1] = '\0';
/* do the substitution */
- if (tftpd_pcre_sub(pcre_top, out, MAXLEN, string) < 0)
+ if (tftpd_pcre_sub(pcre_top, out, MAXLEN, string,
0x7f000001) < 0)
printf("Substitution: \"%s\" -> \"\"\n", string);
else
printf("Substitution: \"%s\" -> \"%s\"\n",
string, out);
diff -ru atftp-0.7.dfsg-6_orig/tftpd_file.c atftp-0.7.dfsg-6/tftpd_file.c
--- atftp-0.7.dfsg-6_orig/tftpd_file.c 2004-02-18 03:21:47.000000000
+0100
+++ atftp-0.7.dfsg-6/tftpd_file.c 2008-12-22 14:55:48.000000000 +0100
@@ -409,7 +409,7 @@
struct sockaddr_in from;
int sockfd = data->sockfd;
struct tftphdr *tftphdr = (struct tftphdr *)data->data_buffer;
- FILE *fp;
+ FILE *fp = NULL;
char filename[MAXLEN];
char string[MAXLEN];
int timeout = data->timeout;
@@ -429,7 +429,7 @@
int prev_file_pos = 0;
int temp = 0;
- /* look for mode option */
+ /* look for mode option */
if (strcasecmp(data->tftp_options[OPT_MODE].value, "netascii") == 0)
{
convert = 1;
@@ -448,9 +448,6 @@
return ERR;
}
- /* verify that the requested file exist */
- fp = fopen(filename, "r");
-
#ifdef HAVE_PCRE
if (fp == NULL)
{
@@ -458,7 +455,8 @@
if (pcre_top != NULL)
{
if (tftpd_pcre_sub(pcre_top, string, MAXLEN,
-
data->tftp_options[OPT_FILENAME].value) < 0)
+ data->tftp_options[OPT_FILENAME].value,
+ ntohl(sa->sin_addr.s_addr)) < 0)
{
logger(LOG_DEBUG, "PCRE failed to match");
}
@@ -484,6 +482,9 @@
}
}
}
+#else
+ /* verify that the requested file exist */
+ fp = fopen(filename, "r");
#endif
if (fp == NULL)
{
diff -ru atftp-0.7.dfsg-6_orig/tftpd_pcre.c atftp-0.7.dfsg-6/tftpd_pcre.c
--- atftp-0.7.dfsg-6_orig/tftpd_pcre.c 2008-12-22 14:59:32.000000000
+0100
+++ atftp-0.7.dfsg-6/tftpd_pcre.c 2008-12-22 15:13:04.000000000 +0100
@@ -195,7 +195,7 @@
int tftpd_pcre_makesub(struct tftpd_pcre_pattern *pat,
char *outstr, int outsize,
char *str,
- int *ovector, int matches)
+ int *ovector, int matches, in_addr_t client_ip)
{
char *chp, *outchp;
const char *tmpstr;
@@ -231,6 +231,24 @@
break;
}
}
+ else if ((*chp == '$') && (*(chp+1) == 'I'))
+ {
+ /* inet_ntoa is not thread safe */
+ char buffer[16];
+ int const ipsize =
+ snprintf(buffer, 16, "%d.%d.%d.%d",
+ (client_ip>>24) & 0xff,
+ (client_ip>>16) & 0xff,
+ (client_ip>> 8) & 0xff,
+ client_ip & 0xff);
+ chp++;
+ if (outchp - outstr + ipsize + 1 < outsize)
+ {
+ Strncpy(outchp, buffer, ipsize + 1);
+ outchp += ipsize;
+ continue;
+ }
+ }
else
{
*outchp = *chp;
@@ -243,7 +261,7 @@
/* search for a replacement and return a string after substituation */
/* if no match is found return -1 */
-int tftpd_pcre_sub(tftpd_pcre_self_t *self, char *outstr, int outlen,
char *str)
+int tftpd_pcre_sub(tftpd_pcre_self_t *self, char *outstr, int outlen,
char *str, in_addr_t client_ip)
{
int rc;
int ovector[OVECCOUNT];
@@ -279,7 +297,7 @@
rc = tftpd_pcre_makesub(pat,
outstr, outlen,
str,
- ovector, matches);
+ ovector, matches, client_ip);
logger(LOG_DEBUG,"outstr: \"%s\"", outstr);
pthread_mutex_unlock(&self->lock);
return 0;
diff -ru atftp-0.7.dfsg-6_orig/tftpd_pcre.h atftp-0.7.dfsg-6/tftpd_pcre.h
--- atftp-0.7.dfsg-6_orig/tftpd_pcre.h 2003-02-21 06:06:06.000000000
+0100
+++ atftp-0.7.dfsg-6/tftpd_pcre.h 2008-12-22 12:09:43.000000000 +0100
@@ -67,7 +67,7 @@
/* function prototypes */
tftpd_pcre_self_t *tftpd_pcre_open(char *filename);
char *tftpd_pcre_getfilename(tftpd_pcre_self_t *self);
-int tftpd_pcre_sub(tftpd_pcre_self_t *self, char *outstr, int outlen,
char *str);
+int tftpd_pcre_sub(tftpd_pcre_self_t *self, char *outstr, int outlen,
char *str, in_addr_t client_ip);
void tftpd_pcre_close(tftpd_pcre_self_t *self);
#endif
--
To UNSUBSCRIBE, email to [email protected]
with a subject of "unsubscribe". Trouble? Contact [email protected]