Full OTP support.

git-svn-id: svn://svn.h5l.se/heimdal/trunk/heimdal@979 ec53bebd-3082-4978-b11e-865c3cabbd6b
This commit is contained in:
Assar Westerlund
1996-11-16 17:52:53 +00:00
parent f902292bd3
commit fadac636c7

View File

@@ -130,10 +130,6 @@ RCSID("$Id$");
#include <kafs.h>
#include "roken.h"
#if defined(SKEY)
#include <skey.h>
#endif
#include <otp.h>
void yyparse();
@@ -183,8 +179,12 @@ char hostname[MaxHostNameLen];
char remotehost[MaxHostNameLen];
static char ttyline[20];
/* Default level for security, 0 allow any kind of connection, 1 only
authorized and anonymous connections, 2 only authorized */
/* Default level for security:
* 0 allow any kind of connection
* 1 only OTP, authorized and anonymous connections
* 2 only authorized and anonymous connections,
* 3 only authorized
*/
static int auth_level = 1;
/*
@@ -498,10 +498,6 @@ sgetpwnam(char *name)
static int login_attempts; /* number of failed login attempts */
static int askpasswd; /* had user command, ask for passwd */
static char curname[10]; /* current USER name */
#ifdef SKEY
static struct skey sk;
static int permit_passwd;
#endif /* SKEY */
OtpContext otp_ctx;
/*
@@ -580,24 +576,6 @@ user(char *name)
if(auth_ok())
ct->userok(name);
else {
#if 0
#ifdef SKEY
char ss[256];
permit_passwd = skeyaccess(k_getpwnam (name), NULL,
remotehost, NULL);
if (skeychallenge (&sk, name, ss) == 0) {
reply (331, "Password [%s] for %s required.",
ss, name);
askpasswd = 1;
} else if (permit_passwd)
#endif
{
reply(331, "Password required for %s.", name);
askpasswd = 1;
}
#endif
char ss[256];
if (otp_challenge(&otp_ctx, name, ss, sizeof(ss)) == 0) {
@@ -607,10 +585,15 @@ user(char *name)
} else if (auth_level == 0) {
reply(331, "Password required for %s.", name);
askpasswd = 1;
} else
} else {
char *s;
if (s = otp_error (&otp_ctx))
lreply(530, "OTP: %s", s);
reply(530,
"Only authorized, anonymous and OTP "
"login allowed.");
}
}
/*
@@ -761,20 +744,10 @@ pass(char *passwd)
return;
}
askpasswd = 0;
rval = 1;
if (!guest) { /* "ftp" is only account allowed no password */
if (pw == NULL)
rval = 1; /* failure below */
#if 0
#ifdef SKEY
if (skeyverify (&sk, passwd) == 0) {
rval = 0;
goto skip;
} else if(!permit_passwd) {
rval = 1;
goto skip;
}
#endif
#endif
else if (otp_verify_user (&otp_ctx, passwd) == 0) {
rval = 0;
} else if(auth_level == 0) {
@@ -784,6 +757,11 @@ pass(char *passwd)
passwd, 1, NULL);
if (rval != 0 )
rval = unix_verify_user(pw->pw_name, passwd);
} else {
char *s;
if (s = otp_error(&otp_ctx))
lreply(530, "OTP: %s", s);
}
memset (passwd, 0, strlen(passwd));
@@ -1801,7 +1779,6 @@ gunique(char *local)
void
perror_reply(int code, char *string)
{
reply(code, "%s: %s.", string, strerror(errno));
}
@@ -1813,134 +1790,134 @@ static char *onefile[] = {
void
send_file_list(char *whichf)
{
struct stat st;
DIR *dirp = NULL;
struct dirent *dir;
FILE *dout = NULL;
char **dirlist, *dirname;
int simple = 0;
int freeglob = 0;
glob_t gl;
struct stat st;
DIR *dirp = NULL;
struct dirent *dir;
FILE *dout = NULL;
char **dirlist, *dirname;
int simple = 0;
int freeglob = 0;
glob_t gl;
char buf[MaxPathLen];
char buf[MaxPathLen];
if (strpbrk(whichf, "~{[*?") != NULL) {
int flags = GLOB_BRACE|GLOB_NOCHECK|GLOB_QUOTE|GLOB_TILDE;
if (strpbrk(whichf, "~{[*?") != NULL) {
int flags = GLOB_BRACE|GLOB_NOCHECK|GLOB_QUOTE|GLOB_TILDE;
memset(&gl, 0, sizeof(gl));
freeglob = 1;
if (glob(whichf, flags, 0, &gl)) {
reply(550, "not found");
goto out;
} else if (gl.gl_pathc == 0) {
errno = ENOENT;
perror_reply(550, whichf);
goto out;
}
dirlist = gl.gl_pathv;
} else {
onefile[0] = whichf;
dirlist = onefile;
simple = 1;
}
if (setjmp(urgcatch)) {
transflag = 0;
goto out;
}
while ((dirname = *dirlist++)) {
if (stat(dirname, &st) < 0) {
/*
* If user typed "ls -l", etc, and the client
* used NLST, do what the user meant.
*/
if (dirname[0] == '-' && *dirlist == NULL &&
transflag == 0) {
retrieve("/bin/ls %s", dirname);
goto out;
}
perror_reply(550, whichf);
if (dout != NULL) {
(void) fclose(dout);
transflag = 0;
data = -1;
pdata = -1;
}
goto out;
}
if (S_ISREG(st.st_mode)) {
if (dout == NULL) {
dout = dataconn("file list", (off_t)-1, "w");
if (dout == NULL)
goto out;
transflag++;
}
sprintf(buf, "%s%s\n", dirname,
type == TYPE_A ? "\r" : "");
auth_write(fileno(dout), buf, strlen(buf));
byte_count += strlen(dirname) + 1;
continue;
} else if (!S_ISDIR(st.st_mode))
continue;
if ((dirp = opendir(dirname)) == NULL)
continue;
while ((dir = readdir(dirp)) != NULL) {
char nbuf[MaxPathLen];
if (!strcmp(dir->d_name, "."))
continue;
if (!strcmp(dir->d_name, ".."))
continue;
sprintf(nbuf, "%s/%s", dirname, dir->d_name);
/*
* We have to do a stat to insure it's
* not a directory or special file.
*/
if (simple || (stat(nbuf, &st) == 0 &&
S_ISREG(st.st_mode))) {
if (dout == NULL) {
dout = dataconn("file list", (off_t)-1, "w");
if (dout == NULL)
goto out;
transflag++;
}
if(strncmp(nbuf, "./", 2) == 0)
sprintf(buf, "%s%s\n", nbuf +2,
type == TYPE_A ? "\r" : "");
else
sprintf(buf, "%s%s\n", nbuf,
type == TYPE_A ? "\r" : "");
auth_write(fileno(dout), buf, strlen(buf));
byte_count += strlen(nbuf) + 1;
}
}
(void) closedir(dirp);
}
if (dout == NULL)
reply(550, "No files found.");
else if (ferror(dout) != 0)
perror_reply(550, "Data connection");
else
reply(226, "Transfer complete.");
memset(&gl, 0, sizeof(gl));
freeglob = 1;
if (glob(whichf, flags, 0, &gl)) {
reply(550, "not found");
goto out;
} else if (gl.gl_pathc == 0) {
errno = ENOENT;
perror_reply(550, whichf);
goto out;
}
dirlist = gl.gl_pathv;
} else {
onefile[0] = whichf;
dirlist = onefile;
simple = 1;
}
if (setjmp(urgcatch)) {
transflag = 0;
goto out;
}
while ((dirname = *dirlist++)) {
if (stat(dirname, &st) < 0) {
/*
* If user typed "ls -l", etc, and the client
* used NLST, do what the user meant.
*/
if (dirname[0] == '-' && *dirlist == NULL &&
transflag == 0) {
retrieve("/bin/ls %s", dirname);
goto out;
}
perror_reply(550, whichf);
if (dout != NULL) {
(void) fclose(dout);
transflag = 0;
if (dout != NULL){
auth_write(fileno(dout), buf, 0); /* XXX flush */
(void) fclose(dout);
}
data = -1;
pdata = -1;
out:
if (freeglob) {
freeglob = 0;
globfree(&gl);
}
goto out;
}
if (S_ISREG(st.st_mode)) {
if (dout == NULL) {
dout = dataconn("file list", (off_t)-1, "w");
if (dout == NULL)
goto out;
transflag++;
}
sprintf(buf, "%s%s\n", dirname,
type == TYPE_A ? "\r" : "");
auth_write(fileno(dout), buf, strlen(buf));
byte_count += strlen(dirname) + 1;
continue;
} else if (!S_ISDIR(st.st_mode))
continue;
if ((dirp = opendir(dirname)) == NULL)
continue;
while ((dir = readdir(dirp)) != NULL) {
char nbuf[MaxPathLen];
if (!strcmp(dir->d_name, "."))
continue;
if (!strcmp(dir->d_name, ".."))
continue;
sprintf(nbuf, "%s/%s", dirname, dir->d_name);
/*
* We have to do a stat to insure it's
* not a directory or special file.
*/
if (simple || (stat(nbuf, &st) == 0 &&
S_ISREG(st.st_mode))) {
if (dout == NULL) {
dout = dataconn("file list", (off_t)-1, "w");
if (dout == NULL)
goto out;
transflag++;
}
if(strncmp(nbuf, "./", 2) == 0)
sprintf(buf, "%s%s\n", nbuf +2,
type == TYPE_A ? "\r" : "");
else
sprintf(buf, "%s%s\n", nbuf,
type == TYPE_A ? "\r" : "");
auth_write(fileno(dout), buf, strlen(buf));
byte_count += strlen(nbuf) + 1;
}
}
(void) closedir(dirp);
}
if (dout == NULL)
reply(550, "No files found.");
else if (ferror(dout) != 0)
perror_reply(550, "Data connection");
else
reply(226, "Transfer complete.");
transflag = 0;
if (dout != NULL){
auth_write(fileno(dout), buf, 0); /* XXX flush */
(void) fclose(dout);
}
data = -1;
pdata = -1;
out:
if (freeglob) {
freeglob = 0;
globfree(&gl);
}
}