diff options
Diffstat (limited to 'appl/cmd/ssh/authtis.b')
| -rw-r--r-- | appl/cmd/ssh/authtis.b | 116 |
1 files changed, 116 insertions, 0 deletions
diff --git a/appl/cmd/ssh/authtis.b b/appl/cmd/ssh/authtis.b new file mode 100644 index 00000000..f06c10f1 --- /dev/null +++ b/appl/cmd/ssh/authtis.b @@ -0,0 +1,116 @@ +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; + } +} |
