Beispiel #1
0
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;
}
Beispiel #2
0
/*
 * 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");
}
Beispiel #3
0
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_);
}
Beispiel #4
0
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;
}
Beispiel #5
0
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;
}
Beispiel #6
0
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;
}
Beispiel #7
0
/*
 *  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;
}
Beispiel #8
0
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;
}
Beispiel #9
0
/*
 * 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;
}
Beispiel #10
0
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);
}
Beispiel #11
0
AuthInfo*
p9anyfactotum(int fd, int afd)
{
	return auth_proxy(fd, askuser, "proto=p9any role=client %s", keyspec);
}
Beispiel #12
0
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);
}
Beispiel #13
0
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);
}