Add IP-based checking to fossil.
[rsc] --rw-rw-r-- M 1428987 jmk sys 4438 Jan 28 11:32 sys/src/cmd/fossil/9.h
/n/sourcesdump/2006/0128/plan9/sys/src/cmd/fossil/9.h:44,57 -
/n/sourcesdump/2006/0129/plan9/sys/src/cmd/fossil/9.h:44,62
MsgF = 4,
};
+ enum {
+ ConNoneAllow = 1<<0,
+ ConNoAuthCheck = 1<<1,
+ ConNoPermCheck = 1<<2,
+ ConWstatAllow = 1<<3,
+ ConIPCheck = 1<<4,
+ };
struct Con {
char* name;
uchar* data; /* max, not negotiated */
int isconsole; /* immutable */
- int noauth; /* immutable */
- int noperm; /* immutable */
- int wstatallow; /* immutable */
-
+ int flags; /* immutable */
+ char remote[128]; /* immutable */
VtLock* lock;
int state;
int fd;
/n/sourcesdump/2006/0128/plan9/sys/src/cmd/fossil/9.h:191,197 -
/n/sourcesdump/2006/0129/plan9/sys/src/cmd/fossil/9.h:196,202
/*
* 9proc.c
*/
- extern Con* conAlloc(int, char*);
+ extern Con* conAlloc(int, char*, int);
extern void conInit(void);
extern void msgFlush(Msg*);
extern void msgInit(void);
[rsc] --rw-rw-r-- M 1428987 rsc sys 3863 Jan 28 11:32 sys/src/cmd/fossil/9auth.c
/n/sourcesdump/2006/0128/plan9/sys/src/cmd/fossil/9auth.c:84,93 -
/n/sourcesdump/2006/0129/plan9/sys/src/cmd/fossil/9auth.c:84,99
* authentication.
*/
vtRLock(con->alock);
- if(!con->isconsole &&
- (strcmp(fid->uname, unamenone) != 0 || !con->aok)){
+ if(con->isconsole){
+ /* anything goes */
+ }else if((con->flags&ConNoneAllow) || con->aok){
+ consPrint("attach %s as %s: allowing as none\n", fsysGetName(fsys), fid->uname);
+ vtMemFree(fid->uname);
+ fid->uname = vtStrDup(unamenone);
+ }else{
vtRUnlock(con->alock);
consPrint("attach %s as %s: connection not authenticated, not console\n", fsysGetName(fsys), fid->uname);
+ vtSetError("cannot attach as none before authentication");
return 0;
}
vtRUnlock(con->alock);
/n/sourcesdump/2006/0128/plan9/sys/src/cmd/fossil/9auth.c:94,99 -
/n/sourcesdump/2006/0129/plan9/sys/src/cmd/fossil/9auth.c:100,106
if((fid->uid = uidByUname(fid->uname)) == nil){
consPrint("attach %s as %s: unknown uname\n", fsysGetName(fsys), fid->uname);
+ vtSetError("unknown user");
return 0;
}
return 1;
/n/sourcesdump/2006/0128/plan9/sys/src/cmd/fossil/9auth.c:101,106 -
/n/sourcesdump/2006/0129/plan9/sys/src/cmd/fossil/9auth.c:108,114
if((afid = fidGet(con, t->afid, 0)) == nil){
consPrint("attach %s as %s: bad afid\n", fsysGetName(fsys), fid->uname);
+ vtSetError("bad authentication fid");
return 0;
}
/n/sourcesdump/2006/0128/plan9/sys/src/cmd/fossil/9auth.c:111,121 -
/n/sourcesdump/2006/0129/plan9/sys/src/cmd/fossil/9auth.c:119,131
if(!(afid->qid.type & QTAUTH)){
consPrint("attach %s as %s: afid not an auth file\n", fsysGetName(fsys), fid->uname);
fidPut(afid);
+ vtSetError("bad authentication fid");
return 0;
}
if(strcmp(afid->uname, fid->uname) != 0 || afid->fsys != fsys){
consPrint("attach %s as %s: afid is for %s as %s\n", fsysGetName(fsys), fid->uname, fsysGetName(afid->fsys), afid->uname);
fidPut(afid);
+ vtSetError("attach/auth mismatch");
return 0;
}
/n/sourcesdump/2006/0128/plan9/sys/src/cmd/fossil/9auth.c:125,130 -
/n/sourcesdump/2006/0129/plan9/sys/src/cmd/fossil/9auth.c:135,141
vtUnlock(afid->alock);
consPrint("attach %s as %s: %R\n", fsysGetName(fsys), fid->uname);
fidPut(afid);
+ vtSetError("authentication protocol not finished");
return 0;
}
}
/n/sourcesdump/2006/0128/plan9/sys/src/cmd/fossil/9auth.c:134,139 -
/n/sourcesdump/2006/0129/plan9/sys/src/cmd/fossil/9auth.c:145,151
if((fid->uid = uidByUname(afid->cuname)) == nil){
consPrint("attach %s as %s: unknown cuname %s\n", fsysGetName(fsys), fid->uname, afid->cuname);
fidPut(afid);
+ vtSetError("unknown user");
return 0;
}
[rsc] --rw-rw-r-- M 1428987 rsc sys 3024 Jan 28 12:31 sys/src/cmd/fossil/9lstn.c
/n/sourcesdump/2006/0128/plan9/sys/src/cmd/fossil/9lstn.c:5,10 -
/n/sourcesdump/2006/0129/plan9/sys/src/cmd/fossil/9lstn.c:5,11
typedef struct Lstn Lstn;
typedef struct Lstn {
int afd;
+ int flags;
char* address;
char dir[NETPATHLEN];
/n/sourcesdump/2006/0128/plan9/sys/src/cmd/fossil/9lstn.c:45,51 -
/n/sourcesdump/2006/0129/plan9/sys/src/cmd/fossil/9lstn.c:46,52
Lstn *lstn;
int dfd, lfd;
char newdir[NETPATHLEN];
-
+
vtThreadSetName("listen");
lstn = a;
/n/sourcesdump/2006/0128/plan9/sys/src/cmd/fossil/9lstn.c:54,71 -
/n/sourcesdump/2006/0129/plan9/sys/src/cmd/fossil/9lstn.c:55,70
fprint(2, "listen: listen '%s': %r", lstn->dir);
break;
}
-
if((dfd = accept(lfd, newdir)) >= 0)
- conAlloc(dfd, newdir);
+ conAlloc(dfd, newdir, lstn->flags);
else
- fprint(2, "listen: accept '%s': %r", newdir);
- close(lfd);
+ fprint(2, "listen: accept %s: %r\n", newdir);
}
lstnFree(lstn);
}
static Lstn*
- lstnAlloc(char* address)
+ lstnAlloc(char* address, int flags)
{
int afd;
Lstn *lstn;
/n/sourcesdump/2006/0128/plan9/sys/src/cmd/fossil/9lstn.c:89,94 -
/n/sourcesdump/2006/0129/plan9/sys/src/cmd/fossil/9lstn.c:88,94
lstn = vtMemAllocZ(sizeof(Lstn));
lstn->afd = afd;
lstn->address = vtStrDup(address);
+ lstn->flags = flags;
memmove(lstn->dir, dir, NETPATHLEN);
if(lbox.tail != nil){
/n/sourcesdump/2006/0128/plan9/sys/src/cmd/fossil/9lstn.c:114,125 -
/n/sourcesdump/2006/0129/plan9/sys/src/cmd/fossil/9lstn.c:114,125
static int
cmdLstn(int argc, char* argv[])
{
- int dflag;
+ int dflag, flags;
Lstn *lstn;
- char *usage = "usage: listen [-d] [address]";
+ char *usage = "usage: listen [-dIN] [address]";
dflag = 0;
-
+ flags = 0;
ARGBEGIN{
default:
return cliError(usage);
/n/sourcesdump/2006/0128/plan9/sys/src/cmd/fossil/9lstn.c:126,131 -
/n/sourcesdump/2006/0129/plan9/sys/src/cmd/fossil/9lstn.c:126,137
case 'd':
dflag = 1;
break;
+ case 'I':
+ flags |= ConIPCheck;
+ break;
+ case 'N':
+ flags |= ConNoneAllow;
+ break;
}ARGEND
switch(argc){
/n/sourcesdump/2006/0128/plan9/sys/src/cmd/fossil/9lstn.c:139,145 -
/n/sourcesdump/2006/0129/plan9/sys/src/cmd/fossil/9lstn.c:145,151
break;
case 1:
if(!dflag){
- if(lstnAlloc(argv[0]) == nil)
+ if(lstnAlloc(argv[0], flags) == nil)
return 0;
break;
}
[rsc] --rw-rw-r-- M 1428987 rsc sys 22935 Jan 28 11:32 sys/src/cmd/fossil/9p.c
[diffs elided - too long]
[diff -c /n/sourcesdump/2006/0128/plan9/sys/src/cmd/fossil/9p.c /n/sourcesdump/2006/0129/plan9/sys/src/cmd/fossil/9p.c]
[rsc] --rw-rw-r-- M 1428987 rsc sys 15148 Jan 28 12:31 sys/src/cmd/fossil/9proc.c
/n/sourcesdump/2006/0128/plan9/sys/src/cmd/fossil/9proc.c:63,69 -
/n/sourcesdump/2006/0129/plan9/sys/src/cmd/fossil/9proc.c:63,69
}
con->state = ConDead;
con->aok = 0;
- con->noauth = con->noperm = con->wstatallow = 0;
+ con->flags = 0;
con->isconsole = 0;
vtLock(cbox.alock);
/n/sourcesdump/2006/0128/plan9/sys/src/cmd/fossil/9proc.c:502,510 -
/n/sourcesdump/2006/0129/plan9/sys/src/cmd/fossil/9proc.c:502,512
}
Con*
- conAlloc(int fd, char* name)
+ conAlloc(int fd, char* name, int flags)
{
Con *con;
+ char buf[128], *p;
+ int rfd, n;
vtLock(cbox.alock);
while(cbox.ahead == nil){
/n/sourcesdump/2006/0128/plan9/sys/src/cmd/fossil/9proc.c:558,565 -
/n/sourcesdump/2006/0129/plan9/sys/src/cmd/fossil/9proc.c:560,578
con->name = vtStrDup(name);
else
con->name = vtStrDup("unknown");
- con->aok = 0;
- con->noauth = con->noperm = con->wstatallow = 0;
+ con->remote[0] = 0;
+ snprint(buf, sizeof buf, "%s/remote", con->name);
+ if((rfd = open(buf, OREAD)) >= 0){
+ n = read(rfd, buf, sizeof buf-1);
+ close(rfd);
+ if(n > 0){
+ buf[n] = 0;
+ if((p = strchr(buf, '\n')) != nil)
+ *p = 0;
+ strecpy(con->remote, con->remote+sizeof con->remote, buf);
+ }
+ }
+ con->flags = flags;
con->isconsole = 0;
vtUnlock(cbox.alock);
/n/sourcesdump/2006/0128/plan9/sys/src/cmd/fossil/9proc.c:692,698 -
/n/sourcesdump/2006/0129/plan9/sys/src/cmd/fossil/9proc.c:705,711
cmdWho(int argc, char* argv[])
{
char *usage = "usage: who";
- int i;
+ int i, l1, l2, l;
Con *con;
Fid *fid, *last;
/n/sourcesdump/2006/0128/plan9/sys/src/cmd/fossil/9proc.c:705,712 -
/n/sourcesdump/2006/0129/plan9/sys/src/cmd/fossil/9proc.c:718,733
return cliError(usage);
vtRLock(cbox.clock);
+ l1 = 0;
+ l2 = 0;
for(con=cbox.chead; con; con=con->cnext){
- consPrint("\t%q:", con->name);
+ if((l = strlen(con->name)) > l1)
+ l1 = l;
+ if((l = strlen(con->remote)) > l2)
+ l2 = l;
+ }
+ for(con=cbox.chead; con; con=con->cnext){
+ consPrint("\t%-*s %-*s", l1, con->name, l2, con->remote);
vtLock(con->fidlock);
last = nil;
for(i=0; i<NFidHash; i++)
[rsc] --rw-rw-r-- M 1428987 rsc sys 3956 Jan 28 11:32 sys/src/cmd/fossil/9srv.c
/n/sourcesdump/2006/0128/plan9/sys/src/cmd/fossil/9srv.c:131,139 -
/n/sourcesdump/2006/0129/plan9/sys/src/cmd/fossil/9srv.c:131,141
Con *con;
Srv *srv;
char *usage = "usage: srv [-APWdp] [service]";
- int Aflag, Pflag, Wflag, dflag, fd[2], mode, pflag, r;
+ int conflags, dflag, fd[2], mode, pflag, r;
- Aflag = Pflag = Wflag = dflag = pflag = 0;
+ dflag = 0;
+ pflag = 0;
+ conflags = 0;
mode = 0666;
ARGBEGIN{
/n/sourcesdump/2006/0128/plan9/sys/src/cmd/fossil/9srv.c:140,153 -
/n/sourcesdump/2006/0129/plan9/sys/src/cmd/fossil/9srv.c:142,161
default:
return cliError(usage);
case 'A':
- Aflag = 1;
+ conflags |= ConNoAuthCheck;
break;
+ case 'I':
+ conflags |= ConIPCheck;
+ break;
+ case 'N':
+ conflags |= ConNoneAllow;
+ break;
case 'P':
- Pflag = 1;
+ conflags |= ConNoPermCheck;
mode = 0600;
break;
case 'W':
- Wflag = 1;
+ conflags |= ConWstatAllow;
mode = 0600;
break;
case 'd':
/n/sourcesdump/2006/0128/plan9/sys/src/cmd/fossil/9srv.c:159,165 -
/n/sourcesdump/2006/0129/plan9/sys/src/cmd/fossil/9srv.c:167,173
break;
}ARGEND
- if(pflag && Pflag){
+ if(pflag && (conflags&ConNoPermCheck)){
vtSetError("srv: cannot use -P with -p");
return 0;
}
/n/sourcesdump/2006/0128/plan9/sys/src/cmd/fossil/9srv.c:207,221 -
/n/sourcesdump/2006/0129/plan9/sys/src/cmd/fossil/9srv.c:215,225
if(pflag)
r = consOpen(fd[1], srv->srvfd, -1);
else{
- con = conAlloc(fd[1], srv->mntpnt);
+ con = conAlloc(fd[1], srv->mntpnt, conflags);
if(con == nil)
r = 0;
- else{
+ else
r = 1;
- con->noauth = Aflag;
- con->noperm = Pflag;
- con->wstatallow = Wflag;
- }
}
if(r == 0){
close(fd[1]);
[rsc] --rw-rw-r-- M 1428987 rsc sys 7985 Jan 28 11:32 sys/src/cmd/fossil/Ccmd.c
/n/sourcesdump/2006/0128/plan9/sys/src/cmd/fossil/Ccmd.c:446,452 -
/n/sourcesdump/2006/0129/plan9/sys/src/cmd/fossil/Ccmd.c:446,452
if(pipe(cbox.confd) < 0)
return 0;
- if((cbox.con = conAlloc(cbox.confd[1], "console")) == nil){
+ if((cbox.con = conAlloc(cbox.confd[1], "console", 0)) == nil){
close(cbox.confd[0]);
close(cbox.confd[1]);
cbox.confd[0] = cbox.confd[1] = -1;
[rsc] --rw-rw-r-- M 1428987 rsc sys 18276 Jan 28 11:37 sys/man/8/fossilcons
/n/sourcesdump/2006/0128/plan9/sys/man/8/fossilcons:33,39 -
/n/sourcesdump/2006/0129/plan9/sys/man/8/fossilcons:33,39
.PP
.B listen
[
- .B -d
+ .B -INd
]
[
.I address
/n/sourcesdump/2006/0128/plan9/sys/man/8/fossilcons:400,405 -
/n/sourcesdump/2006/0129/plan9/sys/man/8/fossilcons:400,427
.I listen
to remove the listener
at the given address.
+ By default, the user
+ .I none
+ is only allowed to attach on a connection after
+ at least one other user has successfully attached.
+ The
+ .B -N
+ flag allows connections from
+ .I none
+ at any time.
+ The
+ .B -I
+ flag causes
+ .I fossil
+ to check the IP address of incoming connections
+ against
+ .BR /mnt/ipok ,
+ rejecting attaches from disallowed addresses.
+ This mechanism is not intended for general use.
+ The server
+ .I sources.cs.bell-labs.com
+ uses it to comply with U.S. crytography
+ export regulations.
.PP
.I Msg
prints the maximum internal 9P message queue size
[rsc] --rw-rw-r-- M 1428987 rsc sys 3024 Jan 28 12:31 sys/src/cmd/fossil/9lstn.c
[rsc] --rw-rw-r-- M 1428987 rsc sys 15148 Jan 28 12:31 sys/src/cmd/fossil/9proc.c
|