summaryrefslogtreecommitdiff
path: root/appl/cmd/auth/factotum/proto/infauth.b
diff options
context:
space:
mode:
Diffstat (limited to 'appl/cmd/auth/factotum/proto/infauth.b')
-rw-r--r--appl/cmd/auth/factotum/proto/infauth.b66
1 files changed, 54 insertions, 12 deletions
diff --git a/appl/cmd/auth/factotum/proto/infauth.b b/appl/cmd/auth/factotum/proto/infauth.b
index cfc847eb..e9b87553 100644
--- a/appl/cmd/auth/factotum/proto/infauth.b
+++ b/appl/cmd/auth/factotum/proto/infauth.b
@@ -139,9 +139,8 @@ interaction(attrs: list of ref Attr, io: ref IO): string
senderr(io, e);
break;
Error1 =>
- senderr(io, "missing your authentication data");
- x: string = e;
- return "remote: "+x;
+ senderr(io, "failed"); # acknowledge error
+ return remote(e);
}
{
@@ -151,8 +150,7 @@ interaction(attrs: list of ref Attr, io: ref IO): string
Error0 =>
return e;
Error1 =>
- x: string = e;
- return "remote: "+x;
+ return remote(e);
}
if(err != nil)
return err;
@@ -160,13 +158,26 @@ interaction(attrs: list of ref Attr, io: ref IO): string
return negotiatecrypto(io, key, ai, rattrs);
}
+remote(s: string): string
+{
+ # account for strange earlier interface
+ if(len s < 6 || s[0: 6] != "remote")
+ return "remote: "+s;
+ return s;
+}
+
+# TO DO: exchange attr/value pairs, covered by hmac (use part of secret up to hmac block size of 64 bytes)
+# the old scheme can be distinguished either by a prefix "attrs " or simply because the string contains "=",
+# and the server side can then reply. the hmac is to prevent tampering.
negotiatecrypto(io: ref IO, key: ref Key, ai: ref Authinfo, attrs: list of ref Sexp): string
{
role := authio->lookattrval(key.attrs, "role");
alg: string;
{
if(role == "client"){
- alg = authio->lookattrval(key.attrs, "alg");
+ alg = authio->lookattrval(key.attrs, ":alg");
+ if(alg == nil)
+ alg = authio->lookattrval(key.attrs, "alg"); # old way
if(alg == nil)
alg = "md5/rc4_256";
sendmsg(io, array of byte alg);
@@ -297,7 +308,8 @@ getmsg(io: ref IO): array of byte raises (Error0, Error1)
if(len buf != m)
raise Error0("io error: (impossible?) msg length " + string m);
if(h[0] == '!'){
-sys->print("got remote error: %s, len %d\n", string buf, len string buf);
+ if(0)
+ sys->print("got remote error: %q, len %d\n", string buf, len string buf);
raise Error1(string buf);
}
return buf;
@@ -318,16 +330,46 @@ senderr(io: ref IO, e: string)
io.write(buf, len buf);
}
+# both the s-expression and k=v form are interim, until all
+# the factotum implementations can manage public keys
+# the s-expression form was the original one used by Inferno factotum
+# the form in which Authinfo components are separate attributes is the
+# one now used by Plan 9 and Plan 9 Ports factotum implementations
keytoauthinfo(key:ref Key): (ref Keyring->Authinfo, string)
{
- if((s := authio->lookattrval(key.secrets, "!authinfo")) == nil){
- # XXX could look up authinfo by hash at this point
- return (nil, "no authinfo attribute");
- }
+ if((s := authio->lookattrval(key.secrets, "!authinfo")) != nil)
+ return strtoauthinfo(s);
+ # TO DO: could look up authinfo by hash
+ ai := ref Keyring->Authinfo;
+ if((s = kv(key.secrets, "!sk")) == nil || (ai.mysk = keyring->strtosk(s)) == nil)
+ return (nil, "bad secret key");
+ if((s = kv(key.attrs, "pk")) == nil || (ai.mypk = keyring->strtopk(s)) == nil)
+ return (nil, "bad public key");
+ if((s = kv(key.attrs, "cert")) == nil || (ai.cert = keyring->strtocert(s)) == nil)
+ return (nil, "bad certificate");
+ if((s = kv(key.attrs, "spk")) == nil || (ai.spk = keyring->strtopk(s)) == nil)
+ return (nil, "bad signer public key");
+ if((s = kv(key.attrs, "dh-alpha")) == nil || (ai.alpha = IPint.strtoip(s, 16)) == nil)
+ return (nil, "bad value for alpha");
+ if((s = kv(key.attrs, "dh-p")) == nil || (ai.p = IPint.strtoip(s, 16)) == nil)
+ return (nil, "bad value for p");
+ return (ai, nil);
+}
- return strtoauthinfo(s);
+kv(a: list of ref Attr, name: string): string
+{
+ return rnl(authio->lookattrval(a, name));
+}
+
+rnl(s: string): string
+{
+ for(i := 0; i < len s; i++)
+ if(s[i] == '^')
+ s[i] = '\n';
+ return s;
}
+# s-expression form
strtoauthinfo(s: string): (ref Keyring->Authinfo, string)
{
(se, err, nil) := Sexp.parse(s);