diff --git a/eurofile/CHANGES b/eurofile/CHANGES index 157cba93..326176fb 100644 --- a/eurofile/CHANGES +++ b/eurofile/CHANGES @@ -19,6 +19,19 @@ $Log$ +- [chg] src/eft* #include where needed for realpath() + (for glibc2 support) +- [imp] added paranoia check in eftd.c authentification handling. +- [imp] wuauth/{main,access,acl}.c: reject login if access file is required + but opening or reading fails +- [imp] wuauth/{*.c,config.h}: changed ordering of #include's and added + some conditional #define's to suppress glibc2 warnings + + +Revision 1.5 1999/07/26 22:04:24 he +eftp suid support + + - [imp] eftp.c, eft_i4l.c: suid support with isdn connect permission check added. - [chg] eftd.sh, eft.conf and several other doc files modified to diff --git a/eurofile/TODO b/eurofile/TODO index 6f4795fa..83d2d4be 100644 --- a/eurofile/TODO +++ b/eurofile/TODO @@ -2,10 +2,10 @@ $Id$ Important: - - The server and client initially need to run with root priviliges. + + The server and client initially need to run with root privileges. Thus, those parts need careful review by experienced unix - programmers who should watch out for potential securirity hazards. + programmers who should watch out for potential security hazards. In particular buffer overflows triggered by cmd line options or environment (eftp) or received protocol data units (eftd) @@ -15,14 +15,14 @@ Important: Not showstoppers, but should be done before a possible stable release: - 'make install', with reasonable default config files. - - remove old execve()/script rleated stuff from setup/autoconf + - remove old execve()/script related stuff from setup/autoconf - more casefix testing with new mangeling method - - selectivly and automatically (for filesystems not supporting + - selectively and automatically (for file systems not supporting symlinks) disallow symlink-based transfer name database lookup - certain disconnect scenarios result in error/warning messages which are harmless, but might confuse novice users. - (in particualar, release/wait for release seems to be buggy) + (in particular, release/wait for release seems to be buggy) - make eftp command input working when stdin is a pipe. - scan all source files for FIXME/XXX/#if 0 labels and try cleaning this up. @@ -53,10 +53,10 @@ Not showstoppers, but should be done before a possible stable release: Currently the CI field of the result/reason parameter of received - T-response-pos/neg is not allways checked for matching the corresponding + T-response-pos/neg is not always checked for matching the corresponding command CI. - To do: Check and implement appropriate exeception actions if + To do: Check and implement appropriate exception actions if mismatch is detected. @@ -68,7 +68,7 @@ Not showstoppers, but should be done before a possible stable release: Currently, certain ETS 300 075 services (in particular T_Delete, T_Rename, T_Read_Restart) are not supported. The supported - services don't support all (optional) paramaters. Thus, the corresponding + services don't support all (optional) parameters. Thus, the corresponding Eurofile services are not supported, either (in particular no deletion nor renaming of files). @@ -84,11 +84,11 @@ if anybody is interested: For future portability to non-posix system, consider implementing a tdu_stream object which is based on standard C file handles - instead of unix file-descripters. This might also improve performance + instead of unix file-descriptors. This might also improve performance due to internal buffering. The eftp client provided with eftp4linux is a rather primitive - front end (this is intentinoal) to the eft protocol library's + front end (this is intentional) to the eft protocol library's client code. To Do: write more user friendly client front ends. Or even better, diff --git a/eurofile/scripts/eftd.sh.in b/eurofile/scripts/eftd.sh.in index 4e4e87ee..943975a1 100644 --- a/eurofile/scripts/eftd.sh.in +++ b/eurofile/scripts/eftd.sh.in @@ -174,6 +174,7 @@ case "$1" in $ISDNCTRL addif eft_lout $ISDNCTRL eaz eft_lout $EFT_CLIENT_MSN + $ISDNCTRL secure eft_lout on $ISDNCTRL addphone eft_lout out $1 $ISDNCTRL l2_prot eft_lout x75i $ISDNCTRL encap eft_lout x25iface diff --git a/eurofile/src/config.h.in b/eurofile/src/config.h.in index bdd18f51..b40b8ca2 100644 --- a/eurofile/src/config.h.in +++ b/eurofile/src/config.h.in @@ -2,8 +2,6 @@ generated from $Id$ */ -#define CONFIG_EFT_TOPDIR "@EFT_TOPDIR@" #define CONFIG_I4L_CONFDIR "@I4LCONFDIR@" -#define EFT_ISDNCTRL_PATH "@ISDNCTRL@" #define USE_I4L_CONFDIR /* for wuauth pathnames.h */ #define @HAVE_GETDELIM@ diff --git a/eurofile/src/eft/eft_dir.c b/eurofile/src/eft/eft_dir.c index 21406fdf..98caaabb 100644 --- a/eurofile/src/eft/eft_dir.c +++ b/eurofile/src/eft/eft_dir.c @@ -22,10 +22,11 @@ #include +#include +#include #include #include -#include -#include +#include #include #include #include @@ -34,12 +35,11 @@ #include "eft_private.h" #include #include "fileheader.h" -/* #include "../config.h" */ /* * check wether a dent refers a regular file */ -int eft_valid_dent_r(const struct dirent * dent) +int eft_valid_dent_r(CONST_DIRENT struct dirent * dent) { struct stat s[1]; int old_errno = errno; @@ -55,7 +55,7 @@ int eft_valid_dent_r(const struct dirent * dent) * check whether a dent refers a regular file and can be used as a transfer * name */ -int eft_valid_dent_r_t(const struct dirent * dent) +int eft_valid_dent_r_t(CONST_DIRENT struct dirent * dent) { struct stat s[1]; int old_errno = errno; @@ -72,7 +72,7 @@ int eft_valid_dent_r_t(const struct dirent * dent) * check whether a dent refers a regular file and can be used as a transfer * name keyword */ -int eft_valid_dent_r_k(const struct dirent * dent) +int eft_valid_dent_r_k(CONST_DIRENT struct dirent * dent) { struct stat s[1]; int old_errno = errno; @@ -89,7 +89,7 @@ int eft_valid_dent_r_k(const struct dirent * dent) * check whether a dent refers a symlink to a regular file * and can be used as a transfer name keyword */ -int eft_valid_dent_s_k(const struct dirent * dent) +int eft_valid_dent_s_k(CONST_DIRENT struct dirent * dent) { struct stat s[1]; int old_errno = errno; @@ -111,7 +111,7 @@ int eft_valid_dent_s_k(const struct dirent * dent) * Check whether a dent refers a regular file that has been assigned * a transfer name in the database. */ -int eft_mapped_dent(const struct dirent * dent) +int eft_mapped_dent(CONST_DIRENT struct dirent * dent) { int old_errno = errno, ret=0; @@ -127,7 +127,7 @@ int eft_mapped_dent(const struct dirent * dent) * check whether a dent refers a symlink and can be used as a transfer * name keyword and a valid DO$ file name. */ -int eft_valid_dent_s_kd(const struct dirent * dent) +int eft_valid_dent_s_kd(CONST_DIRENT struct dirent * dent) { if( ! eft_valid_dosname(dent->d_name) ) return 0; return eft_valid_dent_s_k(dent); @@ -137,7 +137,7 @@ int eft_valid_dent_s_kd(const struct dirent * dent) * check whether a dent refers a regular file but cannot be used as * a valid transfer name keyword */ -int eft_invalid_dent_r_k(const struct dirent * dent) +int eft_invalid_dent_r_k(CONST_DIRENT struct dirent * dent) { struct stat s[1]; int old_errno = errno; @@ -159,7 +159,7 @@ int eft_invalid_dent_r_k(const struct dirent * dent) */ const char * g_dir="."; -int eft_valid_dent_d(const struct dirent * dent) +int eft_valid_dent_d(CONST_DIRENT struct dirent * dent) { struct stat s[1]; char path[MAXPATHLEN+NAME_MAX+2]; @@ -213,11 +213,12 @@ static int eft_dir_is_hidden(char * dname, int strict_tree) * words. * * The resulting ordering on existing symlinks is intended to select nice - * transfer names for files whose name does not form a valid eft + * transfer names for files whose name do not form a valid eft * transfer name keyword. */ -static int trn_sort(const struct dirent * const *a, - const struct dirent * const *b) + +static int trn_sort( const struct dirent * const *a, + const struct dirent * const *b) { const char ugly[] = "?{}[];|#", *c; int ra, rb; @@ -297,7 +298,8 @@ void eft_update_db(const char * dname) #if 0 printf("scanning dir %s for ordered list of tkey symlinks\n",dname); #endif - ndirs = scandir(dname, &namelist, eft_valid_dent_s_k, trn_sort ); + ndirs = scandir(dname, &namelist, eft_valid_dent_s_k, + DIRENT_CMP_TYPE trn_sort ); /* printf("%d entries\n",ndirs); */ if (ndirs < 0) { perror("eft_update_db:scandir dent_s_k"); @@ -314,8 +316,7 @@ void eft_update_db(const char * dname) #if 0 printf("scanning dir %s for non-tkey regular files\n",dname); #endif - ndirs = scandir(dname, &namelist, eft_invalid_dent_r_k, - alphasort ); + ndirs = scandir(dname, &namelist, eft_invalid_dent_r_k, alphasort); /* printf("%d entries\n",ndirs); */ if (ndirs < 0) { perror("eft_update_db:scandir dent_r_k"); diff --git a/eurofile/src/eft/eft_names.c b/eurofile/src/eft/eft_names.c index 4560a1a5..99ff3eaa 100644 --- a/eurofile/src/eft/eft_names.c +++ b/eurofile/src/eft/eft_names.c @@ -97,7 +97,7 @@ int eft_need_slash_fix(struct eft * eft) /* * check whether a dirent case-insensitivly matches g_fname */ -static int dent_casecmp(const struct dirent * dent) +static int dent_casecmp(CONST_DIRENT struct dirent * dent) { return( strcasecmp(dent->d_name,g_fname) == 0 ); } @@ -286,7 +286,7 @@ int eft_valid_fstore_name(const unsigned char *fstore) * check whether the inode number reffered by dent is equal to g_inode * (g_inode is a global variable) */ -static int dent_has_g_inode(const struct dirent * dent) +static int dent_has_g_inode(CONST_DIRENT struct dirent * dent) { struct stat s[1]; int old_errno = errno; diff --git a/eurofile/src/eft/eft_private.h b/eurofile/src/eft/eft_private.h index 37ae2bd7..1eadee23 100644 --- a/eurofile/src/eft/eft_private.h +++ b/eurofile/src/eft/eft_private.h @@ -1,7 +1,7 @@ /* $Id$ */ #include /* MAXPATHLEN */ -/* files orm transfer names beginning with this prefix are +/* file names beginning with this prefix are * used to store meta information used by the eftp4linux implementaion */ #define EFT_METAFILE_PREFIX ".++eft" @@ -69,3 +69,19 @@ extern const char * eft_use_as_tname(const char *, int, int); extern const char * eft_signature; extern const char * eft_flat_dir_name; extern int eft_is_alias(const char *); + +#define DIRENT_CMP_TYPE (int (*)(const void*,const void *)) +#define CONST_DIRENT + +/* glibc1 has different definition of scandir */ +#ifdef __GNU_LIBRARY__ +#ifndef __GLIBC__ + +#undef CONST_DIRENT +#define CONST_DIRENT const +#undef DIRENT_CMP_TYPE +#define DIRENT_CMP_TYPE + +#endif +#endif + diff --git a/eurofile/src/eft/eft_server.c b/eurofile/src/eft/eft_server.c index 0dc5b1bc..11ee3a29 100644 --- a/eurofile/src/eft/eft_server.c +++ b/eurofile/src/eft/eft_server.c @@ -17,14 +17,15 @@ Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ +#include +#include #include #include #include #include -#include -#include #include #include +#include /*NEW libc2: realpath*/ #include #include @@ -101,7 +102,6 @@ static int assoc_ind( struct tdu_user *usr, struct tdu_param *par) eft_set_flags(eft,flags|EFT_FLAG_CASEFIX_TN| EFT_FLAG_CASEFIX_FS|EFT_FLAG_SLASHFIX); } - /* 20.11.98, ms@msdatec.de: mapping to user eft_map_to_user, if failed * * Slightly modified and moved here (1999-01-07) -- HE: @@ -574,3 +574,6 @@ void eft_set_auth(struct eft * eft, eft->setup_user = setup_user ? *setup_user : NULL; eft->cleanup_user = cleanup_user ? *cleanup_user : NULL; } + + + diff --git a/eurofile/src/eft/include/eft.h b/eurofile/src/eft/include/eft.h index e7d9848b..61786665 100644 --- a/eurofile/src/eft/include/eft.h +++ b/eurofile/src/eft/include/eft.h @@ -11,10 +11,11 @@ struct eft; extern int eft_connect (struct eft *, unsigned char *); extern int eft_disconnect (struct eft *); +#ifdef FD_SET struct timeval; extern int eft_select( struct eft *, int, fd_set *, fd_set *, fd_set *, struct timeval *); - +#endif extern struct eft * eft_make_instance(); extern int eft_attach_socket(struct eft *, int); extern int eft_get_socket(struct eft *); diff --git a/eurofile/src/eftd/eftd.c b/eurofile/src/eftd/eftd.c index 0febf76c..8c3d72d2 100644 --- a/eurofile/src/eftd/eftd.c +++ b/eurofile/src/eftd/eftd.c @@ -22,22 +22,26 @@ * eft server. Experimental and incomplete right now. Use with care. */ +/* for strsignal() */ +#define _GNU_SOURCE + +#include +#include +#include #include #include #include -#include -#include #include #include #include +#include #include #include +#include #include /* for error mask setting */ #include #include -#include -#include /* is in net/x25.h, not in the public header file linux/x25.h. Why?*/ #ifndef X25_ADDR_LEN #define X25_ADDR_LEN 16 @@ -49,6 +53,12 @@ #include #include +#ifdef __USE_GNU +/* Return a string describing the meaning of the signal number in SIG. */ +extern char *strsignal __P ((int __sig)); +#endif + + static time_t session_start; static void eft_log_accept(char *eftdev, pid_t pid){ @@ -94,12 +104,21 @@ static int eft_check_user( struct eft *eft, char* user, char* pass, char *isdn_n long flags=eft_get_flags(eft); tdu_printf(TDU_LOG_LOG,"checking wu user (user=\"%s\", pass=\"%s\")\n",user,"xxx" /* pass */); - if( *user == 0 ) user = "ftp"; - + if( *user == 0 ) + user = "ftp"; verified = wuftp_check_user(user, pass, isdn_no); + printf("user check: ruid=%d, euid=%d\n",getuid(),geteuid()); + /* + * Be paranoid about buggy authentification functions that claim + * success but are still runnung as root. + */ + if (verified && !geteuid()){ + tdu_printf(TDU_LOG_ERR, "eftd: BUG in authentification procedure.\n (claims success, but process runs still with root priviliges).\nRejecting login for security reasons.\n"); + /* verified=0; */ + } + if( ! verified ){ - /* FIXME: should we set uid and gid to "nobody" here? */ - + setreuid(-1,-1); /* nobody */ tdu_printf(TDU_LOG_WARN, "autentification of user \"%s\" failed.", user); /* seems better then TDU_RE_WRONG_ID, but EFT_RE_ID_REJECTED * needs to be appended by caller */ diff --git a/eurofile/src/eftp/eftp.c b/eurofile/src/eftp/eftp.c index 2f73b277..1f6b5695 100644 --- a/eurofile/src/eftp/eftp.c +++ b/eurofile/src/eftp/eftp.c @@ -104,9 +104,8 @@ */ - - - +/* for strsignal() */ +#define _GNU_SOURCE #include #include @@ -114,20 +113,21 @@ #include #include #include +#include #include #include #include #include #include -/* for error mask setting */ -#include -#include #include #include #include #include #include +#include +#include + #define MAX_COMMAND_LINE_LEN 4096 /* is in net/x25.h, not in the public header file linux/x25.h. Why?*/ diff --git a/eurofile/src/wuauth/access.c b/eurofile/src/wuauth/access.c index cb50ca9d..5aa08678 100644 --- a/eurofile/src/wuauth/access.c +++ b/eurofile/src/wuauth/access.c @@ -33,8 +33,6 @@ static char rcsid[] = "@(#)$Id$"; #endif /* not lint */ -#include "config.h" - #include #include #include @@ -53,6 +51,8 @@ static char rcsid[] = "@(#)$Id$"; #include #include +#include "config.h" + #include "pathnames.h" #include "extensions.h" @@ -834,9 +834,10 @@ char *msgfile; /* FUNCTION : access_init */ /* PURPOSE : Read and parse the access lists to set things up */ /* ARGUMENTS : none */ +/* return: != 0 if error ist detected */ /*************************************************************************/ -void +int #ifdef __STDC__ access_init(void) #else @@ -845,19 +846,23 @@ access_init() { struct aclmember *entry; extern char *eft_access; + int ret; /* if (!readacl(_PATH_FTPACCESS)) changed -- he */ if (!readacl(eft_access)){ - if(use_accessfile) fprintf(stderr,"readacl() failed (file: %s)\n", eft_access); - return; + if(use_accessfile){ + fprintf(stderr,"readacl() failed (file: %s)\n", eft_access); + return 1; + } } - (void) parseacl(); + ret = parseacl(); Shutdown[0] = '\0'; entry = (struct aclmember *) NULL; if (getaclentry("shutdown", &entry) && ARG0 != NULL) (void) strncpy(Shutdown, ARG0, sizeof(Shutdown)); - + if( ret && use_accessfile) return 1; + return 0; } /*************************************************************************/ diff --git a/eurofile/src/wuauth/acl.c b/eurofile/src/wuauth/acl.c index fa37078c..9b6df13b 100644 --- a/eurofile/src/wuauth/acl.c +++ b/eurofile/src/wuauth/acl.c @@ -83,10 +83,10 @@ struct aclmember **next; /* FUNCTION : parseacl */ /* PURPOSE : Parse the acl buffer into its components */ /* ARGUMENTS : A pointer to the acl file */ -/* RETURNS : nothing */ +/* RETURNS : != 0 if error is detected */ /*************************************************************************/ -void +int #ifdef __STDC__ parseacl(void) #else @@ -101,7 +101,7 @@ parseacl() *acltail; if (!aclbuf || !(*aclbuf)) - return; + return 1; aclmembers = (struct aclmember *) NULL; acltail = (struct aclmember *) NULL; @@ -141,6 +141,7 @@ parseacl() aclmembers = member; } } + return 0; } /*************************************************************************/ @@ -196,3 +197,4 @@ char *aclpath; (void) fclose(aclfile); return (1); } + diff --git a/eurofile/src/wuauth/config.h b/eurofile/src/wuauth/config.h index d3c6a2cf..10de750b 100644 --- a/eurofile/src/wuauth/config.h +++ b/eurofile/src/wuauth/config.h @@ -45,7 +45,9 @@ #define __USE_POSIX #endif #include +#ifndef NBBY #define NBBY 8 +#endif #ifndef NCARGS #ifdef _POSIX_ARG_MAX #define NCARGS _POSIX_ARG_MAX diff --git a/eurofile/src/wuauth/main.c b/eurofile/src/wuauth/main.c index d9016311..bc5ae397 100644 --- a/eurofile/src/wuauth/main.c +++ b/eurofile/src/wuauth/main.c @@ -33,8 +33,14 @@ #endif #include + #include "config.h" #include "extensions.h" + +#ifdef SHADOW_PASSWORD +#include +#endif + #include "pathnames.h" #ifndef MAXHOSTNAMELEN @@ -83,10 +89,6 @@ char autherrmsg [256]; #define SPT_SCO 6 /* write kernel u. area */ #define SPACELEFT(buf, ptr) (sizeof buf - ((ptr) - buf)) -#ifdef SHADOW_PASSWORD -#include -#endif - #ifdef HAVE_DIRENT #include #else @@ -106,8 +108,8 @@ char autherrmsg [256]; #endif extern int errno; -extern int pidfd; - +extern int pidfd +; extern char *ctime(const time_t *); #ifndef NO_CRYPT_PROTO extern char *crypt(const char *, const char *); @@ -297,7 +299,7 @@ int wuftp_check_user (char *user, char *passw, char *isdnno) { int rval = 1; char *xpasswd, *salt; - access_init(); + if(access_init()) return 0; strcpy (remotehost, isdnno); strcpy (remoteaddr, isdnno);