int passive(void) { int fd; /* * Ignore doauth==0 on purpose. Is it useful here? */ procsetname("auth_proxy auth_getkey proto=p9any role=server"); ai = auth_proxy(0, auth_getkey, "proto=p9any role=server"); if(ai == nil) sysfatal("auth_proxy: %r"); if(auth_chuid(ai, nil) < 0) sysfatal("auth_chuid: %r"); putenv("service", "import"); fd = dup(0, -1); close(0); open("/dev/null", ORDWR); close(1); open("/dev/null", ORDWR); return fd; }
/* * called by listen as rexexec rexexec net dir ... */ void main(int argc, char **argv) { char buf[8192]; int n, nn; AuthInfo *ai; ARGBEGIN{ }ARGEND; ai = auth_proxy(0, auth_getkey, "proto=p9any role=server"); if(ai == nil) sysfatal("auth_proxy: %r"); if(strcmp(ai->cuid, "none") == 0) sysfatal("rexexec by none disallowed"); if(auth_chuid(ai, nil) < 0) sysfatal("auth_chuid: %r"); n = 0; do { nn = read(0, buf+n, 1); if(nn <= 0) sysfatal("can't read command"); n += nn; if(n == sizeof buf) buf[n-1] = '\0'; } while (buf[n-1] != '\0'); putenv("service", "rx"); execl("/bin/rc", "rc", "-lc", buf, nil); sysfatal("can't exec rc"); }
void Client::authAndBind() { const sg::Properties& prop = sg::Service::instance()->getProperties(); auth_server::client_methods::rpc::AuthRequest auth_req; auth_req.set_uid(uid_); auth_req.set_auth_type(prop.get<string>("auth.auth_type")); auth_req.set_auth_data(prop.get<string>("auth.auth_data")); auto_ptr<base::net::FilterCreatorStrategyBase> ssl_filter; #ifndef NO_SSL if (prop.getWithDef<int>("auth_server.use_ssl", 0)) { ssl_filter.reset( new base::net::SSLFilterCreatorStrategy( prop.getWithDef<string>("auth_server.pem_file", ""), prop.getWithDef<string>("auth_server.pem_password", ""), base::net::SSLFilter::AllowInvalidCertificates)); } #endif sg::ChannelFactoryT<> sslfactory(stubs_, ssl_filter); sg::ConnectionHandlerScoperT<> auth_handler = sslfactory.createHandler(base::net::SockAddr(prop.get<string>("auth_server.address"))); sg::Proxy auth_proxy(auth_handler); auth_server::client_methods::rpc::AuthResponse auth_resp; auth_proxy.call<auth_server::client_methods::rpc::Auth>(auth_req, &auth_resp); LOG(info, "auth success. ua address=" << auth_resp.ua_ipaddr() << ", uid=" << auth_resp.uid()); // bind string realm = base::HMAC_MD5String(auth_resp.session(), auth_resp.nonce()); user_access_server::client_methods::rpc::BindRequest bind_req; user_access_server::client_methods::rpc::BindResponse bind_resp; bind_req.set_uid(auth_resp.uid()); bind_req.set_realm(realm); sg::ChannelFactoryT<> factory(stubs_); sg::ConnectionHandlerScoperT<> ua_handler = factory.createHandler(base::net::SockAddr(auth_resp.ua_ipaddr())); ua_connection_ = ua_handler; sg::Proxy ua_proxy(ua_handler); ua_proxy.call<user_access_server::client_methods::rpc::Bind>(bind_req, &bind_resp); point_id_ = bind_resp.point_id(); LOG(info, "bind success. point id=" << point_id_); }
int connect(char *system, char *tree, int oldserver) { char buf[ERRMAX], dir[128], *na; int fd, n; char *authp; na = netmkaddr(system, 0, "exportfs"); procsetname("dial %s", na); if((fd = dial(na, 0, dir, 0)) < 0) sysfatal("can't dial %s: %r", system); if(doauth){ if(oldserver) authp = "p9sk2"; else authp = "p9any"; procsetname("auth_proxy auth_getkey proto=%q role=client %s", authp, keyspec); ai = auth_proxy(fd, auth_getkey, "proto=%q role=client %s", authp, keyspec); if(ai == nil) sysfatal("%r: %s", system); } if(!skiptree){ procsetname("writing tree name %s", tree); n = write(fd, tree, strlen(tree)); if(n < 0) sysfatal("can't write tree: %r"); strcpy(buf, "can't read tree"); procsetname("awaiting OK for %s", tree); n = read(fd, buf, sizeof buf - 1); if(n!=2 || buf[0]!='O' || buf[1]!='K'){ if (timedout) sysfatal("timed out connecting to %s", na); buf[sizeof buf - 1] = '\0'; sysfatal("bad remote tree: %s", buf); } } if(oldserver) return old9p(fd); return fd; }
int amount(int fd, char *mntpt, int flags, char *aname) { int rv, afd; AuthInfo *ai; afd = fauth(fd, aname); if(afd >= 0){ ai = auth_proxy(afd, amount_getkey, "proto=p9any role=client"); if(ai != nil) auth_freeAI(ai); } rv = mount(fd, afd, mntpt, flags, aname); if(afd >= 0) close(afd); return rv; }
int amount0(int fd, char *mntpt, int flags, char *aname, char *keyspec) { int rv, afd; AuthInfo *ai; afd = fauth(fd, aname); if(afd >= 0){ ai = auth_proxy(afd, amount_getkey, "proto=p9any role=client %s", keyspec); if(ai != nil) auth_freeAI(ai); else fprint(2, "%s: auth_proxy: %r\n", argv0); } rv = mount(fd, afd, mntpt, flags, aname); if(afd >= 0) close(afd); return rv; }
/* * plan9 authentication followed by rc4 encryption */ static int p9auth(int fd) { uchar key[16]; uchar digest[SHA1dlen]; char fromclientsecret[21]; char fromserversecret[21]; int i; AuthInfo *ai; procsetname("%s: auth_proxy proto=%q role=client %s", origargs, p9authproto, keyspec); ai = auth_proxy(fd, auth_getkey, "proto=%q role=client %s", p9authproto, keyspec); if(ai == nil) return -1; memmove(key+4, ai->secret, ai->nsecret); if(ealgs == nil) return fd; /* exchange random numbers */ srand(truerand()); for(i = 0; i < 4; i++) key[i] = rand(); procsetname("writing p9 key"); if(write(fd, key, 4) != 4) return -1; procsetname("reading p9 key"); if(readn(fd, key+12, 4) != 4) return -1; /* scramble into two secrets */ sha1(key, sizeof(key), digest, nil); mksecret(fromclientsecret, digest); mksecret(fromserversecret, digest+10); /* set up encryption */ procsetname("pushssl"); i = pushssl(fd, ealgs, fromclientsecret, fromserversecret, nil); if(i < 0) werrstr("can't establish ssl connection: %r"); return i; }
static int srvp9auth(int fd, char *user) { uchar key[16]; uchar digest[SHA1dlen]; char fromclientsecret[21]; char fromserversecret[21]; int i; AuthInfo *ai; ai = auth_proxy(0, nil, "proto=%q role=server %s", p9authproto, keyspec); if(ai == nil) return -1; if(auth_chuid(ai, nil) < 0) return -1; strecpy(user, user+MaxStr, ai->cuid); memmove(key+4, ai->secret, ai->nsecret); if(ealgs == nil) return fd; /* exchange random numbers */ srand(truerand()); for(i = 0; i < 4; i++) key[i+12] = rand(); if(readn(fd, key, 4) != 4) return -1; if(write(fd, key+12, 4) != 4) return -1; /* scramble into two secrets */ sha1(key, sizeof(key), digest, nil); mksecret(fromclientsecret, digest); mksecret(fromserversecret, digest+10); /* set up encryption */ i = pushssl(fd, ealgs, fromserversecret, fromclientsecret, nil); if(i < 0) werrstr("can't establish ssl connection: %r"); return i; }
/* * exportfs */ int connectexportfs(char *addr) { char buf[ERRMAX], dir[256], *na; int fd, n; char *tree; AuthInfo *ai; tree = "/"; na = netmkaddr(addr, 0, "exportfs"); if((fd = dial(na, 0, dir, 0)) < 0) return -1; ai = auth_proxy(fd, auth_getkey, "proto=p9any role=client"); if(ai == nil) return -1; n = write(fd, tree, strlen(tree)); if(n < 0){ close(fd); return -1; } strcpy(buf, "can't read tree"); n = read(fd, buf, sizeof buf - 1); if(n!=2 || buf[0]!='O' || buf[1]!='K'){ buf[sizeof buf - 1] = '\0'; werrstr("bad remote tree: %s\n", buf); close(fd); return -1; } // if(strstr(dir, "tcp")) // fd = filter(fd); if(oldsystem) return old9p(fd); return fd; }
void boot(int argc, char *argv[]) { int fd, afd; Method *mp; char *cmd, cmdbuf[64], *iargv[16]; char rootbuf[64]; int islocal, ishybrid; char *rp, *rsp, *rdparts; int iargc, n; char buf[32]; AuthInfo *ai; fmtinstall('r', errfmt); /* * we should inherit the standard fds all referring to /dev/cons, * but we're being paranoid. */ close(0); close(1); close(2); bind("#c", "/dev", MBEFORE); open("/dev/cons", OREAD); open("/dev/cons", OWRITE); open("/dev/cons", OWRITE); /* * init will reinitialize its namespace. * #ec gets us plan9.ini settings (*var variables). */ bind("#ec", "/env", MREPL); bind("#e", "/env", MBEFORE|MCREATE); bind("#s", "/srv/", MREPL|MCREATE); if(getenv("debugboot")) debugboot = 1; #ifdef DEBUG print("argc=%d\n", argc); for(fd = 0; fd < argc; fd++) print("%#p %s ", argv[fd], argv[fd]); print("\n"); #endif /* DEBUG */ ARGBEGIN{ case 'k': kflag = 1; break; case 'm': mflag = 1; break; case 'f': fflag = 1; break; }ARGEND readfile("#e/cputype", cputype, sizeof(cputype)); /* * set up usb keyboard & mouse, if any. * starts usbd, which mounts itself on /dev. * starts partfs on first disk, if any, to permit nvram on usb. */ usbinit(Dontpost); /* * pick a method and initialize it */ if(method[0].name == nil) fatal("no boot methods"); mp = rootserver(argc ? *argv : 0); (*mp->config)(mp); islocal = strcmp(mp->name, "local") == 0; ishybrid = strcmp(mp->name, "hybrid") == 0; /* * load keymap if it's there. */ kbmap(); /* don't trigger aoe until the network has been configured */ bind("#æ", "/dev", MAFTER); /* nvram could be here */ bind("#S", "/dev", MAFTER); /* nvram could be here */ /* * read disk partition tables here so that readnvram via factotum * can see them. ideally we would have this information in * environment variables before attaching #S, which would then * parse them and create partitions. */ rdparts = getenv("readparts"); if(rdparts) readparts(); free(rdparts); /* * authentication agent * sets hostowner, creating an auth discontinuity */ if(debugboot) fprint(2, "auth..."); authentication(cpuflag); /* leave existing subprocesses in their own namespace */ rfork(RFNAMEG); /* * restart partfs under the new hostowner id */ usbinit(Post); /* * connect to the root file system */ fd = (*mp->connect)(); if(fd < 0) fatal("can't connect to file server"); if(getenv("srvold9p")) fd = old9p(fd); if(!islocal && !ishybrid){ if(cfs) fd = (*cfs)(fd); } print("version..."); buf[0] = '\0'; n = fversion(fd, 0, buf, sizeof buf); if(n < 0) fatal("can't init 9P"); srvcreate("boot", fd); /* * create the name space, mount the root fs */ if(bind("/", "/", MREPL) < 0) fatal("bind /"); rp = getenv("rootspec"); if(rp == nil) rp = ""; afd = fauth(fd, rp); if(afd >= 0){ ai = auth_proxy(afd, auth_getkey, "proto=p9any role=client"); if(ai == nil) print("authentication failed (%r), trying mount anyways\n"); } if(mount(fd, afd, "/root", MREPL|MCREATE, rp) < 0) fatal("mount /"); rsp = rp; rp = getenv("rootdir"); if(rp == nil) rp = rootdir; if(bind(rp, "/", MAFTER|MCREATE) < 0){ if(strncmp(rp, "/root", 5) == 0){ fprint(2, "boot: couldn't bind $rootdir=%s to root: %r\n", rp); fatal("second bind /"); } snprint(rootbuf, sizeof rootbuf, "/root/%s", rp); rp = rootbuf; if(bind(rp, "/", MAFTER|MCREATE) < 0){ fprint(2, "boot: couldn't bind $rootdir=%s to root: %r\n", rp); if(strcmp(rootbuf, "/root//plan9") == 0){ fprint(2, "**** warning: remove rootdir=/plan9 entry from plan9.ini\n"); rp = "/root"; if(bind(rp, "/", MAFTER|MCREATE) < 0) fatal("second bind /"); }else fatal("second bind /"); } } close(fd); setenv("rootdir", rp); settime(islocal, afd, rsp); if(afd > 0) close(afd); swapproc(); cmd = getenv("init"); if(cmd == nil){ sprint(cmdbuf, "/%s/init -%s%s", cputype, cpuflag ? "c" : "t", mflag ? "m" : ""); cmd = cmdbuf; } iargc = tokenize(cmd, iargv, nelem(iargv)-1); cmd = iargv[0]; /* make iargv[0] basename(iargv[0]) */ if(iargv[0] = strrchr(iargv[0], '/')) iargv[0]++; else iargv[0] = cmd; iargv[iargc] = nil; chmod("/srv/" PARTSRV, 0600); exec(cmd, iargv); fatal(cmd); }
AuthInfo* p9anyfactotum(int fd, int afd) { return auth_proxy(fd, askuser, "proto=p9any role=client %s", keyspec); }
void boot(int argc, char *argv[]) { int fd, afd, srvt; Method *mp; char *cmd, cmdbuf[64], *iargv[16]; char rootbuf[64]; int islocal, ishybrid; char *rp, *rsp; int iargc, n; char buf[32]; AuthInfo *ai; fmtinstall('r', errfmt); bind("#c", "/dev", MBEFORE); open("/dev/cons", OREAD); open("/dev/cons", OWRITE); open("/dev/cons", OWRITE); /* * init will reinitialize its namespace. * #ec gets us plan9.ini settings (*var variables). */ bind("#ec", "/env", MREPL); bind("#e", "/env", MBEFORE|MCREATE); bind("#s", "/srv", MREPL|MCREATE); bind("#p", "/proc", MREPL|MCREATE); print("\nHello, I am Harvey :-)\n\n"); #ifdef DEBUG print("argc=%d\n", argc); for(fd = 0; fd < argc; fd++) print("%#p %s ", argv[fd], argv[fd]); print("\n"); #endif //DEBUG ARGBEGIN{ case 'k': kflag = 1; break; case 'm': mflag = 1; break; case 'f': fflag = 1; break; }ARGEND readfile("#e/cputype", cputype, sizeof(cputype)); readfile("#e/service", service, sizeof(service)); /* Do the initial ACPI interrupt setup work. * If we don't do this we may not get needed * interfaces. */ if (getenv("acpiirq")) acpiirq(); /* * set up usb keyboard, mouse and disk, if any. */ usbinit(); print("usbinit done\n"); /* * pick a method and initialize it */ if(method[0].name == nil) fatal("no boot methods"); mp = rootserver(argc ? *argv : 0); (*mp->config)(mp); islocal = strcmp(mp->name, "local") == 0; ishybrid = strcmp(mp->name, "hybrid") == 0; /* * load keymap if it is there. */ kbmap(); /* * authentication agent */ authentication(cpuflag); print("connect..."); /* * connect to the root file system */ fd = (*mp->connect)(); if(fd < 0) fatal("can't connect to file server"); if(!islocal && !ishybrid){ if(cfs) fd = (*cfs)(fd); } print("version..."); buf[0] = '\0'; n = fversion(fd, 0, buf, sizeof buf); if(n < 0) fatal("can't init 9P"); srvcreate("boot", fd); /* * create the name space, mount the root fs */ if(bind("/", "/", MREPL) < 0) fatal("bind /"); rp = getenv("rootspec"); if(rp == nil) rp = ""; afd = fauth(fd, rp); if(afd >= 0){ ai = auth_proxy(afd, auth_getkey, "proto=p9any role=client"); if(ai == nil) print("authentication failed (%r), trying mount anyways\n"); } if(mount(fd, afd, "/root", MREPL|MCREATE, rp, 'M') < 0) fatal("mount /"); rsp = rp; rp = getenv("rootdir"); if(rp == nil) rp = rootdir; if(bind(rp, "/", MAFTER|MCREATE) < 0){ if(strncmp(rp, "/root", 5) == 0){ fprint(2, "boot: couldn't bind $rootdir=%s to root: %r\n", rp); fatal("second bind /"); } snprint(rootbuf, sizeof rootbuf, "/root/%s", rp); rp = rootbuf; if(bind(rp, "/", MAFTER|MCREATE) < 0){ fprint(2, "boot: couldn't bind $rootdir=%s to root: %r\n", rp); if(strcmp(rootbuf, "/root//plan9") == 0){ fprint(2, "**** warning: remove rootdir=/plan9 entry from plan9.ini\n"); rp = "/root"; if(bind(rp, "/", MAFTER|MCREATE) < 0) fatal("second bind /"); }else fatal("second bind /"); } } close(fd); setenv("rootdir", rp); settime(islocal, afd, rsp); if(afd > 0) close(afd); cmd = getenv("init"); srvt = strcmp(service, "terminal"); if(cmd == nil){ if(!srvt) { sprint(cmdbuf, "/%s/bin/init -%s%s", cputype, "t", mflag ? "m" : ""); cmd = cmdbuf; } else { sprint(cmdbuf, "/%s/bin/init -%s%s", cputype, "c", mflag ? "m" : ""); cmd = cmdbuf; } } iargc = tokenize(cmd, iargv, nelem(iargv)-1); cmd = iargv[0]; /* make iargv[0] basename(iargv[0]) */ if((iargv[0] = strrchr(iargv[0], '/')) != nil) iargv[0]++; else iargv[0] = cmd; iargv[iargc] = nil; exec(cmd, iargv); fatal(cmd); }
void rexec(User *user, Job *j) { char buf[8*1024]; int n, fd; AuthInfo *ai; switch(rfork(RFPROC|RFNOWAIT|RFNAMEG|RFENVG|RFFDG)){ case 0: break; case -1: clog("can't fork a job for %s: %r\n", user->name); default: return; } if(!mkcmd(j->cmd, buf, sizeof buf)){ clog("internal error: cmd buffer overflow"); _exits(0); } /* * local call, auth, cmd with no i/o */ if(strcmp(j->host, "local") == 0){ if(becomeuser(user->name) < 0){ clog("%s: can't change uid for %s on %s: %r", user->name, j->cmd, j->host); _exits(0); } putenv("service", "rx"); clog("%s: ran '%s' on %s", user->name, j->cmd, j->host); execl("/bin/rc", "rc", "-lc", buf, nil); clog("%s: exec failed for %s on %s: %r", user->name, j->cmd, j->host); _exits(0); } /* * remote call, auth, cmd with no i/o * give it 2 min to complete */ alarm(2*Minute*1000); fd = call(j->host); if(fd < 0){ if(fd == -2) clog("%s: dangerous host %s", user->name, j->host); clog("%s: can't call %s: %r", user->name, j->host); _exits(0); } clog("%s: called %s on %s", user->name, j->cmd, j->host); if(becomeuser(user->name) < 0){ clog("%s: can't change uid for %s on %s: %r", user->name, j->cmd, j->host); _exits(0); } ai = auth_proxy(fd, nil, "proto=p9any role=client"); if(ai == nil){ clog("%s: can't authenticate for %s on %s: %r", user->name, j->cmd, j->host); _exits(0); } clog("%s: authenticated %s on %s", user->name, j->cmd, j->host); write(fd, buf, strlen(buf)+1); write(fd, buf, 0); while((n = read(fd, buf, sizeof(buf)-1)) > 0){ buf[n] = 0; clog("%s: %s\n", j->cmd, buf); } _exits(0); }