implement Auth; # TO DO: add chal/resp to Factotum include "sys.m"; sys: Sys; include "keyring.m"; kr: Keyring; IPint: import kr; include "factotum.m"; factotum: Factotum; Attr: import factotum; findattrval: import factotum; include "sshio.m"; sshio: Sshio; Conn, Msg: import sshio; debug: import sshio; id(): int{ return SSH_AUTH_TIS;} init(mod: Sshio){ sshio = mod; sys = load Sys Sys->PATH; kr = load Keyring Keyring->PATH; factotum = load Factotum Factotum->PATH; factotum->init();} firstmsg(): int{ return SSH_CMSG_AUTH_TIS;} authsrv(conn: ref Conn, nil: ref Msg): ref AuthInfo{ if((c := factotum->challenge(sys->sprint("proto=p9cr user=%q role=server", conn.user))) == nil){# sshlog("auth_challenge failed for %s", conn.user); return nil; } s := sys->sprint("Challenge: %s\nResponse: ", c.chal); m := Msg.mk(SSH_SMSG_AUTH_TIS_CHALLENGE, 4+len s); m.putstring(s); conn.out <-= m; m = sshio->recvmsg(conn, 0); if(m == nil) return nil; if(m.mtype != SSH_CMSG_AUTH_TIS_RESPONSE){ # # apparently you can just give up on # this protocol and start a new one. # sshio->unrecvmsg(conn, m); return nil; } ai := factotum->response(c, m.getstring()); if(ai == nil){ debug(DBG_AUTH, sys->sprint("response rejected: %r\n")); return nil; } return ref AuthInfo(ai.cuid, ai.cap);} auth(c: ref Conn): int{ if(!c.interactive) return -1; debug(DBG_AUTH, "try TIS\n"); c.out <-= Msg.mk(SSH_CMSG_AUTH_TIS, 0); m := sshio->recvmsg(c, -1); case m.mtype { SSH_SMSG_FAILURE => return -1; SSH_SMSG_AUTH_TIS_CHALLENGE => ; * => sshio->badmsg(m, SSH_SMSG_AUTH_TIS_CHALLENGE, nil); } chal := m.getstring(); if((fd := sys->open("/dev/cons", Sys->ORDWR)) == nil) sshio->error(sys->sprint("can't open /dev/cons: %r")); sys->fprint(fd, "TIS Authentication\n%s", chal); resp := array[256] of byte; n := sys->read(fd, resp, len resp); if(n <= 0 || resp[0] == byte '\n') return -1; m = Msg.mk(SSH_CMSG_AUTH_TIS_RESPONSE, 4+n); m.put4(len resp); m.putbytes(resp, n); c.out <-= m; m = sshio->recvmsg(c, -1); case m.mtype { SSH_SMSG_SUCCESS => return 0; SSH_SMSG_FAILURE => return -1; * => sshio->badmsg(m, 0, nil); return -1; }}
implement Auth;
# TO DO: add chal/resp to Factotum
include "sys.m";
sys: Sys;
include "keyring.m";
kr: Keyring;
IPint: import kr;
include "factotum.m";
factotum: Factotum;
Attr: import factotum;
findattrval: import factotum;
include "sshio.m";
sshio: Sshio;
Conn, Msg: import sshio;
debug: import sshio;
id(): int
{
return SSH_AUTH_TIS;
}
init(mod: Sshio)
{
sshio = mod;
sys = load Sys Sys->PATH;
kr = load Keyring Keyring->PATH;
factotum = load Factotum Factotum->PATH;
factotum->init();
}
firstmsg(): int
{
return SSH_CMSG_AUTH_TIS;
}
authsrv(conn: ref Conn, nil: ref Msg): ref AuthInfo
{
if((c := factotum->challenge(sys->sprint("proto=p9cr user=%q role=server", conn.user))) == nil){
# sshlog("auth_challenge failed for %s", conn.user);
return nil;
}
s := sys->sprint("Challenge: %s\nResponse: ", c.chal);
m := Msg.mk(SSH_SMSG_AUTH_TIS_CHALLENGE, 4+len s);
m.putstring(s);
conn.out <-= m;
m = sshio->recvmsg(conn, 0);
if(m == nil)
return nil;
if(m.mtype != SSH_CMSG_AUTH_TIS_RESPONSE){
#
# apparently you can just give up on
# this protocol and start a new one.
#
sshio->unrecvmsg(conn, m);
return nil;
}
ai := factotum->response(c, m.getstring());
if(ai == nil){
debug(DBG_AUTH, sys->sprint("response rejected: %r\n"));
return nil;
}
return ref AuthInfo(ai.cuid, ai.cap);
}
auth(c: ref Conn): int
{
if(!c.interactive)
return -1;
debug(DBG_AUTH, "try TIS\n");
c.out <-= Msg.mk(SSH_CMSG_AUTH_TIS, 0);
m := sshio->recvmsg(c, -1);
case m.mtype {
SSH_SMSG_FAILURE =>
return -1;
SSH_SMSG_AUTH_TIS_CHALLENGE =>
;
* =>
sshio->badmsg(m, SSH_SMSG_AUTH_TIS_CHALLENGE, nil);
}
chal := m.getstring();
if((fd := sys->open("/dev/cons", Sys->ORDWR)) == nil)
sshio->error(sys->sprint("can't open /dev/cons: %r"));
sys->fprint(fd, "TIS Authentication\n%s", chal);
resp := array[256] of byte;
n := sys->read(fd, resp, len resp);
if(n <= 0 || resp[0] == byte '\n')
return -1;
m = Msg.mk(SSH_CMSG_AUTH_TIS_RESPONSE, 4+n);
m.put4(len resp);
m.putbytes(resp, n);
c.out <-= m;
m = sshio->recvmsg(c, -1);
case m.mtype {
SSH_SMSG_SUCCESS =>
return 0;
SSH_SMSG_FAILURE =>
return -1;
* =>
sshio->badmsg(m, 0, nil);
return -1;
}
}