172 lines
3.6 KiB
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;
|
|
}
|