jehanne/sys/src/cmd/auth/guard.srv.c

172 lines
3.6 KiB
C

/*
* This file is part of the UCB release of Plan 9. It is subject to the license
* terms in the LICENSE file found in the top-level directory of this
* distribution and at http://akaros.cs.berkeley.edu/files/Plan9License. No
* part of the UCB release of Plan 9, including this file, may be copied,
* modified, propagated, or distributed except according to the terms contained
* in the LICENSE file.
*/
/* Portions of this file are Copyright (C) 9front's team.
* See /doc/license/9front-mit for details about the licensing.
* See http://git.9front.org/plan9front/plan9front/HEAD/info.html for a list of authors.
*/
/* Portions of this file are Copyright (C) 2015-2018 Giacomo Tesio <giacomo@tesio.it>
* See /doc/license/gpl-2.0.txt for details about the licensing.
*/
/*
* guard service
*/
#include <u.h>
#include <lib9.h>
#include <9P2000.h>
#include <bio.h>
#include <ndb.h>
#include <libsec.h>
#include <authsrv.h>
#include "authcmdlib.h"
enum {
Pinlen = 4,
};
/*
* c -> a client
* a -> c challenge prompt
* c -> a KC'{challenge}
* a -> c OK or NO
*/
void catchalarm(void*, char*);
void getraddr(char*);
char user[ANAMELEN];
char raddr[128];
int debug;
Ndb *db;
void
main(int argc, char *argv[])
{
int n;
int32_t chal;
char *err;
char ukey[DESKEYLEN], resp[32], buf[NETCHLEN];
Ndb *db2;
ARGBEGIN{
case 'd':
debug = 1;
break;
}ARGEND;
db = ndbopen("/lib/ndb/auth");
if(db == 0)
syslog(0, AUTHLOG, "no /lib/ndb/auth");
db2 = ndbopen(0);
if(db2 == 0)
syslog(0, AUTHLOG, "no /lib/ndb/local");
db = ndbcat(db, db2);
werrstr("");
strcpy(raddr, "unknown");
if(argc >= 1)
getraddr(argv[argc-1]);
argv0 = "guard";
sys_notify(catchalarm);
/*
* read the host and client and get their keys
*/
if(readarg(0, user, sizeof user) < 0)
fail(0);
/*
* challenge-response
*/
chal = nfastrand(MAXNETCHAL);
sprint(buf, "challenge: %lud\nresponse: ", chal);
n = strlen(buf) + 1;
if(jehanne_write(1, buf, n) != n){
if(debug)
syslog(0, AUTHLOG, "g-fail %s@%s: %r sending chal",
user, raddr);
exits("replying to server");
}
sys_alarm(3*60*1000);
werrstr("");
if(readarg(0, resp, sizeof resp) < 0){
if(debug)
syslog(0, AUTHLOG, "g-fail %s@%s: %r reading resp",
user, raddr);
fail(0);
}
sys_alarm(0);
/* remove password login from guard.research.bell-labs.com, sucre, etc. */
// if(!findkey(KEYDB, user, ukey) || !netcheck(ukey, chal, resp))
if(!finddeskey(NETKEYDB, user, ukey) || !netcheck(ukey, chal, resp))
if((err = secureidcheck(user, resp)) != nil){
print("NO %s", err);
jehanne_write(1, "NO", 2);
if(debug) {
char *r;
/*
* don't log the entire response, since the first
* Pinlen digits may be the user's secure-id pin.
*/
if (strlen(resp) < Pinlen)
r = strdup("<too short for pin>");
else if (strlen(resp) == Pinlen)
r = strdup("<pin only>");
else
r = smprint("%.*s%s", Pinlen,
"******************", resp + Pinlen);
syslog(0, AUTHLOG,
"g-fail %s@%s: %s: resp %s to chal %lud",
user, raddr, err, r, chal);
free(r);
}
fail(user);
}
jehanne_write(1, "OK", 2);
if(debug)
syslog(0, AUTHLOG, "g-ok %s@%s", user, raddr);
succeed(user);
exits(0);
}
void
catchalarm(void *x, char *msg)
{
if(debug)
syslog(0, AUTHLOG, "g-timed out %s", raddr);
fail(0);
}
void
getraddr(char *dir)
{
int n, fd;
char *cp;
char file[128];
snprint(file, sizeof(file), "%s/remote", dir);
fd = sys_open(file, OREAD);
if(fd < 0)
return;
n = jehanne_read(fd, raddr, sizeof(raddr)-1);
sys_close(fd);
if(n <= 0)
return;
raddr[n] = 0;
cp = strchr(raddr, '\n');
if(cp)
*cp = 0;
cp = strchr(raddr, '!');
if(cp)
*cp = 0;
}