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 debian-bugs-dist-requ...@lists.debian.org with a subject of "unsubscribe". Trouble? Contact listmas...@lists.debian.org