9fans - fans of the OS Plan 9 from Bell Labs
 help / color / mirror / Atom feed
* multi-user terminal
@ 1995-08-23 11:26 Vadim
  0 siblings, 0 replies; 2+ messages in thread
From: Vadim @ 1995-08-23 11:26 UTC (permalink / raw)



The following changes effectively separate the CPU server
functionality and terminal functionality, so the console
of a CPU server can be used as a "normal" terminal.

Effectively, it allows to run a full-blown Plan9 system on
a stand-alone machine.

The kernel modifications provide interface to the new device
#c/termowner, which is the same as hostowner but affects only
devices associated with the terminal interface (keyboard, screen,
floppy).  Only hostowner can write to termowner, and writing
to hostowner changes termowner as well.

There's also a new revision of init which asks the user name
and performs authentication; for the hostowner both #c/key
and the auth. server are attempted (so if auth. server is dead
you still can log into the machine as an owner).

To log out of 81/2 you've got to kill it.  You know where to
complain.

Also, to use that functionality you may want to modify /rc/bin/cpurc
to set up VGA and mouse before doing other things (before, to
allow for diagnostics to stay on the screen).

--vadim

echo /sys/src/cmd/init.c...
cp /sys/src/cmd/init.c /sys/src/cmd/init.c.old
ed - /sys/src/cmd/init.c <<END-OF-FILE
156a
	else if(iscpu) 
		execl("/bin/rc", "rc", "-c", "home=/usr/$user; cd; . lib/profile", 0);
.
155c
	else if(manual || (iscpu && !strcmp(user, newuser)))
.
147a
	return 0;
.
144,146c
		if(p[0])
			print("%s\n", w.msg);
.
139,142c

		/* verify the return status */
		p = strchr(w.msg, ':');
		p = p? p+1 : w.msg;
		if(strcmp(p, "auth") == 0)
			return 0;	/* authentication failure */
		if(strcmp(p, "key") == 0)
			return 1;	/* cannot read key */
		if(strcmp(p, "exec") == 0) {
			print("init: exec failed\n");
			return 1;
.
137c
			return 1;
		} else if(i != pid)
.
135c
		if(i == -1) {
.
131a

.
128a

.
125a
		if(newuser) {
			/* attempt to authenticate */
			i = 0;
			if(!strcmp(newuser, user)) {
				if((i = pass()) > 0)
					goto authok;
			}
			if(!doauth()) {
				if(i < 0)
					exits("key");
				print("Login failed\n");
				exits("auth");
			}

			/* build new namespace */
		authok: newns(newuser, 0);

			/* set environment */
			setenv("#e/service", "terminal");
			setenv("#e/user", newuser);
		}

.
124c
	switch(pid = rfork(RFPROC|RFFDG|RFENVG|RFNOTEG)){
.
122a
	char *p;
.
120a
	char key[DESKEYLEN];
	char crypted[DESKEYLEN];
	char erb[ERRLEN];
	int fd;
	int a;

	if(passtokey(crypted, password) == 0) {
		a = 0;
		goto out;
	}
	fd = open("#c/key", OREAD);
	if(fd < 0) {
		errstr(erb);
		print("init: can't open #c/key: %s\n", erb);
		a = -1;
		goto out;
	}
	seek(fd, 0, 0);
	if(read(fd, key, DESKEYLEN) != DESKEYLEN){
		print("init: can't read key\n");
		close(fd);
		a = -1;
		goto out;
	}
	close(fd);
	a = !memcmp(crypted, key, sizeof key);
	
	/* clean up memory */
out:	memset(crypted, 0, sizeof crypted);
	memset(key, 0, sizeof key);
	return a;
}

/*
 * Authenticate regular users by talking to auth server
 * Returns 1 on success, 0 on failure
 */
int
doauth(void)
{
	char crypted[DESKEYLEN];
	char buf[NAMELEN];
	Chalstate ch;
	int a = 0;

	if(passtokey(crypted, password) == 0)
		goto out;
	if(getchal(&ch, newuser) < 0)
		goto out;
	strcpy(buf, ch.chal);
	netcrypt(crypted, buf);
	a = (chalreply(&ch, buf) >= 0);
	
out:	memset(crypted, 0, sizeof crypted);
	memset(buf, 0, sizeof buf);
	return a;	
}

/*
 * Returns 1 on system errors, 0 on successful execution
 * or auth. failures
 */
int
fexec(void (*execfn)(void), char *newuser)
{
.
118,119c
/*
 * Authenticate owner of the host
 * Returns 0 on bad passwd, -1 on failure and 1 on success
 */
int
pass(void)
.
115a
	close(consctl);
	return 1;
.
111,114c
		}			
		if(((*s > ' ' && *s < 0177) || (*s & 0200)) &&
	           s < &pbuf[pblen-2] ) {
			if(!noecho)
				write(1, s, 1);
			s++;				
		}
.
109c
		if(*s == 025 && s > pbuf) {	/* ctrl-U */
			write(1, "\n", 1);
			write(1, prompt, strlen(prompt));
.
102,107d
100c
		if(*s == '\b' && s > pbuf) {			
			s--;
			if(!noecho)
				write(1, "\b \b", 3);
.
87,98c
	consctl = open("#c/consctl", OWRITE);
	if(consctl < 0 || write(consctl, "rawon", 5) != 5)
		return 1;
	write(1, prompt, strlen(prompt));
	for(s = pbuf ; read(0, s, 1) == 1 ;) {
		if(*s == '\n' || *s == '\r') {
			*s = 0;
			write(consctl, "rawoff", 6);
			close(consctl);
			write(1, "\n", 1);
			return 0;
.
82,85c
	int consctl;
	char *s;
.
79,80c
int
prompt(char *prompt, char *pbuf, int pblen, int noecho)
.
71,72c
unsecure:	print("\ninit: starting /bin/rc\n");
		fexec(rcexec, 0);
.
68,69c

			/* Authenticate and execute */
			pres = fexec(rcexec, newuser);
			memset(password, 0, sizeof password);
			
			/* Restore terminal onwer */
			i = open("#c/termowner", OWRITE);
			if(i >= 0) {
				write(i, user, strlen(user));
				close(i);
			}

			if(!pres)
				continue;
			print("Cannot authenticate owner of the host!!!\n");
.
60,66c
			/* Read password & username */
			if(prompt("user: ", newuser, sizeof newuser, 0))
				goto unsecure;
			if(newuser[0] == 0)
				continue;
			if(prompt("password: ", password, sizeof password, 1))
				goto unsecure;

			/* Set terminal owner */
			i = open("#c/termowner", OWRITE);
			if(i >= 0) {
				write(i, newuser, strlen(newuser));
				close(i);
.
56c
		fexec(cpustart, 0);
	print("\n\n");
.
24,25c
	int i, pres;
.
19a
char	user[NAMELEN];
char	newuser[NAMELEN];
char	password[NAMELEN];
.
12c
int	pass(void);
int	doauth(void);
int	prompt(char*, char*, int, int);
.
9c
int	fexec(void(*)(void), char*);
.
END-OF-FILE
echo /sys/src/9/port/auth.c...
cp /sys/src/9/port/auth.c /sys/src/9/port/auth.c.old
ed - /sys/src/9/port/auth.c <<END-OF-FILE
623a

/*
 *  called by devcons() for terminal owner
 */
long
termownerwrite(char *a, int n)
{
	char buf[NAMELEN];

	if(!iseve())
		error(Eperm);
	if(n >= NAMELEN)
		error(Ebadarg);
	memset(buf, 0, NAMELEN);
	strncpy(buf, a, n);
	if(buf[0] == 0)
		error(Ebadarg);
	memmove(eveterm, buf, NAMELEN);
	return n;
}

.
603a
	memmove(eveterm, buf, NAMELEN);
.
588c
 *  writing hostowner also sets user and terminal owner
.
51a
 *  return true if current user is eveterm
 */
int
iseveterm(void)
{
	return strcmp(eveterm, u->p->user) == 0;
}

/*
.
38a
char	eveterm[NAMELEN] = "bootes";
.
END-OF-FILE
echo /sys/src/9/port/dev.c...
cp /sys/src/9/port/dev.c /sys/src/9/port/dev.c.old
ed - /sys/src/9/port/dev.c <<END-OF-FILE
60c
	devdir(c, tab->qid, tab->name, tab->length, 
	       (tab->perm & TDEV)? eveterm : eve, tab->perm & ~TDEV, dp);
.
56a

.
END-OF-FILE
echo /sys/src/9/port/devbit.c...
cp /sys/src/9/port/devbit.c /sys/src/9/port/devbit.c.old
ed - /sys/src/9/port/devbit.c <<END-OF-FILE
200,203c
	"bitblt",	{Qbitblt},	0,		TDEV | 0666,
	"mouse",	{Qmouse},	0,		TDEV | 0666,
	"mousectl",	{Qmousectl},	0,		TDEV | 0220,
	"screen",	{Qscreen},	0,		TDEV | 0444,
.
END-OF-FILE
echo /sys/src/9/port/devcons.c...
cp /sys/src/9/port/devcons.c /sys/src/9/port/devcons.c.old
ed - /sys/src/9/port/devcons.c <<END-OF-FILE
801a

	case Qtermowner:
		return termownerwrite(a, n);
.
615a
	case Qtermowner:
		return readstr(offset, buf, n, eveterm);

.
464c
		if(!iseveterm())
.
379a
	"termowner",	{Qtermowner},	NAMELEN,	0664,
.
372c
	"noise",	{Qnoise},	0,		TDEV | 0220,
.
370c
	"lights",	{Qlights},	0,		TDEV | 0220,
.
362,363c
	"cons",		{Qcons},	0,		TDEV | 0660,
	"consctl",	{Qconsctl},	0,		TDEV | 0220,
.
352a
	Qtermowner,
.
END-OF-FILE
echo /sys/src/9/port/devfloppy.c...
cp /sys/src/9/port/devfloppy.c /sys/src/9/port/devfloppy.c.old
ed - /sys/src/9/port/devfloppy.c <<END-OF-FILE
106,113c
	"fd0disk",		{Qdata + 0},	0,	TDEV | 0660,
	"fd0ctl",		{Qctl + 0},	0,	TDEV | 0660,
	"fd1disk",		{Qdata + 1},	0,	TDEV | 0660,
	"fd1ctl",		{Qctl + 1},	0,	TDEV | 0660,
	"fd2disk",		{Qdata + 2},	0,	TDEV | 0660,
	"fd2ctl",		{Qctl + 2},	0,	TDEV | 0660,
	"fd3disk",		{Qdata + 3},	0,	TDEV | 0660,
	"fd3ctl",		{Qctl + 3},	0,	TDEV | 0660,
.
END-OF-FILE
echo /sys/src/9/port/portdat.h...
cp /sys/src/9/port/portdat.h /sys/src/9/port/portdat.h.old
ed - /sys/src/9/port/portdat.h <<END-OF-FILE
775a
extern	char	eveterm[];
.
203a
/* A special flag in Dirtab's perm field to indicate that */
/* the the device is a part of the console terminal */
#define TDEV	01000

.
END-OF-FILE
echo /sys/src/9/port/portfns.h...
cp /sys/src/9/port/portfns.h /sys/src/9/port/portfns.h.old
ed - /sys/src/9/port/portfns.h <<END-OF-FILE
107a
int		iseveterm(void);
.
97a
long		termownerwrite(char*, int);
.
END-OF-FILE






^ permalink raw reply	[flat|nested] 2+ messages in thread

* multi-user terminal
@ 1995-08-24  2:39 jmk
  0 siblings, 0 replies; 2+ messages in thread
From: jmk @ 1995-08-24  2:39 UTC (permalink / raw)


i thought it was too quiet...






^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~1995-08-24  2:39 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
1995-08-23 11:26 multi-user terminal Vadim
1995-08-24  2:39 jmk

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).