1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
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;
}
}
|