You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

265 lines
6.6 KiB
C

/*
* Copyright (c) 1997-2000 The Stanford SRP Authentication Project
* All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND,
* EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
* WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
*
* IN NO EVENT SHALL STANFORD BE LIABLE FOR ANY SPECIAL, INCIDENTAL,
* INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, OR ANY DAMAGES WHATSOEVER
* RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER OR NOT ADVISED OF
* THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF LIABILITY, ARISING OUT
* OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*
* In addition, the following conditions apply:
*
* 1. Any software that incorporates the SRP authentication technology
* must display the following acknowlegment:
* "This product uses the 'Secure Remote Password' cryptographic
* authentication system developed by Tom Wu (tjw@CS.Stanford.EDU)."
*
* 2. Any software that incorporates all or part of the SRP distribution
* itself must also display the following acknowledgment:
* "This product includes software developed by Tom Wu and Eugene
* Jhong for the SRP Distribution (http://srp.stanford.edu/srp/)."
*
* 3. Redistributions in source or binary form must retain an intact copy
* of this copyright notice and list of conditions.
*/
#include "t_defines.h"
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif /* HAVE_UNISTD_H */
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#ifdef USE_HOMEDIR
#include <pwd.h>
#endif
#ifdef WIN32
#include <io.h>
#endif
#include "t_pwd.h"
#include "t_read.h"
#include "t_sha.h"
#include "t_server.h"
static struct t_pw * syspw = NULL;
static struct t_passwd tpass;
_TYPE( struct t_server * )
t_serveropen(username)
const char * username;
{
struct t_passwd * p;
p = gettpnam(username);
if(p == NULL) {
return NULL;
} else {
return t_serveropenraw(&p->tp, &p->tc);
}
}
/* t_openpw(NULL) is deprecated - use settpent()/gettpnam() instead */
_TYPE( struct t_pw * )
t_openpw(fp)
FILE * fp;
{
struct t_pw * tpw;
char close_flag = 0;
if(fp == NULL) { /* Deprecated */
if((fp = fopen(DEFAULT_PASSWD, "r")) == NULL)
return NULL;
close_flag = 1;
}
else
close_flag = 0;
if((tpw = malloc(sizeof(struct t_pw))) == NULL) {
fclose(fp);
return NULL;
}
tpw->instream = fp;
tpw->close_on_exit = close_flag;
tpw->state = FILE_ONLY;
return tpw;
}
_TYPE( struct t_pw * )
t_openpwbyname(pwname)
const char * pwname;
{
FILE * fp;
struct t_pw * t;
if(pwname == NULL) /* Deprecated */
return t_openpw(NULL);
if((fp = fopen(pwname, "r")) == NULL)
return NULL;
t = t_openpw(fp);
t->close_on_exit = 1;
return t;
}
_TYPE( void )
t_closepw(tpw)
struct t_pw * tpw;
{
if(tpw->close_on_exit)
fclose(tpw->instream);
free(tpw);
}
_TYPE( void )
t_rewindpw(tpw)
struct t_pw * tpw;
{
#ifdef ENABLE_YP
if(tpw->state == IN_NIS)
tpw->state = FILE_NIS;
#endif
rewind(tpw->instream);
}
#ifdef ENABLE_YP
static void
savepwent(tpw, pwent)
struct t_pw * tpw;
struct t_pwent *pwent;
{
tpw->pebuf.name = tpw->userbuf;
tpw->pebuf.password.data = tpw->pwbuf;
tpw->pebuf.salt.data = tpw->saltbuf;
strcpy(tpw->pebuf.name, pwent->name);
tpw->pebuf.password.len = pwent->password.len;
memcpy(tpw->pebuf.password.data, pwent->password.data, pwent->password.len);
tpw->pebuf.salt.len = pwent->salt.len;
memcpy(tpw->pebuf.salt.data, pwent->salt.data, pwent->salt.len);
tpw->pebuf.index = pwent->index;
}
#endif /* ENABLE_YP */
_TYPE( struct t_pwent * )
t_getpwbyname(tpw, user)
struct t_pw * tpw;
const char * user;
{
char indexbuf[16];
char passbuf[MAXB64PARAMLEN];
char saltstr[MAXB64SALTLEN];
char username[MAXUSERLEN];
#ifdef ENABLE_YP
struct t_passwd * nisent;
#endif
t_rewindpw(tpw);
while(t_nextfield(tpw->instream, username, MAXUSERLEN) > 0) {
#ifdef ENABLE_YP
if(tpw->state == FILE_NIS && *username == '+') {
if(strlen(username) == 1 || strcmp(user, username+1) == 0) {
nisent = _yp_gettpnam(user); /* Entry is +username or + */
if(nisent != NULL) {
savepwent(tpw, &nisent->tp);
return &tpw->pebuf;
}
}
}
#endif
if(strcmp(user, username) == 0)
if(t_nextfield(tpw->instream, passbuf, MAXB64PARAMLEN) > 0 &&
(tpw->pebuf.password.len = t_fromb64(tpw->pwbuf, passbuf)) > 0 &&
t_nextfield(tpw->instream, saltstr, MAXB64SALTLEN) > 0 &&
(tpw->pebuf.salt.len = t_fromb64(tpw->saltbuf, saltstr)) > 0 &&
t_nextfield(tpw->instream, indexbuf, 16) > 0 &&
(tpw->pebuf.index = atoi(indexbuf)) > 0) {
strcpy(tpw->userbuf, username);
tpw->pebuf.name = tpw->userbuf;
tpw->pebuf.password.data = tpw->pwbuf;
tpw->pebuf.salt.data = tpw->saltbuf;
t_nextline(tpw->instream);
return &tpw->pebuf;
}
if(t_nextline(tpw->instream) < 0)
return NULL;
}
return NULL;
}
/* System password file accessors */
static int
pwinit()
{
if(syspw == NULL) {
if((syspw = t_openpwbyname(DEFAULT_PASSWD)) == NULL)
return -1;
syspw->state = FILE_NIS;
}
return 0;
}
static void
pwsetup(out, tpwd, tcnf)
struct t_passwd * out;
struct t_pwent * tpwd;
struct t_confent * tcnf;
{
out->tp.name = tpwd->name;
out->tp.password.len = tpwd->password.len;
out->tp.password.data = tpwd->password.data;
out->tp.salt.len = tpwd->salt.len;
out->tp.salt.data = tpwd->salt.data;
out->tp.index = tpwd->index;
out->tc.index = tcnf->index;
out->tc.modulus.len = tcnf->modulus.len;
out->tc.modulus.data = tcnf->modulus.data;
out->tc.generator.len = tcnf->generator.len;
out->tc.generator.data = tcnf->generator.data;
}
_TYPE( struct t_passwd * )
gettpnam
(user)
const char * user;
{
struct t_pwent * tpptr;
struct t_confent * tcptr;
if(pwinit() < 0)
return NULL;
tpptr = t_getpwbyname(syspw, user);
if(tpptr == NULL)
return NULL;
tcptr =
gettcid
(tpptr->index);
if(tcptr == NULL)
return NULL;
pwsetup(&tpass, tpptr, tcptr);
return &tpass;
}