* Case insensitive lookup patch for tftp-hpa * * Copyright (c) 2006-2007 Gianluigi Tiesi * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public * License along with this software; if not, write to the * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA diff -ur tftp-hpa-0.40.orig/tftpd/tftpd.c tftp-hpa-0.40/tftpd/tftpd.c --- tftp-hpa-0.40.orig/tftpd/tftpd.c 2004-09-15 00:38:46.000000000 +0200 +++ tftp-hpa-0.40/tftpd/tftpd.c 2006-02-17 23:41:31.000000000 +0100 @@ -61,6 +61,7 @@ #include #include #include +#include #include "tftpsubs.h" #include "recvfrom.h" @@ -713,6 +714,9 @@ void tftp_sendfile(struct formats *, struct tftphdr *, int); void tftp_recvfile(struct formats *, struct tftphdr *, int); +int lookup_entry(const char *comp, char *dest); +void lookup_file(char *filename); + struct formats { const char *f_mode; char *(*f_rewrite)(char *, int, const char **); @@ -1049,6 +1053,64 @@ } #endif + +int lookup_entry(const char *comp, char *dest) +{ + DIR *dirp; + struct dirent *dptr; + dirp = opendir(dest[0] ? dest : "."); + if (!dirp) return 0; + while ((dptr = readdir(dirp))) + { + if (!strcasecmp(dptr->d_name, comp)) + { + if (dest[0]) strcat(dest, "/"); + strcat(dest, dptr->d_name); + closedir(dirp); + return 1; + } + } + closedir(dirp); + return 0; +} + + +void lookup_file(char *filename) +{ + int found = 0; + int len = 0; + char dest[1024]; + char comp[1024]; + char *check = filename; + char *seek = NULL; + + dest[0] = 0; + check++; + while (*check) + { + seek = strchr(check, '\\'); + if (!seek) + { + if ((*check) && (lookup_entry(check, dest))) + found = 1; + break; + } + len = seek - check; + memcpy(comp, check, len); + comp[len]=0; + if (!lookup_entry(comp, dest)) + break; + check += len + 1; + } + + if (found) + { + filename[0] = 0; + strcat(filename, dest); + } +} + + FILE *file; /* * Validate file access. Since we @@ -1075,6 +1137,8 @@ tsize_ok = 0; *errmsg = NULL; + if (*filename == '\\') lookup_file(filename); + if (!secure) { if (*filename != '/') { *errmsg = "Only absolute filenames allowed";