blob: 048c190663c4b0779df9e00ddfe99deda97b2540 [file] [log] [blame]
#include "std.h"
#include "dat.h"
#include <bio.h>
int
memrandom(void *p, int n)
{
uchar *cp;
for(cp = (uchar*)p; n > 0; n--)
*cp++ = fastrand();
return 0;
}
/*
* create a change uid capability
*/
static int caphashfd;
static char*
mkcap(char *from, char *to)
{
uchar rand[20];
char *cap;
char *key;
int nfrom, nto;
uchar hash[SHA1dlen];
if(caphashfd < 0)
return nil;
/* create the capability */
nto = strlen(to);
nfrom = strlen(from);
cap = emalloc(nfrom+1+nto+1+sizeof(rand)*3+1);
sprint(cap, "%s@%s", from, to);
memrandom(rand, sizeof(rand));
key = cap+nfrom+1+nto+1;
enc64(key, sizeof(rand)*3, rand, sizeof(rand));
/* hash the capability */
hmac_sha1((uchar*)cap, strlen(cap), (uchar*)key, strlen(key), hash, nil);
/* give the kernel the hash */
key[-1] = '@';
if(write(caphashfd, hash, SHA1dlen) < 0){
free(cap);
return nil;
}
return cap;
}
Attr*
addcap(Attr *a, char *from, Ticket *t)
{
char *cap;
cap = mkcap(from, t->suid);
return addattr(a, "cuid=%q suid=%q cap=%q", t->cuid, t->suid, cap);
}
/* bind in the default network and cs */
static int
bindnetcs(void)
{
int srvfd;
if(access("/net/tcp", AEXIST) < 0)
bind("#I", "/net", MBEFORE);
if(access("/net/cs", AEXIST) < 0){
if((srvfd = open("#s/cs", ORDWR)) >= 0){
/* mount closes srvfd on success */
if(mount(srvfd, -1, "/net", MBEFORE, "") >= 0)
return 0;
close(srvfd);
}
return -1;
}
return 0;
}
int
_authdial(char *net, char *authdom)
{
int vanilla;
vanilla = net==nil || strcmp(net, "/net")==0;
if(!vanilla || bindnetcs()>=0)
return authdial(net, authdom);
/* use the auth sever passed to us as an arg */
if(authaddr == nil)
return -1;
return dial(netmkaddr(authaddr, "tcp", "567"), 0, 0, 0);
}
Key*
plan9authkey(Attr *a)
{
char *dom;
Key *k;
/*
* The only important part of a is dom.
* We don't care, for example, about user name.
*/
dom = strfindattr(a, "dom");
if(dom)
k = keylookup("proto=p9sk1 role=server user? dom=%q", dom);
else
k = keylookup("proto=p9sk1 role=server user? dom?");
if(k == nil)
werrstr("could not find plan 9 auth key dom %q", dom);
return k;
}
/*
* prompt for a string with a possible default response
*/
char*
readcons(char *prompt, char *def, int raw)
{
int fdin, fdout, ctl, n;
char line[10];
char *s;
fdin = open("/dev/cons", OREAD);
if(fdin < 0)
fdin = 0;
fdout = open("/dev/cons", OWRITE);
if(fdout < 0)
fdout = 1;
if(def != nil)
fprint(fdout, "%s[%s]: ", prompt, def);
else
fprint(fdout, "%s: ", prompt);
if(raw){
ctl = open("/dev/consctl", OWRITE);
if(ctl >= 0)
write(ctl, "rawon", 5);
} else
ctl = -1;
s = estrdup("");
for(;;){
n = read(fdin, line, 1);
if(n == 0){
Error:
close(fdin);
close(fdout);
if(ctl >= 0)
close(ctl);
free(s);
return nil;
}
if(n < 0)
goto Error;
if(line[0] == 0x7f)
goto Error;
if(n == 0 || line[0] == '\n' || line[0] == '\r'){
if(raw){
write(ctl, "rawoff", 6);
write(fdout, "\n", 1);
}
close(ctl);
close(fdin);
close(fdout);
if(*s == 0 && def != nil)
s = estrappend(s, "%s", def);
return s;
}
if(line[0] == '\b'){
if(strlen(s) > 0)
s[strlen(s)-1] = 0;
} else if(line[0] == 0x15) { /* ^U: line kill */
if(def != nil)
fprint(fdout, "\n%s[%s]: ", prompt, def);
else
fprint(fdout, "\n%s: ", prompt);
s[0] = 0;
} else {
s = estrappend(s, "%c", line[0]);
}
}
return nil; /* not reached */
}