Add real factotum.
This commit is contained in:
parent
06b60293ad
commit
ab73f2bbf5
19
Makefile
19
Makefile
@ -8,27 +8,23 @@ OFILES=\
|
|||||||
readcons.$O\
|
readcons.$O\
|
||||||
secstore.$O\
|
secstore.$O\
|
||||||
latin1.$O\
|
latin1.$O\
|
||||||
|
$(OS)-factotum.$O\
|
||||||
|
|
||||||
LIBS=\
|
LIBS1=\
|
||||||
kern/libkern.a\
|
kern/libkern.a\
|
||||||
exportfs/libexportfs.a\
|
exportfs/libexportfs.a\
|
||||||
|
libauth/libauth.a\
|
||||||
libauthsrv/libauthsrv.a\
|
libauthsrv/libauthsrv.a\
|
||||||
libsec/libsec.a\
|
libsec/libsec.a\
|
||||||
libmp/libmp.a\
|
libmp/libmp.a\
|
||||||
libmemdraw/libmemdraw.a\
|
libmemdraw/libmemdraw.a\
|
||||||
libmemlayer/libmemlayer.a\
|
libmemlayer/libmemlayer.a\
|
||||||
libdraw/libdraw.a\
|
libdraw/libdraw.a\
|
||||||
libc/libc.a\
|
|
||||||
kern/libkern.a\
|
|
||||||
gui-$(GUI)/libgui.a\
|
gui-$(GUI)/libgui.a\
|
||||||
libmemdraw/libmemdraw.a\
|
|
||||||
libdraw/libdraw.a\
|
|
||||||
kern/libkern.a\
|
|
||||||
libc/libc.a\
|
libc/libc.a\
|
||||||
libmemdraw/libmemdraw.a\
|
|
||||||
libmemlayer/libmemlayer.a\
|
# stupid gcc
|
||||||
libdraw/libdraw.a\
|
LIBS=$(LIBS1) $(LIBS1) $(LIBS1) libmachdep.a
|
||||||
libmachdep.a
|
|
||||||
|
|
||||||
$(TARG): $(OFILES) $(LIBS)
|
$(TARG): $(OFILES) $(LIBS)
|
||||||
$(CC) $(LDFLAGS) -o $(TARG) $(OFILES) $(LIBS) $(LDADD)
|
$(CC) $(LDFLAGS) -o $(TARG) $(OFILES) $(LIBS) $(LDADD)
|
||||||
@ -45,6 +41,9 @@ kern/libkern.a:
|
|||||||
exportfs/libexportfs.a:
|
exportfs/libexportfs.a:
|
||||||
(cd exportfs; make)
|
(cd exportfs; make)
|
||||||
|
|
||||||
|
libauth/libauth.a:
|
||||||
|
(cd libauth; make)
|
||||||
|
|
||||||
libauthsrv/libauthsrv.a:
|
libauthsrv/libauthsrv.a:
|
||||||
(cd libauthsrv; make)
|
(cd libauthsrv; make)
|
||||||
|
|
||||||
|
118
cpu.c
118
cpu.c
@ -17,7 +17,6 @@
|
|||||||
#define Maxfdata 8192
|
#define Maxfdata 8192
|
||||||
#define MaxStr 128
|
#define MaxStr 128
|
||||||
|
|
||||||
static char* getuser(void);
|
|
||||||
static void fatal(int, char*, ...);
|
static void fatal(int, char*, ...);
|
||||||
static void catcher(void*, char*);
|
static void catcher(void*, char*);
|
||||||
static void usage(void);
|
static void usage(void);
|
||||||
@ -98,7 +97,9 @@ cpumain(int argc, char **argv)
|
|||||||
close(fd);
|
close(fd);
|
||||||
}
|
}
|
||||||
|
|
||||||
user = readcons("user", getenv("USER"), 0);
|
user = getenv("USER");
|
||||||
|
if(user == nil)
|
||||||
|
user = readcons("user", nil, 0);
|
||||||
secstoreserver = nil;
|
secstoreserver = nil;
|
||||||
ARGBEGIN{
|
ARGBEGIN{
|
||||||
case 'a':
|
case 'a':
|
||||||
@ -126,6 +127,9 @@ cpumain(int argc, char **argv)
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
*/
|
*/
|
||||||
|
case 'k':
|
||||||
|
keyspec = EARGF(usage());
|
||||||
|
break;
|
||||||
case 'u':
|
case 'u':
|
||||||
user = EARGF(usage());
|
user = EARGF(usage());
|
||||||
break;
|
break;
|
||||||
@ -136,6 +140,15 @@ cpumain(int argc, char **argv)
|
|||||||
usage();
|
usage();
|
||||||
}ARGEND;
|
}ARGEND;
|
||||||
|
|
||||||
|
if((fd = dialfactotum()) < 0)
|
||||||
|
fprint(2, "dial factotum: %r\n");
|
||||||
|
else if(sysmount(fd, -1, "/mnt/factotum", MREPL, "") < 0)
|
||||||
|
fprint(2, "mount factotum: %r\n");
|
||||||
|
else if((fd = open("/mnt/factotum/ctl", OREAD)) < 0)
|
||||||
|
fprint(2, "open /mnt/factotum/ctl: %r\n");
|
||||||
|
else
|
||||||
|
close(fd);
|
||||||
|
|
||||||
if(secstoreserver == nil)
|
if(secstoreserver == nil)
|
||||||
secstoreserver = authserver;
|
secstoreserver = authserver;
|
||||||
|
|
||||||
@ -436,6 +449,96 @@ gettickets(Ticketreq *tr, char *key, char *trbuf, char *tbuf)
|
|||||||
return mkserverticket(tr, key, tbuf);
|
return mkserverticket(tr, key, tbuf);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* prompt user for a key. don't care about memory leaks, runs standalone
|
||||||
|
*/
|
||||||
|
static Attr*
|
||||||
|
promptforkey(char *params)
|
||||||
|
{
|
||||||
|
char *v;
|
||||||
|
int fd;
|
||||||
|
Attr *a, *attr;
|
||||||
|
char *def;
|
||||||
|
|
||||||
|
fd = open("/dev/cons", ORDWR);
|
||||||
|
if(fd < 0)
|
||||||
|
sysfatal("opening /dev/cons: %r");
|
||||||
|
|
||||||
|
attr = _parseattr(params);
|
||||||
|
fprint(fd, "\n!Adding key:");
|
||||||
|
for(a=attr; a; a=a->next)
|
||||||
|
if(a->type != AttrQuery && a->name[0] != '!')
|
||||||
|
fprint(fd, " %q=%q", a->name, a->val);
|
||||||
|
fprint(fd, "\n");
|
||||||
|
|
||||||
|
for(a=attr; a; a=a->next){
|
||||||
|
v = a->name;
|
||||||
|
if(a->type != AttrQuery || v[0]=='!')
|
||||||
|
continue;
|
||||||
|
def = nil;
|
||||||
|
if(strcmp(v, "user") == 0)
|
||||||
|
def = getuser();
|
||||||
|
a->val = readcons(v, def, 0);
|
||||||
|
if(a->val == nil)
|
||||||
|
sysfatal("user terminated key input");
|
||||||
|
a->type = AttrNameval;
|
||||||
|
}
|
||||||
|
for(a=attr; a; a=a->next){
|
||||||
|
v = a->name;
|
||||||
|
if(a->type != AttrQuery || v[0]!='!')
|
||||||
|
continue;
|
||||||
|
def = nil;
|
||||||
|
if(strcmp(v+1, "user") == 0)
|
||||||
|
def = getuser();
|
||||||
|
a->val = readcons(v+1, def, 1);
|
||||||
|
if(a->val == nil)
|
||||||
|
sysfatal("user terminated key input");
|
||||||
|
a->type = AttrNameval;
|
||||||
|
}
|
||||||
|
fprint(fd, "!\n");
|
||||||
|
close(fd);
|
||||||
|
return attr;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* send a key to the mounted factotum
|
||||||
|
*/
|
||||||
|
static int
|
||||||
|
sendkey(Attr *attr)
|
||||||
|
{
|
||||||
|
int fd, rv;
|
||||||
|
char buf[1024];
|
||||||
|
|
||||||
|
fd = open("/mnt/factotum/ctl", ORDWR);
|
||||||
|
if(fd < 0)
|
||||||
|
sysfatal("opening /mnt/factotum/ctl: %r");
|
||||||
|
rv = fprint(fd, "key %A\n", attr);
|
||||||
|
read(fd, buf, sizeof buf);
|
||||||
|
close(fd);
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
askuser(char *params)
|
||||||
|
{
|
||||||
|
Attr *attr;
|
||||||
|
|
||||||
|
fmtinstall('A', _attrfmt);
|
||||||
|
|
||||||
|
attr = promptforkey(params);
|
||||||
|
if(attr == nil)
|
||||||
|
sysfatal("no key supplied");
|
||||||
|
if(sendkey(attr) < 0)
|
||||||
|
sysfatal("sending key to factotum: %r");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
AuthInfo*
|
||||||
|
p9anyfactotum(int fd, int afd)
|
||||||
|
{
|
||||||
|
return auth_proxy(fd, askuser, "proto=p9any role=client %s", keyspec);
|
||||||
|
}
|
||||||
|
|
||||||
AuthInfo*
|
AuthInfo*
|
||||||
p9any(int fd)
|
p9any(int fd)
|
||||||
{
|
{
|
||||||
@ -444,11 +547,14 @@ p9any(int fd)
|
|||||||
char tbuf[TICKETLEN+TICKETLEN+AUTHENTLEN], trbuf[TICKREQLEN];
|
char tbuf[TICKETLEN+TICKETLEN+AUTHENTLEN], trbuf[TICKREQLEN];
|
||||||
char authkey[DESKEYLEN];
|
char authkey[DESKEYLEN];
|
||||||
Authenticator auth;
|
Authenticator auth;
|
||||||
int i, v2, n;
|
int afd, i, v2, n;
|
||||||
Ticketreq tr;
|
Ticketreq tr;
|
||||||
Ticket t;
|
Ticket t;
|
||||||
AuthInfo *ai;
|
AuthInfo *ai;
|
||||||
|
|
||||||
|
if((afd = open("/mnt/factotum/ctl", ORDWR)) >= 0)
|
||||||
|
return p9anyfactotum(fd, afd);
|
||||||
|
|
||||||
if((n = readstr(fd, buf, sizeof buf)) < 0)
|
if((n = readstr(fd, buf, sizeof buf)) < 0)
|
||||||
fatal(1, "cannot read p9any negotiation");
|
fatal(1, "cannot read p9any negotiation");
|
||||||
bbuf = buf;
|
bbuf = buf;
|
||||||
@ -598,9 +704,3 @@ setamalg(char *s)
|
|||||||
return setam(s);
|
return setam(s);
|
||||||
}
|
}
|
||||||
|
|
||||||
char*
|
|
||||||
getuser(void)
|
|
||||||
{
|
|
||||||
return getenv("USER");
|
|
||||||
}
|
|
||||||
|
|
||||||
|
@ -8,3 +8,5 @@ extern int exportfs(int, int);
|
|||||||
extern char *user;
|
extern char *user;
|
||||||
extern char *getkey(char*, char*);
|
extern char *getkey(char*, char*);
|
||||||
extern char *findkey(char**, char*);
|
extern char *findkey(char**, char*);
|
||||||
|
extern int dialfactotum(void);
|
||||||
|
extern char *getuser(void);
|
||||||
|
@ -99,7 +99,7 @@ exportfs(int fd, int msgsz)
|
|||||||
fatal("convM2S format error");
|
fatal("convM2S format error");
|
||||||
}
|
}
|
||||||
|
|
||||||
//iprint("<- %F\n", &r->work);
|
if(0) iprint("<- %F\n", &r->work);
|
||||||
DEBUG(DFD, "%F\n", &r->work);
|
DEBUG(DFD, "%F\n", &r->work);
|
||||||
(fcalls[r->work.type])(r);
|
(fcalls[r->work.type])(r);
|
||||||
}
|
}
|
||||||
@ -110,6 +110,7 @@ reply(Fcall *r, Fcall *t, char *err)
|
|||||||
{
|
{
|
||||||
uchar *data;
|
uchar *data;
|
||||||
int m, n;
|
int m, n;
|
||||||
|
static QLock lk;
|
||||||
|
|
||||||
t->tag = r->tag;
|
t->tag = r->tag;
|
||||||
t->fid = r->fid;
|
t->fid = r->fid;
|
||||||
@ -120,7 +121,7 @@ reply(Fcall *r, Fcall *t, char *err)
|
|||||||
else
|
else
|
||||||
t->type = r->type + 1;
|
t->type = r->type + 1;
|
||||||
|
|
||||||
//iprint("-> %F\n", t);
|
if(0) iprint("-> %F\n", t);
|
||||||
DEBUG(DFD, "\t%F\n", t);
|
DEBUG(DFD, "\t%F\n", t);
|
||||||
|
|
||||||
data = malloc(messagesize); /* not mallocz; no need to clear */
|
data = malloc(messagesize); /* not mallocz; no need to clear */
|
||||||
|
@ -431,6 +431,7 @@ slave(Fsrpc *f)
|
|||||||
Proc *p;
|
Proc *p;
|
||||||
int pid;
|
int pid;
|
||||||
static int nproc;
|
static int nproc;
|
||||||
|
static QLock lk;
|
||||||
|
|
||||||
for(;;) {
|
for(;;) {
|
||||||
for(p = Proclist; p; p = p->next) {
|
for(p = Proclist; p; p = p->next) {
|
||||||
|
@ -50,6 +50,8 @@ extern int dirwstat(char*, Dir*);
|
|||||||
extern int dirfwstat(int, Dir*);
|
extern int dirfwstat(int, Dir*);
|
||||||
extern long dirread(int, Dir*, long);
|
extern long dirread(int, Dir*, long);
|
||||||
|
|
||||||
|
extern int lfdfd(int);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* network dialing and authentication
|
* network dialing and authentication
|
||||||
*/
|
*/
|
||||||
|
@ -13,6 +13,7 @@ OFILES=\
|
|||||||
devfs-$(OS).$O\
|
devfs-$(OS).$O\
|
||||||
devip.$O\
|
devip.$O\
|
||||||
devip-$(OS).$O\
|
devip-$(OS).$O\
|
||||||
|
devlfd.$O\
|
||||||
devmnt.$O\
|
devmnt.$O\
|
||||||
devmouse.$O\
|
devmouse.$O\
|
||||||
devpipe.$O\
|
devpipe.$O\
|
||||||
|
@ -175,25 +175,6 @@ print(char *fmt, ...)
|
|||||||
return n;
|
return n;
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
|
||||||
iprint(char *fmt, ...)
|
|
||||||
{
|
|
||||||
int n, s;
|
|
||||||
va_list arg;
|
|
||||||
char buf[PRINTSIZE];
|
|
||||||
|
|
||||||
s = splhi();
|
|
||||||
va_start(arg, fmt);
|
|
||||||
n = vseprint(buf, buf+sizeof(buf), fmt, arg) - buf;
|
|
||||||
va_end(arg);
|
|
||||||
if(screenputs != nil && iprintscreenputs)
|
|
||||||
screenputs(buf, n);
|
|
||||||
uartputs(buf, n);
|
|
||||||
splx(s);
|
|
||||||
|
|
||||||
return n;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
void
|
||||||
panic(char *fmt, ...)
|
panic(char *fmt, ...)
|
||||||
{
|
{
|
||||||
@ -1208,3 +1189,23 @@ writebintime(char *buf, int n)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int
|
||||||
|
iprint(char *fmt, ...)
|
||||||
|
{
|
||||||
|
int n, s;
|
||||||
|
va_list arg;
|
||||||
|
char buf[PRINTSIZE];
|
||||||
|
|
||||||
|
s = splhi();
|
||||||
|
va_start(arg, fmt);
|
||||||
|
n = vseprint(buf, buf+sizeof(buf), fmt, arg) - buf;
|
||||||
|
va_end(arg);
|
||||||
|
if(screenputs != nil && iprintscreenputs)
|
||||||
|
screenputs(buf, n);
|
||||||
|
#undef write
|
||||||
|
write(2, buf, n);
|
||||||
|
splx(s);
|
||||||
|
|
||||||
|
return n;
|
||||||
|
}
|
||||||
|
|
||||||
|
126
kern/devlfd.c
Normal file
126
kern/devlfd.c
Normal file
@ -0,0 +1,126 @@
|
|||||||
|
#include "u.h"
|
||||||
|
#include <errno.h>
|
||||||
|
#include "lib.h"
|
||||||
|
#include "dat.h"
|
||||||
|
#include "fns.h"
|
||||||
|
#include "error.h"
|
||||||
|
|
||||||
|
#undef pread
|
||||||
|
#undef pwrite
|
||||||
|
|
||||||
|
Chan*
|
||||||
|
lfdchan(int fd)
|
||||||
|
{
|
||||||
|
Chan *c;
|
||||||
|
|
||||||
|
c = newchan();
|
||||||
|
c->type = devno('L', 0);
|
||||||
|
c->aux = (void*)fd;
|
||||||
|
c->name = newcname("fd");
|
||||||
|
c->mode = ORDWR;
|
||||||
|
c->qid.type = 0;
|
||||||
|
c->qid.path = 0;
|
||||||
|
c->qid.vers = 0;
|
||||||
|
c->dev = 0;
|
||||||
|
c->offset = 0;
|
||||||
|
return c;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
lfdfd(int fd)
|
||||||
|
{
|
||||||
|
return newfd(lfdchan(fd));
|
||||||
|
}
|
||||||
|
|
||||||
|
static Chan*
|
||||||
|
lfdattach(char *x)
|
||||||
|
{
|
||||||
|
USED(x);
|
||||||
|
|
||||||
|
error(Egreg);
|
||||||
|
return nil;
|
||||||
|
}
|
||||||
|
|
||||||
|
static Walkqid*
|
||||||
|
lfdwalk(Chan *c, Chan *nc, char **name, int nname)
|
||||||
|
{
|
||||||
|
USED(c);
|
||||||
|
USED(nc);
|
||||||
|
USED(name);
|
||||||
|
USED(nname);
|
||||||
|
|
||||||
|
error(Egreg);
|
||||||
|
return nil;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
lfdstat(Chan *c, uchar *dp, int n)
|
||||||
|
{
|
||||||
|
USED(c);
|
||||||
|
USED(dp);
|
||||||
|
USED(n);
|
||||||
|
error(Egreg);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static Chan*
|
||||||
|
lfdopen(Chan *c, int omode)
|
||||||
|
{
|
||||||
|
USED(c);
|
||||||
|
USED(omode);
|
||||||
|
|
||||||
|
error(Egreg);
|
||||||
|
return nil;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
lfdclose(Chan *c)
|
||||||
|
{
|
||||||
|
close((int)c->aux);
|
||||||
|
}
|
||||||
|
|
||||||
|
static long
|
||||||
|
lfdread(Chan *c, void *buf, long n, vlong off)
|
||||||
|
{
|
||||||
|
USED(off); /* can't pread on pipes */
|
||||||
|
n = read((int)c->aux, buf, n);
|
||||||
|
if(n < 0){
|
||||||
|
iprint("error %d\n", errno);
|
||||||
|
oserror();
|
||||||
|
}
|
||||||
|
return n;
|
||||||
|
}
|
||||||
|
|
||||||
|
static long
|
||||||
|
lfdwrite(Chan *c, void *buf, long n, vlong off)
|
||||||
|
{
|
||||||
|
USED(off); /* can't pread on pipes */
|
||||||
|
|
||||||
|
n = write((int)c->aux, buf, n);
|
||||||
|
if(n < 0){
|
||||||
|
iprint("error %d\n", errno);
|
||||||
|
oserror();
|
||||||
|
}
|
||||||
|
return n;
|
||||||
|
}
|
||||||
|
|
||||||
|
Dev lfddevtab = {
|
||||||
|
'L',
|
||||||
|
"lfd",
|
||||||
|
|
||||||
|
devreset,
|
||||||
|
devinit,
|
||||||
|
devshutdown,
|
||||||
|
lfdattach,
|
||||||
|
lfdwalk,
|
||||||
|
lfdstat,
|
||||||
|
lfdopen,
|
||||||
|
devcreate,
|
||||||
|
lfdclose,
|
||||||
|
lfdread,
|
||||||
|
devbread,
|
||||||
|
lfdwrite,
|
||||||
|
devbwrite,
|
||||||
|
devremove,
|
||||||
|
devwstat,
|
||||||
|
};
|
@ -8,9 +8,12 @@ enum
|
|||||||
{
|
{
|
||||||
Qdir = 0,
|
Qdir = 0,
|
||||||
Qboot = 0x1000,
|
Qboot = 0x1000,
|
||||||
|
Qmnt = 0x2000,
|
||||||
|
Qfactotum,
|
||||||
|
|
||||||
Nrootfiles = 32,
|
Nrootfiles = 32,
|
||||||
Nbootfiles = 32,
|
Nbootfiles = 32,
|
||||||
|
Nmntfiles = 2,
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef struct Dirlist Dirlist;
|
typedef struct Dirlist Dirlist;
|
||||||
@ -26,6 +29,7 @@ struct Dirlist
|
|||||||
static Dirtab rootdir[Nrootfiles] = {
|
static Dirtab rootdir[Nrootfiles] = {
|
||||||
"#/", {Qdir, 0, QTDIR}, 0, DMDIR|0555,
|
"#/", {Qdir, 0, QTDIR}, 0, DMDIR|0555,
|
||||||
"boot", {Qboot, 0, QTDIR}, 0, DMDIR|0555,
|
"boot", {Qboot, 0, QTDIR}, 0, DMDIR|0555,
|
||||||
|
"mnt", {Qmnt, 0, QTDIR}, 0, DMDIR|0555,
|
||||||
};
|
};
|
||||||
static uchar *rootdata[Nrootfiles];
|
static uchar *rootdata[Nrootfiles];
|
||||||
static Dirlist rootlist =
|
static Dirlist rootlist =
|
||||||
@ -33,7 +37,7 @@ static Dirlist rootlist =
|
|||||||
0,
|
0,
|
||||||
rootdir,
|
rootdir,
|
||||||
rootdata,
|
rootdata,
|
||||||
2,
|
3,
|
||||||
Nrootfiles
|
Nrootfiles
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -50,6 +54,19 @@ static Dirlist bootlist =
|
|||||||
Nbootfiles
|
Nbootfiles
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static Dirtab mntdir[Nmntfiles] = {
|
||||||
|
"mnt", {Qmnt, 0, QTDIR}, 0, DMDIR|0555,
|
||||||
|
"factotum", {Qfactotum, 0, QTDIR}, 0, DMDIR|0555,
|
||||||
|
};
|
||||||
|
static Dirlist mntlist =
|
||||||
|
{
|
||||||
|
Qmnt,
|
||||||
|
mntdir,
|
||||||
|
nil,
|
||||||
|
2,
|
||||||
|
Nmntfiles
|
||||||
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* add a file to the list
|
* add a file to the list
|
||||||
*/
|
*/
|
||||||
@ -97,7 +114,6 @@ rootreset(void)
|
|||||||
addrootdir("dev");
|
addrootdir("dev");
|
||||||
addrootdir("env");
|
addrootdir("env");
|
||||||
addrootdir("fd");
|
addrootdir("fd");
|
||||||
addrootdir("mnt");
|
|
||||||
addrootdir("net");
|
addrootdir("net");
|
||||||
addrootdir("net.alt");
|
addrootdir("net.alt");
|
||||||
addrootdir("proc");
|
addrootdir("proc");
|
||||||
@ -129,6 +145,13 @@ rootgen(Chan *c, char *name, Dirtab *dirt, int ndirt, int s, Dir *dp)
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
return devgen(c, name, rootlist.dir, rootlist.ndir, s, dp);
|
return devgen(c, name, rootlist.dir, rootlist.ndir, s, dp);
|
||||||
|
case Qmnt:
|
||||||
|
if(s == DEVDOTDOT){
|
||||||
|
Qid tqiddir = {Qdir, 0, QTDIR};
|
||||||
|
devdir(c, tqiddir, "#/", 0, eve, 0555, dp);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
return devgen(c, name, mntlist.dir, mntlist.ndir, s, dp);
|
||||||
case Qboot:
|
case Qboot:
|
||||||
if(s == DEVDOTDOT){
|
if(s == DEVDOTDOT){
|
||||||
Qid tqiddir = {Qdir, 0, QTDIR};
|
Qid tqiddir = {Qdir, 0, QTDIR};
|
||||||
@ -139,22 +162,25 @@ rootgen(Chan *c, char *name, Dirtab *dirt, int ndirt, int s, Dir *dp)
|
|||||||
default:
|
default:
|
||||||
if(s == DEVDOTDOT){
|
if(s == DEVDOTDOT){
|
||||||
Qid tqiddir = {Qdir, 0, QTDIR};
|
Qid tqiddir = {Qdir, 0, QTDIR};
|
||||||
if((int)c->qid.path < Qboot)
|
tqiddir.path = c->qid.path&0xF000;
|
||||||
devdir(c, tqiddir, "#/", 0, eve, 0555, dp);
|
devdir(c, tqiddir, "#/", 0, eve, 0555, dp);
|
||||||
else {
|
|
||||||
tqiddir.path = Qboot;
|
|
||||||
devdir(c, tqiddir, "#/", 0, eve, 0555, dp);
|
|
||||||
}
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
if(s != 0)
|
if(s != 0)
|
||||||
return -1;
|
return -1;
|
||||||
if((int)c->qid.path < Qboot){
|
switch((int)c->qid.path & 0xF000){
|
||||||
|
case Qdir:
|
||||||
t = c->qid.path-1;
|
t = c->qid.path-1;
|
||||||
l = &rootlist;
|
l = &rootlist;
|
||||||
}else{
|
break;
|
||||||
|
case Qboot:
|
||||||
t = c->qid.path - Qboot - 1;
|
t = c->qid.path - Qboot - 1;
|
||||||
l = &bootlist;
|
l = &bootlist;
|
||||||
|
break;
|
||||||
|
case Qmnt:
|
||||||
|
t = c->qid.path - Qmnt - 1;
|
||||||
|
l = &mntlist;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
if(t >= l->ndir)
|
if(t >= l->ndir)
|
||||||
return -1;
|
return -1;
|
||||||
@ -209,17 +235,19 @@ rootread(Chan *c, void *buf, long n, vlong off)
|
|||||||
switch(t){
|
switch(t){
|
||||||
case Qdir:
|
case Qdir:
|
||||||
case Qboot:
|
case Qboot:
|
||||||
|
case Qmnt:
|
||||||
return devdirread(c, buf, n, nil, 0, rootgen);
|
return devdirread(c, buf, n, nil, 0, rootgen);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(t<Qboot)
|
if(t&Qboot)
|
||||||
l = &rootlist;
|
|
||||||
else{
|
|
||||||
t -= Qboot;
|
|
||||||
l = &bootlist;
|
l = &bootlist;
|
||||||
}
|
else if(t&Qmnt)
|
||||||
|
l = &mntlist;
|
||||||
|
else
|
||||||
|
l = &bootlist;
|
||||||
|
t &= 0xFFF;
|
||||||
t--;
|
t--;
|
||||||
|
|
||||||
if(t >= l->ndir)
|
if(t >= l->ndir)
|
||||||
error(Egreg);
|
error(Egreg);
|
||||||
|
|
||||||
|
@ -765,6 +765,7 @@ sslput(Dstate *s, Block * volatile b)
|
|||||||
int offset;
|
int offset;
|
||||||
|
|
||||||
if(waserror()){
|
if(waserror()){
|
||||||
|
iprint("error: %s\n", up->errstr);
|
||||||
if(b != nil)
|
if(b != nil)
|
||||||
free(b);
|
free(b);
|
||||||
nexterror();
|
nexterror();
|
||||||
@ -1071,8 +1072,9 @@ sslwrite(Chan *c, void *a, long n, vlong o)
|
|||||||
nexterror();
|
nexterror();
|
||||||
}
|
}
|
||||||
qlock(&s->out.q);
|
qlock(&s->out.q);
|
||||||
|
|
||||||
p = a;
|
p = a;
|
||||||
|
if(0) iprint("write %d %.2ux %.2ux %.2ux %.2ux %.2ux %.2ux %.2ux %.2ux\n",
|
||||||
|
n, p[0], p[1], p[2], p[3], p[4], p[5], p[6], p[7]);
|
||||||
e = p + n;
|
e = p + n;
|
||||||
do {
|
do {
|
||||||
m = e - p;
|
m = e - p;
|
||||||
@ -1092,7 +1094,9 @@ sslwrite(Chan *c, void *a, long n, vlong o)
|
|||||||
|
|
||||||
p += m;
|
p += m;
|
||||||
} while(p < e);
|
} while(p < e);
|
||||||
|
p = a;
|
||||||
|
if(0) iprint("wrote %d %.2ux %.2ux %.2ux %.2ux %.2ux %.2ux %.2ux %.2ux\n",
|
||||||
|
n, p[0], p[1], p[2], p[3], p[4], p[5], p[6], p[7]);
|
||||||
poperror();
|
poperror();
|
||||||
qunlock(&s->out.q);
|
qunlock(&s->out.q);
|
||||||
return n;
|
return n;
|
||||||
|
@ -12,6 +12,8 @@ extern Dev mousedevtab;
|
|||||||
extern Dev drawdevtab;
|
extern Dev drawdevtab;
|
||||||
extern Dev ipdevtab;
|
extern Dev ipdevtab;
|
||||||
extern Dev fsdevtab;
|
extern Dev fsdevtab;
|
||||||
|
extern Dev mntdevtab;
|
||||||
|
extern Dev lfddevtab;
|
||||||
|
|
||||||
Dev *devtab[] = {
|
Dev *devtab[] = {
|
||||||
&rootdevtab,
|
&rootdevtab,
|
||||||
@ -22,6 +24,8 @@ Dev *devtab[] = {
|
|||||||
&drawdevtab,
|
&drawdevtab,
|
||||||
&ipdevtab,
|
&ipdevtab,
|
||||||
&fsdevtab,
|
&fsdevtab,
|
||||||
|
&mntdevtab,
|
||||||
|
&lfddevtab,
|
||||||
0
|
0
|
||||||
};
|
};
|
||||||
|
|
||||||
|
21
libauth/Makefile
Normal file
21
libauth/Makefile
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
ROOT=..
|
||||||
|
include ../Make.config
|
||||||
|
|
||||||
|
LIB=libauth.a
|
||||||
|
OFILES=\
|
||||||
|
attr.$O\
|
||||||
|
auth_attr.$O\
|
||||||
|
auth_challenge.$O\
|
||||||
|
auth_getuserpasswd.$O\
|
||||||
|
auth_proxy.$O\
|
||||||
|
auth_respond.$O\
|
||||||
|
auth_rpc.$O\
|
||||||
|
auth_userpasswd.$O\
|
||||||
|
|
||||||
|
$(LIB): $(OFILES)
|
||||||
|
$(AR) r $(LIB) $(OFILES)
|
||||||
|
$(RANLIB) $(LIB)
|
||||||
|
|
||||||
|
%.$O: %.c
|
||||||
|
$(CC) $(CFLAGS) $*.c
|
||||||
|
|
174
libauth/attr.c
Normal file
174
libauth/attr.c
Normal file
@ -0,0 +1,174 @@
|
|||||||
|
#include <u.h>
|
||||||
|
#include <libc.h>
|
||||||
|
#include <auth.h>
|
||||||
|
|
||||||
|
int
|
||||||
|
_attrfmt(Fmt *fmt)
|
||||||
|
{
|
||||||
|
char *b, buf[1024], *ebuf;
|
||||||
|
Attr *a;
|
||||||
|
|
||||||
|
ebuf = buf+sizeof buf;
|
||||||
|
b = buf;
|
||||||
|
strcpy(buf, " ");
|
||||||
|
for(a=va_arg(fmt->args, Attr*); a; a=a->next){
|
||||||
|
if(a->name == nil)
|
||||||
|
continue;
|
||||||
|
switch(a->type){
|
||||||
|
case AttrQuery:
|
||||||
|
b = seprint(b, ebuf, " %q?", a->name);
|
||||||
|
break;
|
||||||
|
case AttrNameval:
|
||||||
|
b = seprint(b, ebuf, " %q=%q", a->name, a->val);
|
||||||
|
break;
|
||||||
|
case AttrDefault:
|
||||||
|
b = seprint(b, ebuf, " %q:=%q", a->name, a->val);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return fmtstrcpy(fmt, buf+1);
|
||||||
|
}
|
||||||
|
|
||||||
|
Attr*
|
||||||
|
_copyattr(Attr *a)
|
||||||
|
{
|
||||||
|
Attr **la, *na;
|
||||||
|
|
||||||
|
na = nil;
|
||||||
|
la = &na;
|
||||||
|
for(; a; a=a->next){
|
||||||
|
*la = _mkattr(a->type, a->name, a->val, nil);
|
||||||
|
setmalloctag(*la, getcallerpc(&a));
|
||||||
|
la = &(*la)->next;
|
||||||
|
}
|
||||||
|
*la = nil;
|
||||||
|
return na;
|
||||||
|
}
|
||||||
|
|
||||||
|
Attr*
|
||||||
|
_delattr(Attr *a, char *name)
|
||||||
|
{
|
||||||
|
Attr *fa;
|
||||||
|
Attr **la;
|
||||||
|
|
||||||
|
for(la=&a; *la; ){
|
||||||
|
if(strcmp((*la)->name, name) == 0){
|
||||||
|
fa = *la;
|
||||||
|
*la = (*la)->next;
|
||||||
|
fa->next = nil;
|
||||||
|
_freeattr(fa);
|
||||||
|
}else
|
||||||
|
la=&(*la)->next;
|
||||||
|
}
|
||||||
|
return a;
|
||||||
|
}
|
||||||
|
|
||||||
|
Attr*
|
||||||
|
_findattr(Attr *a, char *n)
|
||||||
|
{
|
||||||
|
for(; a; a=a->next)
|
||||||
|
if(strcmp(a->name, n) == 0 && a->type != AttrQuery)
|
||||||
|
return a;
|
||||||
|
return nil;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
_freeattr(Attr *a)
|
||||||
|
{
|
||||||
|
Attr *anext;
|
||||||
|
|
||||||
|
for(; a; a=anext){
|
||||||
|
anext = a->next;
|
||||||
|
free(a->name);
|
||||||
|
free(a->val);
|
||||||
|
a->name = (void*)~0;
|
||||||
|
a->val = (void*)~0;
|
||||||
|
a->next = (void*)~0;
|
||||||
|
free(a);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Attr*
|
||||||
|
_mkattr(int type, char *name, char *val, Attr *next)
|
||||||
|
{
|
||||||
|
Attr *a;
|
||||||
|
|
||||||
|
a = malloc(sizeof(*a));
|
||||||
|
if(a==nil)
|
||||||
|
sysfatal("_mkattr malloc: %r");
|
||||||
|
a->type = type;
|
||||||
|
a->name = strdup(name);
|
||||||
|
a->val = strdup(val);
|
||||||
|
if(a->name==nil || a->val==nil)
|
||||||
|
sysfatal("_mkattr malloc: %r");
|
||||||
|
a->next = next;
|
||||||
|
setmalloctag(a, getcallerpc(&type));
|
||||||
|
return a;
|
||||||
|
}
|
||||||
|
|
||||||
|
static Attr*
|
||||||
|
cleanattr(Attr *a)
|
||||||
|
{
|
||||||
|
Attr *fa;
|
||||||
|
Attr **la;
|
||||||
|
|
||||||
|
for(la=&a; *la; ){
|
||||||
|
if((*la)->type==AttrQuery && _findattr(a, (*la)->name)){
|
||||||
|
fa = *la;
|
||||||
|
*la = (*la)->next;
|
||||||
|
fa->next = nil;
|
||||||
|
_freeattr(fa);
|
||||||
|
}else
|
||||||
|
la=&(*la)->next;
|
||||||
|
}
|
||||||
|
return a;
|
||||||
|
}
|
||||||
|
|
||||||
|
Attr*
|
||||||
|
_parseattr(char *s)
|
||||||
|
{
|
||||||
|
char *p, *t, *tok[256];
|
||||||
|
int i, ntok, type;
|
||||||
|
Attr *a;
|
||||||
|
|
||||||
|
s = strdup(s);
|
||||||
|
if(s == nil)
|
||||||
|
sysfatal("_parseattr strdup: %r");
|
||||||
|
|
||||||
|
ntok = tokenize(s, tok, nelem(tok));
|
||||||
|
a = nil;
|
||||||
|
for(i=ntok-1; i>=0; i--){
|
||||||
|
t = tok[i];
|
||||||
|
if(p = strchr(t, '=')){
|
||||||
|
*p++ = '\0';
|
||||||
|
// if(p-2 >= t && p[-2] == ':'){
|
||||||
|
// p[-2] = '\0';
|
||||||
|
// type = AttrDefault;
|
||||||
|
// }else
|
||||||
|
type = AttrNameval;
|
||||||
|
a = _mkattr(type, t, p, a);
|
||||||
|
setmalloctag(a, getcallerpc(&s));
|
||||||
|
}
|
||||||
|
else if(t[strlen(t)-1] == '?'){
|
||||||
|
t[strlen(t)-1] = '\0';
|
||||||
|
a = _mkattr(AttrQuery, t, "", a);
|
||||||
|
setmalloctag(a, getcallerpc(&s));
|
||||||
|
}else{
|
||||||
|
/* really a syntax error, but better to provide some indication */
|
||||||
|
a = _mkattr(AttrNameval, t, "", a);
|
||||||
|
setmalloctag(a, getcallerpc(&s));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
free(s);
|
||||||
|
return cleanattr(a);
|
||||||
|
}
|
||||||
|
|
||||||
|
char*
|
||||||
|
_strfindattr(Attr *a, char *n)
|
||||||
|
{
|
||||||
|
a = _findattr(a, n);
|
||||||
|
if(a == nil)
|
||||||
|
return nil;
|
||||||
|
return a->val;
|
||||||
|
}
|
||||||
|
|
13
libauth/auth_attr.c
Normal file
13
libauth/auth_attr.c
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
#include <u.h>
|
||||||
|
#include <libc.h>
|
||||||
|
#include <auth.h>
|
||||||
|
#include <authsrv.h>
|
||||||
|
#include "authlocal.h"
|
||||||
|
|
||||||
|
Attr*
|
||||||
|
auth_attr(AuthRpc *rpc)
|
||||||
|
{
|
||||||
|
if(auth_rpc(rpc, "attr", nil, 0) != ARok)
|
||||||
|
return nil;
|
||||||
|
return _parseattr(rpc->arg);
|
||||||
|
}
|
117
libauth/auth_challenge.c
Normal file
117
libauth/auth_challenge.c
Normal file
@ -0,0 +1,117 @@
|
|||||||
|
#include <u.h>
|
||||||
|
#include <libc.h>
|
||||||
|
#include <auth.h>
|
||||||
|
#include <authsrv.h>
|
||||||
|
#include "authlocal.h"
|
||||||
|
|
||||||
|
Chalstate*
|
||||||
|
auth_challenge(char *fmt, ...)
|
||||||
|
{
|
||||||
|
char *p;
|
||||||
|
va_list arg;
|
||||||
|
Chalstate *c;
|
||||||
|
|
||||||
|
quotefmtinstall(); /* just in case */
|
||||||
|
va_start(arg, fmt);
|
||||||
|
p = vsmprint(fmt, arg);
|
||||||
|
va_end(arg);
|
||||||
|
if(p == nil)
|
||||||
|
return nil;
|
||||||
|
|
||||||
|
c = mallocz(sizeof(*c), 1);
|
||||||
|
if(c == nil){
|
||||||
|
free(p);
|
||||||
|
return nil;
|
||||||
|
}
|
||||||
|
|
||||||
|
if((c->afd = open("/mnt/factotum/rpc", ORDWR)) < 0){
|
||||||
|
Error:
|
||||||
|
auth_freechal(c);
|
||||||
|
free(p);
|
||||||
|
return nil;
|
||||||
|
}
|
||||||
|
|
||||||
|
if((c->rpc=auth_allocrpc(c->afd)) == nil
|
||||||
|
|| auth_rpc(c->rpc, "start", p, strlen(p)) != ARok
|
||||||
|
|| auth_rpc(c->rpc, "read", nil, 0) != ARok)
|
||||||
|
goto Error;
|
||||||
|
|
||||||
|
if(c->rpc->narg > sizeof(c->chal)-1){
|
||||||
|
werrstr("buffer too small for challenge");
|
||||||
|
goto Error;
|
||||||
|
}
|
||||||
|
memmove(c->chal, c->rpc->arg, c->rpc->narg);
|
||||||
|
c->nchal = c->rpc->narg;
|
||||||
|
free(p);
|
||||||
|
return c;
|
||||||
|
}
|
||||||
|
|
||||||
|
AuthInfo*
|
||||||
|
auth_response(Chalstate *c)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
AuthInfo *ai;
|
||||||
|
|
||||||
|
ai = nil;
|
||||||
|
if(c->afd < 0){
|
||||||
|
werrstr("auth_response: connection not open");
|
||||||
|
return nil;
|
||||||
|
}
|
||||||
|
if(c->resp == nil){
|
||||||
|
werrstr("auth_response: nil response");
|
||||||
|
return nil;
|
||||||
|
}
|
||||||
|
if(c->nresp == 0){
|
||||||
|
werrstr("auth_response: unspecified response length");
|
||||||
|
return nil;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(c->user){
|
||||||
|
if(auth_rpc(c->rpc, "write", c->user, strlen(c->user)) != ARok){
|
||||||
|
/*
|
||||||
|
* if this fails we're out of phase with factotum.
|
||||||
|
* give up.
|
||||||
|
*/
|
||||||
|
goto Out;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(auth_rpc(c->rpc, "write", c->resp, c->nresp) != ARok){
|
||||||
|
/*
|
||||||
|
* don't close the connection -- maybe we'll try again.
|
||||||
|
*/
|
||||||
|
return nil;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch(ret = auth_rpc(c->rpc, "read", nil, 0)){
|
||||||
|
case ARok:
|
||||||
|
default:
|
||||||
|
werrstr("factotum protocol botch %d %s", ret, c->rpc->ibuf);
|
||||||
|
break;
|
||||||
|
case ARdone:
|
||||||
|
ai = auth_getinfo(c->rpc);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
Out:
|
||||||
|
close(c->afd);
|
||||||
|
auth_freerpc(c->rpc);
|
||||||
|
c->afd = -1;
|
||||||
|
c->rpc = nil;
|
||||||
|
return ai;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
auth_freechal(Chalstate *c)
|
||||||
|
{
|
||||||
|
if(c == nil)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if(c->afd >= 0)
|
||||||
|
close(c->afd);
|
||||||
|
if(c->rpc != nil)
|
||||||
|
auth_freerpc(c->rpc);
|
||||||
|
|
||||||
|
memset(c, 0xBB, sizeof(*c));
|
||||||
|
free(c);
|
||||||
|
}
|
75
libauth/auth_getuserpasswd.c
Normal file
75
libauth/auth_getuserpasswd.c
Normal file
@ -0,0 +1,75 @@
|
|||||||
|
#include <u.h>
|
||||||
|
#include <libc.h>
|
||||||
|
#include <auth.h>
|
||||||
|
#include "authlocal.h"
|
||||||
|
|
||||||
|
enum {
|
||||||
|
ARgiveup = 100,
|
||||||
|
};
|
||||||
|
|
||||||
|
static int
|
||||||
|
dorpc(AuthRpc *rpc, char *verb, char *val, int len, AuthGetkey *getkey)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
for(;;){
|
||||||
|
if((ret = auth_rpc(rpc, verb, val, len)) != ARneedkey && ret != ARbadkey)
|
||||||
|
return ret;
|
||||||
|
if(getkey == nil)
|
||||||
|
return ARgiveup; /* don't know how */
|
||||||
|
if((*getkey)(rpc->arg) < 0)
|
||||||
|
return ARgiveup; /* user punted */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
UserPasswd*
|
||||||
|
auth_getuserpasswd(AuthGetkey *getkey, char *fmt, ...)
|
||||||
|
{
|
||||||
|
AuthRpc *rpc;
|
||||||
|
char *f[3], *p, *params;
|
||||||
|
int fd;
|
||||||
|
va_list arg;
|
||||||
|
UserPasswd *up;
|
||||||
|
|
||||||
|
up = nil;
|
||||||
|
rpc = nil;
|
||||||
|
params = nil;
|
||||||
|
|
||||||
|
fd = open("/mnt/factotum/rpc", ORDWR);
|
||||||
|
if(fd < 0)
|
||||||
|
goto out;
|
||||||
|
rpc = auth_allocrpc(fd);
|
||||||
|
if(rpc == nil)
|
||||||
|
goto out;
|
||||||
|
quotefmtinstall(); /* just in case */
|
||||||
|
va_start(arg, fmt);
|
||||||
|
params = vsmprint(fmt, arg);
|
||||||
|
va_end(arg);
|
||||||
|
if(params == nil)
|
||||||
|
goto out;
|
||||||
|
|
||||||
|
if(dorpc(rpc, "start", params, strlen(params), getkey) != ARok
|
||||||
|
|| dorpc(rpc, "read", nil, 0, getkey) != ARok)
|
||||||
|
goto out;
|
||||||
|
|
||||||
|
rpc->arg[rpc->narg] = '\0';
|
||||||
|
if(tokenize(rpc->arg, f, 2) != 2){
|
||||||
|
werrstr("bad answer from factotum");
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
up = malloc(sizeof(*up)+rpc->narg+1);
|
||||||
|
if(up == nil)
|
||||||
|
goto out;
|
||||||
|
p = (char*)&up[1];
|
||||||
|
strcpy(p, f[0]);
|
||||||
|
up->user = p;
|
||||||
|
p += strlen(p)+1;
|
||||||
|
strcpy(p, f[1]);
|
||||||
|
up->passwd = p;
|
||||||
|
|
||||||
|
out:
|
||||||
|
free(params);
|
||||||
|
auth_freerpc(rpc);
|
||||||
|
close(fd);
|
||||||
|
return up;
|
||||||
|
}
|
212
libauth/auth_proxy.c
Normal file
212
libauth/auth_proxy.c
Normal file
@ -0,0 +1,212 @@
|
|||||||
|
#include <u.h>
|
||||||
|
#include <libc.h>
|
||||||
|
#include <fcall.h>
|
||||||
|
#include <auth.h>
|
||||||
|
#include "authlocal.h"
|
||||||
|
|
||||||
|
enum {
|
||||||
|
ARgiveup = 100,
|
||||||
|
};
|
||||||
|
|
||||||
|
static uchar*
|
||||||
|
gstring(uchar *p, uchar *ep, char **s)
|
||||||
|
{
|
||||||
|
uint n;
|
||||||
|
|
||||||
|
if(p == nil)
|
||||||
|
return nil;
|
||||||
|
if(p+BIT16SZ > ep)
|
||||||
|
return nil;
|
||||||
|
n = GBIT16(p);
|
||||||
|
p += BIT16SZ;
|
||||||
|
if(p+n > ep)
|
||||||
|
return nil;
|
||||||
|
*s = malloc(n+1);
|
||||||
|
memmove((*s), p, n);
|
||||||
|
(*s)[n] = '\0';
|
||||||
|
p += n;
|
||||||
|
return p;
|
||||||
|
}
|
||||||
|
|
||||||
|
static uchar*
|
||||||
|
gcarray(uchar *p, uchar *ep, uchar **s, int *np)
|
||||||
|
{
|
||||||
|
uint n;
|
||||||
|
|
||||||
|
if(p == nil)
|
||||||
|
return nil;
|
||||||
|
if(p+BIT16SZ > ep)
|
||||||
|
return nil;
|
||||||
|
n = GBIT16(p);
|
||||||
|
p += BIT16SZ;
|
||||||
|
if(p+n > ep)
|
||||||
|
return nil;
|
||||||
|
*s = malloc(n);
|
||||||
|
if(*s == nil)
|
||||||
|
return nil;
|
||||||
|
memmove((*s), p, n);
|
||||||
|
*np = n;
|
||||||
|
p += n;
|
||||||
|
return p;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
auth_freeAI(AuthInfo *ai)
|
||||||
|
{
|
||||||
|
if(ai == nil)
|
||||||
|
return;
|
||||||
|
free(ai->cuid);
|
||||||
|
free(ai->suid);
|
||||||
|
free(ai->cap);
|
||||||
|
free(ai->secret);
|
||||||
|
free(ai);
|
||||||
|
}
|
||||||
|
|
||||||
|
static uchar*
|
||||||
|
convM2AI(uchar *p, int n, AuthInfo **aip)
|
||||||
|
{
|
||||||
|
uchar *e = p+n;
|
||||||
|
AuthInfo *ai;
|
||||||
|
|
||||||
|
ai = mallocz(sizeof(*ai), 1);
|
||||||
|
if(ai == nil)
|
||||||
|
return nil;
|
||||||
|
|
||||||
|
p = gstring(p, e, &ai->cuid);
|
||||||
|
p = gstring(p, e, &ai->suid);
|
||||||
|
p = gstring(p, e, &ai->cap);
|
||||||
|
p = gcarray(p, e, &ai->secret, &ai->nsecret);
|
||||||
|
if(p == nil)
|
||||||
|
auth_freeAI(ai);
|
||||||
|
else
|
||||||
|
*aip = ai;
|
||||||
|
return p;
|
||||||
|
}
|
||||||
|
|
||||||
|
AuthInfo*
|
||||||
|
auth_getinfo(AuthRpc *rpc)
|
||||||
|
{
|
||||||
|
AuthInfo *a;
|
||||||
|
|
||||||
|
if(auth_rpc(rpc, "authinfo", nil, 0) != ARok)
|
||||||
|
return nil;
|
||||||
|
if(convM2AI((uchar*)rpc->arg, rpc->narg, &a) == nil){
|
||||||
|
werrstr("bad auth info from factotum");
|
||||||
|
return nil;
|
||||||
|
}
|
||||||
|
return a;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
dorpc(AuthRpc *rpc, char *verb, char *val, int len, AuthGetkey *getkey)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
for(;;){
|
||||||
|
if((ret = auth_rpc(rpc, verb, val, len)) != ARneedkey && ret != ARbadkey)
|
||||||
|
return ret;
|
||||||
|
if(getkey == nil)
|
||||||
|
return ARgiveup; /* don't know how */
|
||||||
|
if((*getkey)(rpc->arg) < 0)
|
||||||
|
return ARgiveup; /* user punted */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* this just proxies what the factotum tells it to.
|
||||||
|
*/
|
||||||
|
AuthInfo*
|
||||||
|
fauth_proxy(int fd, AuthRpc *rpc, AuthGetkey *getkey, char *params)
|
||||||
|
{
|
||||||
|
char *buf;
|
||||||
|
int m, n, ret;
|
||||||
|
AuthInfo *a;
|
||||||
|
char oerr[ERRMAX];
|
||||||
|
|
||||||
|
rerrstr(oerr, sizeof oerr);
|
||||||
|
werrstr("UNKNOWN AUTH ERROR");
|
||||||
|
|
||||||
|
if(dorpc(rpc, "start", params, strlen(params), getkey) != ARok){
|
||||||
|
werrstr("fauth_proxy start: %r");
|
||||||
|
return nil;
|
||||||
|
}
|
||||||
|
|
||||||
|
buf = malloc(AuthRpcMax);
|
||||||
|
if(buf == nil)
|
||||||
|
return nil;
|
||||||
|
for(;;){
|
||||||
|
switch(dorpc(rpc, "read", nil, 0, getkey)){
|
||||||
|
case ARdone:
|
||||||
|
free(buf);
|
||||||
|
a = auth_getinfo(rpc);
|
||||||
|
errstr(oerr, sizeof oerr); /* no error, restore whatever was there */
|
||||||
|
return a;
|
||||||
|
case ARok:
|
||||||
|
if(write(fd, rpc->arg, rpc->narg) != rpc->narg){
|
||||||
|
werrstr("auth_proxy write fd: %r");
|
||||||
|
goto Error;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case ARphase:
|
||||||
|
n = 0;
|
||||||
|
memset(buf, 0, AuthRpcMax);
|
||||||
|
while((ret = dorpc(rpc, "write", buf, n, getkey)) == ARtoosmall){
|
||||||
|
if(atoi(rpc->arg) > AuthRpcMax)
|
||||||
|
break;
|
||||||
|
m = read(fd, buf+n, atoi(rpc->arg)-n);
|
||||||
|
if(m <= 0){
|
||||||
|
if(m == 0)
|
||||||
|
werrstr("auth_proxy short read: %s", buf);
|
||||||
|
goto Error;
|
||||||
|
}
|
||||||
|
n += m;
|
||||||
|
}
|
||||||
|
if(ret != ARok){
|
||||||
|
werrstr("auth_proxy rpc write: %s: %r", buf);
|
||||||
|
goto Error;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
werrstr("auth_proxy rpc: %r");
|
||||||
|
goto Error;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Error:
|
||||||
|
free(buf);
|
||||||
|
return nil;
|
||||||
|
}
|
||||||
|
|
||||||
|
AuthInfo*
|
||||||
|
auth_proxy(int fd, AuthGetkey *getkey, char *fmt, ...)
|
||||||
|
{
|
||||||
|
int afd;
|
||||||
|
char *p;
|
||||||
|
va_list arg;
|
||||||
|
AuthInfo *ai;
|
||||||
|
AuthRpc *rpc;
|
||||||
|
|
||||||
|
quotefmtinstall(); /* just in case */
|
||||||
|
va_start(arg, fmt);
|
||||||
|
p = vsmprint(fmt, arg);
|
||||||
|
va_end(arg);
|
||||||
|
|
||||||
|
afd = open("/mnt/factotum/rpc", ORDWR);
|
||||||
|
if(afd < 0){
|
||||||
|
werrstr("opening /mnt/factotum/rpc: %r");
|
||||||
|
free(p);
|
||||||
|
return nil;
|
||||||
|
}
|
||||||
|
|
||||||
|
rpc = auth_allocrpc(afd);
|
||||||
|
if(rpc == nil){
|
||||||
|
free(p);
|
||||||
|
return nil;
|
||||||
|
}
|
||||||
|
|
||||||
|
ai = fauth_proxy(fd, rpc, getkey, p);
|
||||||
|
free(p);
|
||||||
|
auth_freerpc(rpc);
|
||||||
|
close(afd);
|
||||||
|
return ai;
|
||||||
|
}
|
||||||
|
|
73
libauth/auth_respond.c
Normal file
73
libauth/auth_respond.c
Normal file
@ -0,0 +1,73 @@
|
|||||||
|
#include <u.h>
|
||||||
|
#include <libc.h>
|
||||||
|
#include <auth.h>
|
||||||
|
#include <authsrv.h>
|
||||||
|
#include "authlocal.h"
|
||||||
|
|
||||||
|
enum {
|
||||||
|
ARgiveup = 100,
|
||||||
|
};
|
||||||
|
|
||||||
|
static int
|
||||||
|
dorpc(AuthRpc *rpc, char *verb, char *val, int len, AuthGetkey *getkey)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
for(;;){
|
||||||
|
if((ret = auth_rpc(rpc, verb, val, len)) != ARneedkey && ret != ARbadkey)
|
||||||
|
return ret;
|
||||||
|
if(getkey == nil)
|
||||||
|
return ARgiveup; /* don't know how */
|
||||||
|
if((*getkey)(rpc->arg) < 0)
|
||||||
|
return ARgiveup; /* user punted */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
auth_respond(void *chal, uint nchal, char *user, uint nuser, void *resp, uint nresp, AuthGetkey *getkey, char *fmt, ...)
|
||||||
|
{
|
||||||
|
char *p, *s;
|
||||||
|
va_list arg;
|
||||||
|
int afd;
|
||||||
|
AuthRpc *rpc;
|
||||||
|
Attr *a;
|
||||||
|
|
||||||
|
if((afd = open("/mnt/factotum/rpc", ORDWR)) < 0)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
if((rpc = auth_allocrpc(afd)) == nil){
|
||||||
|
close(afd);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
quotefmtinstall(); /* just in case */
|
||||||
|
va_start(arg, fmt);
|
||||||
|
p = vsmprint(fmt, arg);
|
||||||
|
va_end(arg);
|
||||||
|
|
||||||
|
if(p==nil
|
||||||
|
|| dorpc(rpc, "start", p, strlen(p), getkey) != ARok
|
||||||
|
|| dorpc(rpc, "write", chal, nchal, getkey) != ARok
|
||||||
|
|| dorpc(rpc, "read", nil, 0, getkey) != ARok){
|
||||||
|
free(p);
|
||||||
|
close(afd);
|
||||||
|
auth_freerpc(rpc);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
free(p);
|
||||||
|
|
||||||
|
if(rpc->narg < nresp)
|
||||||
|
nresp = rpc->narg;
|
||||||
|
memmove(resp, rpc->arg, nresp);
|
||||||
|
|
||||||
|
if((a = auth_attr(rpc)) != nil
|
||||||
|
&& (s = _strfindattr(a, "user")) != nil && strlen(s) < nuser)
|
||||||
|
strcpy(user, s);
|
||||||
|
else if(nuser > 0)
|
||||||
|
user[0] = '\0';
|
||||||
|
|
||||||
|
_freeattr(a);
|
||||||
|
close(afd);
|
||||||
|
auth_freerpc(rpc);
|
||||||
|
return nresp;
|
||||||
|
}
|
116
libauth/auth_rpc.c
Normal file
116
libauth/auth_rpc.c
Normal file
@ -0,0 +1,116 @@
|
|||||||
|
#include <u.h>
|
||||||
|
#include <libc.h>
|
||||||
|
#include <auth.h>
|
||||||
|
#include "authlocal.h"
|
||||||
|
|
||||||
|
static struct {
|
||||||
|
char *verb;
|
||||||
|
int val;
|
||||||
|
} tab[] = {
|
||||||
|
"ok", ARok,
|
||||||
|
"done", ARdone,
|
||||||
|
"error", ARerror,
|
||||||
|
"needkey", ARneedkey,
|
||||||
|
"badkey", ARbadkey,
|
||||||
|
"phase", ARphase,
|
||||||
|
"toosmall", ARtoosmall,
|
||||||
|
"error", ARerror,
|
||||||
|
};
|
||||||
|
|
||||||
|
static int
|
||||||
|
classify(char *buf, uint n, AuthRpc *rpc)
|
||||||
|
{
|
||||||
|
int i, len;
|
||||||
|
|
||||||
|
for(i=0; i<nelem(tab); i++){
|
||||||
|
len = strlen(tab[i].verb);
|
||||||
|
if(n >= len && memcmp(buf, tab[i].verb, len) == 0 && (n==len || buf[len]==' ')){
|
||||||
|
if(n==len){
|
||||||
|
rpc->narg = 0;
|
||||||
|
rpc->arg = "";
|
||||||
|
}else{
|
||||||
|
rpc->narg = n - (len+1);
|
||||||
|
rpc->arg = (char*)buf+len+1;
|
||||||
|
}
|
||||||
|
return tab[i].val;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
werrstr("malformed rpc response: %s", buf);
|
||||||
|
return ARrpcfailure;
|
||||||
|
}
|
||||||
|
|
||||||
|
AuthRpc*
|
||||||
|
auth_allocrpc(int afd)
|
||||||
|
{
|
||||||
|
AuthRpc *rpc;
|
||||||
|
|
||||||
|
rpc = mallocz(sizeof(*rpc), 1);
|
||||||
|
if(rpc == nil)
|
||||||
|
return nil;
|
||||||
|
rpc->afd = afd;
|
||||||
|
return rpc;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
auth_freerpc(AuthRpc *rpc)
|
||||||
|
{
|
||||||
|
free(rpc);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint
|
||||||
|
auth_rpc(AuthRpc *rpc, char *verb, void *a, int na)
|
||||||
|
{
|
||||||
|
int l, n, type;
|
||||||
|
char *f[4];
|
||||||
|
|
||||||
|
l = strlen(verb);
|
||||||
|
if(na+l+1 > AuthRpcMax){
|
||||||
|
werrstr("rpc too big");
|
||||||
|
return ARtoobig;
|
||||||
|
}
|
||||||
|
|
||||||
|
memmove(rpc->obuf, verb, l);
|
||||||
|
rpc->obuf[l] = ' ';
|
||||||
|
memmove(rpc->obuf+l+1, a, na);
|
||||||
|
if((n=write(rpc->afd, rpc->obuf, l+1+na)) != l+1+na){
|
||||||
|
if(n >= 0)
|
||||||
|
werrstr("auth_rpc short write");
|
||||||
|
return ARrpcfailure;
|
||||||
|
}
|
||||||
|
|
||||||
|
if((n=read(rpc->afd, rpc->ibuf, AuthRpcMax)) < 0)
|
||||||
|
return ARrpcfailure;
|
||||||
|
rpc->ibuf[n] = '\0';
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Set error string for good default behavior.
|
||||||
|
*/
|
||||||
|
switch(type = classify(rpc->ibuf, n, rpc)){
|
||||||
|
default:
|
||||||
|
werrstr("unknown rpc type %d (bug in auth_rpc.c)", type);
|
||||||
|
break;
|
||||||
|
case ARok:
|
||||||
|
break;
|
||||||
|
case ARrpcfailure:
|
||||||
|
break;
|
||||||
|
case ARerror:
|
||||||
|
if(rpc->narg == 0)
|
||||||
|
werrstr("unspecified rpc error");
|
||||||
|
else
|
||||||
|
werrstr("%s", rpc->arg);
|
||||||
|
break;
|
||||||
|
case ARneedkey:
|
||||||
|
werrstr("needkey %s", rpc->arg);
|
||||||
|
break;
|
||||||
|
case ARbadkey:
|
||||||
|
if(getfields(rpc->arg, f, nelem(f), 0, "\n") < 2)
|
||||||
|
werrstr("badkey %s", rpc->arg);
|
||||||
|
else
|
||||||
|
werrstr("badkey %s", f[1]);
|
||||||
|
break;
|
||||||
|
case ARphase:
|
||||||
|
werrstr("phase error %s", rpc->arg);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return type;
|
||||||
|
}
|
50
libauth/auth_userpasswd.c
Normal file
50
libauth/auth_userpasswd.c
Normal file
@ -0,0 +1,50 @@
|
|||||||
|
#include <u.h>
|
||||||
|
#include <libc.h>
|
||||||
|
#include <auth.h>
|
||||||
|
#include <authsrv.h>
|
||||||
|
#include "authlocal.h"
|
||||||
|
|
||||||
|
/*
|
||||||
|
* compute the proper response. We encrypt the ascii of
|
||||||
|
* challenge number, with trailing binary zero fill.
|
||||||
|
* This process was derived empirically.
|
||||||
|
* this was copied from inet's guard.
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
netresp(char *key, long chal, char *answer)
|
||||||
|
{
|
||||||
|
uchar buf[8];
|
||||||
|
|
||||||
|
memset(buf, 0, 8);
|
||||||
|
sprint((char *)buf, "%lud", chal);
|
||||||
|
if(encrypt(key, buf, 8) < 0)
|
||||||
|
abort();
|
||||||
|
chal = (buf[0]<<24)+(buf[1]<<16)+(buf[2]<<8)+buf[3];
|
||||||
|
sprint(answer, "%.8lux", chal);
|
||||||
|
}
|
||||||
|
|
||||||
|
AuthInfo*
|
||||||
|
auth_userpasswd(char *user, char *passwd)
|
||||||
|
{
|
||||||
|
char key[DESKEYLEN], resp[16];
|
||||||
|
AuthInfo *ai;
|
||||||
|
Chalstate *ch;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Probably we should have a factotum protocol
|
||||||
|
* to check a raw password. For now, we use
|
||||||
|
* p9cr, which is simplest to speak.
|
||||||
|
*/
|
||||||
|
if((ch = auth_challenge("user=%q proto=p9cr role=server", user)) == nil)
|
||||||
|
return nil;
|
||||||
|
|
||||||
|
passtokey(key, passwd);
|
||||||
|
netresp(key, atol(ch->chal), resp);
|
||||||
|
memset(key, 0, sizeof key);
|
||||||
|
|
||||||
|
ch->resp = resp;
|
||||||
|
ch->nresp = strlen(resp);
|
||||||
|
ai = auth_response(ch);
|
||||||
|
auth_freechal(ch);
|
||||||
|
return ai;
|
||||||
|
}
|
1
libauth/authlocal.h
Normal file
1
libauth/authlocal.h
Normal file
@ -0,0 +1 @@
|
|||||||
|
extern AuthInfo* _fauth_proxy(int fd, AuthRpc *rpc, AuthGetkey *getkey, char *params);
|
51
libauth/httpauth.c
Normal file
51
libauth/httpauth.c
Normal file
@ -0,0 +1,51 @@
|
|||||||
|
#include <u.h>
|
||||||
|
#include <libc.h>
|
||||||
|
#include <auth.h>
|
||||||
|
#include <authsrv.h>
|
||||||
|
|
||||||
|
/* deprecated.
|
||||||
|
This is the mechanism that put entries in /sys/lib/httpd.rewrite
|
||||||
|
and passwords on the authserver in /sys/lib/httppasswords, which
|
||||||
|
was awkward to administer. Instead, use local .httplogin files,
|
||||||
|
which are implemented in sys/src/cmd/ip/httpd/authorize.c */
|
||||||
|
|
||||||
|
int
|
||||||
|
httpauth(char *name, char *password)
|
||||||
|
{
|
||||||
|
int afd;
|
||||||
|
Ticketreq tr;
|
||||||
|
Ticket t;
|
||||||
|
char key[DESKEYLEN];
|
||||||
|
char buf[512];
|
||||||
|
|
||||||
|
afd = authdial(nil, nil);
|
||||||
|
if(afd < 0)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
/* send ticket request to AS */
|
||||||
|
memset(&tr, 0, sizeof(tr));
|
||||||
|
strcpy(tr.uid, name);
|
||||||
|
tr.type = AuthHttp;
|
||||||
|
convTR2M(&tr, buf);
|
||||||
|
if(write(afd, buf, TICKREQLEN) != TICKREQLEN){
|
||||||
|
close(afd);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if(_asrdresp(afd, buf, TICKETLEN) < 0){
|
||||||
|
close(afd);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
close(afd);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* use password and try to decrypt the
|
||||||
|
* ticket. If it doesn't work we've got a bad password,
|
||||||
|
* give up.
|
||||||
|
*/
|
||||||
|
passtokey(key, password);
|
||||||
|
convM2T(buf, &t, key);
|
||||||
|
if(t.num != AuthHr || strcmp(t.cuid, tr.uid))
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
2
main.c
2
main.c
@ -36,6 +36,8 @@ main(int argc, char **argv)
|
|||||||
char buf[1024], *s;
|
char buf[1024], *s;
|
||||||
int n;
|
int n;
|
||||||
|
|
||||||
|
eve = getuser();
|
||||||
|
|
||||||
sizebug();
|
sizebug();
|
||||||
fmtinstall('r', errfmt);
|
fmtinstall('r', errfmt);
|
||||||
|
|
||||||
|
107
posix-factotum.c
Normal file
107
posix-factotum.c
Normal file
@ -0,0 +1,107 @@
|
|||||||
|
#include <u.h>
|
||||||
|
#include <sys/socket.h>
|
||||||
|
#include <sys/un.h>
|
||||||
|
#include <pwd.h>
|
||||||
|
#include <libc.h>
|
||||||
|
#include <auth.h>
|
||||||
|
#include <fcall.h>
|
||||||
|
#include <authsrv.h>
|
||||||
|
#include <libsec.h>
|
||||||
|
#include "drawterm.h"
|
||||||
|
|
||||||
|
#undef socket
|
||||||
|
#undef connect
|
||||||
|
#undef getenv
|
||||||
|
#undef access
|
||||||
|
|
||||||
|
char*
|
||||||
|
getuser(void)
|
||||||
|
{
|
||||||
|
static char user[64];
|
||||||
|
struct passwd *pw;
|
||||||
|
|
||||||
|
pw = getpwuid(getuid());
|
||||||
|
if(pw == nil)
|
||||||
|
return "none";
|
||||||
|
strecpy(user, user+sizeof user, pw->pw_name);
|
||||||
|
return user;
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
* Absent other hints, it works reasonably well to use
|
||||||
|
* the X11 display name as the name space identifier.
|
||||||
|
* This is how sam's B has worked since the early days.
|
||||||
|
* Since most programs using name spaces are also using X,
|
||||||
|
* this still seems reasonable. Terminal-only sessions
|
||||||
|
* can set $NAMESPACE.
|
||||||
|
*/
|
||||||
|
static char*
|
||||||
|
nsfromdisplay(void)
|
||||||
|
{
|
||||||
|
int fd;
|
||||||
|
Dir *d;
|
||||||
|
char *disp, *p;
|
||||||
|
|
||||||
|
if((disp = getenv("DISPLAY")) == nil){
|
||||||
|
werrstr("$DISPLAY not set");
|
||||||
|
return nil;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* canonicalize: xxx:0.0 => xxx:0 */
|
||||||
|
p = strrchr(disp, ':');
|
||||||
|
if(p){
|
||||||
|
p++;
|
||||||
|
while(isdigit((uchar)*p))
|
||||||
|
p++;
|
||||||
|
if(strcmp(p, ".0") == 0)
|
||||||
|
*p = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return smprint("/tmp/ns.%s.%s", getuser(), disp);
|
||||||
|
}
|
||||||
|
|
||||||
|
char*
|
||||||
|
getns(void)
|
||||||
|
{
|
||||||
|
char *ns;
|
||||||
|
|
||||||
|
ns = getenv("NAMESPACE");
|
||||||
|
if(ns == nil)
|
||||||
|
ns = nsfromdisplay();
|
||||||
|
if(ns == nil){
|
||||||
|
werrstr("$NAMESPACE not set, %r");
|
||||||
|
return nil;
|
||||||
|
}
|
||||||
|
return ns;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
dialfactotum(void)
|
||||||
|
{
|
||||||
|
int fd;
|
||||||
|
struct sockaddr_un su;
|
||||||
|
char *name;
|
||||||
|
|
||||||
|
name = smprint("%s/factotum", getns());
|
||||||
|
|
||||||
|
if(name == nil || access(name, 0) < 0)
|
||||||
|
return -1;
|
||||||
|
memset(&su, 0, sizeof su);
|
||||||
|
su.sun_family = AF_UNIX;
|
||||||
|
if(strlen(name)+1 > sizeof su.sun_path){
|
||||||
|
werrstr("socket name too long");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
strcpy(su.sun_path, name);
|
||||||
|
if((fd = socket(AF_UNIX, SOCK_STREAM, 0)) < 0){
|
||||||
|
werrstr("socket: %r");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if(connect(fd, (struct sockaddr*)&su, sizeof su) < 0){
|
||||||
|
werrstr("connect %s: %r", name);
|
||||||
|
close(fd);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return lfdfd(fd);
|
||||||
|
}
|
||||||
|
|
22
win32-factotum.c
Normal file
22
win32-factotum.c
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
#include <u.h>
|
||||||
|
#include <libc.h>
|
||||||
|
#include <auth.h>
|
||||||
|
#include <fcall.h>
|
||||||
|
#include <authsrv.h>
|
||||||
|
#include <libsec.h>
|
||||||
|
#include "drawterm.h"
|
||||||
|
|
||||||
|
#undef getenv
|
||||||
|
|
||||||
|
char*
|
||||||
|
getuser(void)
|
||||||
|
{
|
||||||
|
return getenv("USER");
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
dialfactotum(void)
|
||||||
|
{
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
Loading…
x
Reference in New Issue
Block a user