X-Git-Url: https://arthur.barton.de/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=etc%2Fuams%2Fuams_randnum.c;h=1256a1bca58bf8824824a6921ad996476cadd510;hb=9d78f9b52ea18b442fc91c6a1e8d8b607f2f90e8;hp=0e94b15373b7849937ef3e7f7d9a379a20e830f5;hpb=644c7d4f1a295df818a7f8339ac750821e7c26dc;p=netatalk.git diff --git a/etc/uams/uams_randnum.c b/etc/uams/uams_randnum.c index 0e94b153..1256a1bc 100644 --- a/etc/uams/uams_randnum.c +++ b/etc/uams/uams_randnum.c @@ -1,5 +1,5 @@ /* - * $Id: uams_randnum.c,v 1.5 2001-06-25 20:13:45 rufustfirefly Exp $ + * $Id: uams_randnum.c,v 1.12.6.4.2.2 2008-11-25 15:16:33 didg Exp $ * * Copyright (c) 1990,1993 Regents of The University of Michigan. * Copyright (c) 1999 Adrian Sun (asun@u.washington.edu) @@ -12,17 +12,34 @@ #include #include + +/* STDC check */ +#if STDC_HEADERS #include +#else /* STDC_HEADERS */ +#ifndef HAVE_STRCHR +#define strchr index +#define strrchr index +#endif /* HAVE_STRCHR */ +char *strchr (), *strrchr (); +#ifndef HAVE_MEMCPY +#define memcpy(d,s,n) bcopy ((s), (d), (n)) +#define memmove(d,s,n) bcopy ((s), (d), (n)) +#endif /* ! HAVE_MEMCPY */ +#endif /* STDC_HEADERS */ + #ifdef HAVE_UNISTD_H #include #endif /* HAVE_UNISTD_H */ +#ifdef HAVE_FCNTL_H #include +#endif /* HAVE_FCNTL_H */ #include #include #include #include -#include +#include #include @@ -30,17 +47,12 @@ #include -#ifdef UAM_RNDNUM #include #ifdef USE_CRACKLIB #include #endif /* USE_CRACKLIB */ -#ifndef __inline__ -#define __inline__ -#endif /* __inline__ */ - #define PASSWDLEN 8 static C_Block seskey; @@ -55,16 +67,16 @@ static u_int8_t randbuf[8]; /* handle ~/.passwd. courtesy of shirsch@ibm.net. */ -static __inline__ int home_passwd(const struct passwd *pwd, - const char *path, const int pathlen, - char *passwd, const int len, +static int home_passwd(const struct passwd *pwd, + const char *path, const int pathlen _U_, + unsigned char *passwd, const int len, const int set) { struct stat st; int fd, i; if ( (fd = open(path, (set) ? O_WRONLY : O_RDONLY)) < 0 ) { - syslog( LOG_ERR, "Failed to open %s", path); + LOG(log_error, logtype_uams, "Failed to open %s", path); return AFPERR_ACCESS; } @@ -79,19 +91,19 @@ static __inline__ int home_passwd(const struct passwd *pwd, if (!S_ISREG(st.st_mode) || (pwd->pw_uid != st.st_uid) || (pwd->pw_gid != st.st_gid) || (st.st_mode & ( S_IRWXG | S_IRWXO )) ) { - syslog( LOG_INFO, "Insecure permissions found for %s.", path); + LOG(log_info, logtype_uams, "Insecure permissions found for %s.", path); goto home_passwd_fail; } /* get the password */ if (set) { if (write(fd, passwd, len) < 0) { - syslog( LOG_ERR, "Failed to write to %s", path ); + LOG(log_error, logtype_uams, "Failed to write to %s", path ); goto home_passwd_fail; } } else { if (read(fd, passwd, len) < 0) { - syslog( LOG_ERR, "Failed to read from %s", path ); + LOG(log_error, logtype_uams, "Failed to read from %s", path ); goto home_passwd_fail; } @@ -129,24 +141,25 @@ home_passwd_fail: #define unhex(x) (isdigit(x) ? (x) - '0' : toupper(x) + 10 - 'A') static int afppasswd(const struct passwd *pwd, const char *path, const int pathlen, - char *passwd, int len, + unsigned char *passwd, int len, const int set) { u_int8_t key[DES_KEY_SZ*2]; char buf[MAXPATHLEN + 1], *p; Key_schedule schedule; FILE *fp; - int i, j, keyfd = -1, err = 0; + unsigned int i, j; + int keyfd = -1, err = 0; off_t pos; - if ((fp = fopen(path, (set) ? "r+" : "r")) <= 0) { - syslog( LOG_ERR, "Failed to open %s", path); + if ((fp = fopen(path, (set) ? "r+" : "r")) == NULL) { + LOG(log_error, logtype_uams, "Failed to open %s", path); return AFPERR_ACCESS; } /* open the key file if it exists */ strcpy(buf, path); - if (pathlen < sizeof(buf) - 5) { + if (pathlen < (int) sizeof(buf) - 5) { strcat(buf, ".key"); keyfd = open(buf, O_RDONLY); } @@ -155,10 +168,11 @@ static int afppasswd(const struct passwd *pwd, memset(buf, 0, sizeof(buf)); while (fgets(buf, sizeof(buf), fp)) { if ((p = strchr(buf, ':'))) { - if (strncmp(buf, pwd->pw_name, p - buf) == 0) { + if ( strlen(pwd->pw_name) == (p - buf) && + strncmp(buf, pwd->pw_name, p - buf) == 0) { p++; if (*p == PASSWD_ILLEGAL) { - syslog(LOG_INFO, "invalid password entry for %s", pwd->pw_name); + LOG(log_info, logtype_uams, "invalid password entry for %s", pwd->pw_name); err = AFPERR_ACCESS; goto afppasswd_done; } @@ -185,7 +199,7 @@ afppasswd_found: read(keyfd, key, sizeof(key)); /* convert to binary key */ - for (i = j = 0; i < strlen(key); i += 2, j++) + for (i = j = 0; i < strlen((char *) key); i += 2, j++) key[j] = (unhex(key[i]) << 4) | unhex(key[i + 1]); if (j <= DES_KEY_SZ) memset(key + j, 0, sizeof(key) - j); @@ -201,7 +215,7 @@ afppasswd_found: /* decrypt the password */ ecb_encrypt((C_Block *) p, (C_Block *) p, schedule, DES_DECRYPT); } - memset(schedule, 0, sizeof(schedule)); + memset(&schedule, 0, sizeof(schedule)); } if (set) { @@ -246,7 +260,7 @@ afppasswd_done: * depending upon whether or not the password is in ~/.passwd * or in a global location */ static int randpass(const struct passwd *pwd, const char *file, - char *passwd, const int len, const int set) + unsigned char *passwd, const int len, const int set) { int i; uid_t uid = geteuid(); @@ -283,45 +297,29 @@ static int randpass(const struct passwd *pwd, const char *file, return i; } - /* randnum sends an 8-byte number and uses the user's password to * check against the encrypted reply. */ -static int randnum_login(void *obj, struct passwd **uam_pwd, - char *ibuf, int ibuflen, - char *rbuf, int *rbuflen) +static int rand_login(void *obj, char *username, int ulen, struct passwd **uam_pwd _U_, + char *ibuf _U_, int ibuflen _U_, + char *rbuf, int *rbuflen) { - char *username, *passwdfile; - u_int16_t sessid; - int len, ulen, err; - - *rbuflen = 0; - - if (uam_afpserver_option(obj, UAM_OPTION_USERNAME, - (void *) &username, &ulen) < 0) - return AFPERR_PARAM; - len = UAM_PASSWD_FILENAME; - if (uam_afpserver_option(obj, UAM_OPTION_PASSWDOPT, - (void *) &passwdfile, &len) < 0) - return AFPERR_PARAM; - - len = (unsigned char) *ibuf++; - if ( len > ulen ) { - return AFPERR_PARAM; - } - memcpy(username, ibuf, len ); - ibuf += len; - username[ len ] = '\0'; - if ((unsigned long) ibuf & 1) /* padding */ - ++ibuf; - - if (( randpwd = uam_getname(username, ulen)) == NULL ) + char *passwdfile; + u_int16_t sessid; + int len, err; + + if (( randpwd = uam_getname(obj, username, ulen)) == NULL ) return AFPERR_PARAM; /* unknown user */ - syslog( LOG_INFO, "randnum/rand2num login: %s", username); + LOG(log_info, logtype_uams, "randnum/rand2num login: %s", username); if (uam_checkuser(randpwd) < 0) return AFPERR_NOTAUTH; + len = UAM_PASSWD_FILENAME; + if (uam_afpserver_option(obj, UAM_OPTION_PASSWDOPT, + (void *) &passwdfile, &len) < 0) + return AFPERR_PARAM; + if ((err = randpass(randpwd, passwdfile, seskey, sizeof(seskey), 0)) != AFP_OK) return err; @@ -348,8 +346,8 @@ static int randnum_login(void *obj, struct passwd **uam_pwd, /* check encrypted reply. we actually setup the encryption stuff * here as the first part of randnum and rand2num are identical. */ static int randnum_logincont(void *obj, struct passwd **uam_pwd, - char *ibuf, int ibuflen, - char *rbuf, int *rbuflen) + char *ibuf, int ibuflen _U_, + char *rbuf _U_, int *rbuflen) { u_int16_t sessid; @@ -367,7 +365,7 @@ static int randnum_logincont(void *obj, struct passwd **uam_pwd, memset(seskey, 0, sizeof(seskey)); ecb_encrypt((C_Block *) randbuf, (C_Block *) randbuf, seskeysched, DES_ENCRYPT); - memset(seskeysched, 0, sizeof(seskeysched)); + memset(&seskeysched, 0, sizeof(seskeysched)); /* test against what the client sent */ if (memcmp( randbuf, ibuf, sizeof(randbuf) )) { /* != */ @@ -387,11 +385,11 @@ static int randnum_logincont(void *obj, struct passwd **uam_pwd, * and sends it back as part of the reply. */ static int rand2num_logincont(void *obj, struct passwd **uam_pwd, - char *ibuf, int ibuflen, + char *ibuf, int ibuflen _U_, char *rbuf, int *rbuflen) { u_int16_t sessid; - int i; + unsigned int i; *rbuflen = 0; @@ -415,7 +413,7 @@ static int rand2num_logincont(void *obj, struct passwd **uam_pwd, /* test against client's reply */ if (memcmp(randbuf, ibuf, sizeof(randbuf))) { /* != */ memset(randbuf, 0, sizeof(randbuf)); - memset(seskeysched, 0, sizeof(seskeysched)); + memset(&seskeysched, 0, sizeof(seskeysched)); return AFPERR_NOTAUTH; } ibuf += sizeof(randbuf); @@ -424,7 +422,7 @@ static int rand2num_logincont(void *obj, struct passwd **uam_pwd, /* encrypt client's challenge and send back */ ecb_encrypt( (C_Block *) ibuf, (C_Block *) rbuf, seskeysched, DES_ENCRYPT); - memset(seskeysched, 0, sizeof(seskeysched)); + memset(&seskeysched, 0, sizeof(seskeysched)); *rbuflen = sizeof(randbuf); *uam_pwd = randpwd; @@ -435,9 +433,9 @@ static int rand2num_logincont(void *obj, struct passwd **uam_pwd, * NOTE: an FPLogin must already have completed successfully for this * to work. */ -static int randnum_changepw(void *obj, const char *username, +static int randnum_changepw(void *obj, const char *username _U_, struct passwd *pwd, char *ibuf, - int ibuflen, char *rbuf, int *rbuflen) + int ibuflen _U_, char *rbuf _U_, int *rbuflen _U_) { char *passwdfile; int err, len; @@ -479,7 +477,7 @@ static int randnum_changepw(void *obj, const char *username, err = randpass(pwd, passwdfile, ibuf + PASSWDLEN, sizeof(seskey), 1); /* zero out some fields */ - memset(seskeysched, 0, sizeof(seskeysched)); + memset(&seskeysched, 0, sizeof(seskeysched)); memset(seskey, 0, sizeof(seskey)); memset(ibuf, 0, sizeof(seskey)); /* old passwd */ memset(ibuf + PASSWDLEN, 0, sizeof(seskey)); /* new passwd */ @@ -490,17 +488,81 @@ static int randnum_changepw(void *obj, const char *username, return( AFP_OK ); } +/* randnum login */ +static int randnum_login(void *obj, struct passwd **uam_pwd, + char *ibuf, int ibuflen, + char *rbuf, int *rbuflen) +{ + char *username; + int len, ulen; + + *rbuflen = 0; + + if (uam_afpserver_option(obj, UAM_OPTION_USERNAME, + (void *) &username, &ulen) < 0) + return AFPERR_MISC; + + if (ibuflen <= 1) { + return( AFPERR_PARAM ); + } + + len = (unsigned char) *ibuf++; + ibuflen--; + if (!len || len > ibuflen || len > ulen ) { + return( AFPERR_PARAM ); + } + memcpy(username, ibuf, len ); + ibuf += len; + ibuflen -=len; + username[ len ] = '\0'; + + if ((unsigned long) ibuf & 1) { /* pad character */ + ++ibuf; + ibuflen--; + } + return (rand_login(obj, username, ulen, uam_pwd, ibuf, ibuflen, rbuf, rbuflen)); +} + +/* randnum login ext */ +static int randnum_login_ext(void *obj, char *uname, struct passwd **uam_pwd, + char *ibuf, int ibuflen, + char *rbuf, int *rbuflen) +{ + char *username; + int len, ulen; + u_int16_t temp16; + + *rbuflen = 0; + + if (uam_afpserver_option(obj, UAM_OPTION_USERNAME, + (void *) &username, &ulen) < 0) + return AFPERR_MISC; + + if (*uname != 3) + return AFPERR_PARAM; + uname++; + memcpy(&temp16, uname, sizeof(temp16)); + len = ntohs(temp16); + if (!len || len > ulen ) { + return( AFPERR_PARAM ); + } + memcpy(username, uname +2, len ); + username[ len ] = '\0'; + return (rand_login(obj, username, ulen, uam_pwd, ibuf, ibuflen, rbuf, rbuflen)); +} + static int uam_setup(const char *path) { - if (uam_register(UAM_SERVER_LOGIN, path, "Randnum exchange", - randnum_login, randnum_logincont, NULL) < 0) + if (uam_register(UAM_SERVER_LOGIN_EXT, path, "Randnum exchange", + randnum_login, randnum_logincont, NULL, randnum_login_ext) < 0) return -1; - if (uam_register(UAM_SERVER_LOGIN, path, "2-Way Randnum exchange", - randnum_login, rand2num_logincont, NULL) < 0) { + + if (uam_register(UAM_SERVER_LOGIN_EXT, path, "2-Way Randnum exchange", + randnum_login, rand2num_logincont, NULL, randnum_login_ext) < 0) { uam_unregister(UAM_SERVER_LOGIN, "Randnum exchange"); return -1; } - + if (uam_register(UAM_SERVER_CHANGEPW, path, "Randnum Exchange", randnum_changepw) < 0) { uam_unregister(UAM_SERVER_LOGIN, "Randnum exchange"); @@ -526,5 +588,3 @@ UAM_MODULE_EXPORT struct uam_export uams_randnum = { UAM_MODULE_VERSION, uam_setup, uam_cleanup }; - -#endif /* UAM_RNDNUM */