From: Vadim Antonov avg@postman.ncube.com
Subject: multi-user terminal
Date: Wed, 23 Aug 1995 07:26:05 -0400 [thread overview]
Message-ID: <19950823112605.COgHeGxRKgnhxn9WDPonoO7Ngjdm5jMO-PFeCnedXS0@z> (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
next reply other threads:[~1995-08-23 11:26 UTC|newest]
Thread overview: 2+ messages / expand[flat|nested] mbox.gz Atom feed top
1995-08-23 11:26 Vadim [this message]
1995-08-24 2:39 jmk
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=19950823112605.COgHeGxRKgnhxn9WDPonoO7Ngjdm5jMO-PFeCnedXS0@z \
--to=9fans@9fans.net \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
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).