From mboxrd@z Thu Jan 1 00:00:00 1970 Date: Wed, 23 Aug 1995 07:26:05 -0400 From: Vadim Antonov avg@postman.ncube.com Subject: multi-user terminal Topicbox-Message-UUID: 1b392f42-eac8-11e9-9e20-41e7f4b1d025 Message-ID: <19950823112605.COgHeGxRKgnhxn9WDPonoO7Ngjdm5jMO-PFeCnedXS0@z> 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 < 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 <= 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 <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 <