* [9fans] su for plan9
@ 1998-08-27 8:00 arisawa
0 siblings, 0 replies; only message in thread
From: arisawa @ 1998-08-27 8:00 UTC (permalink / raw)
Hello 9fans!
Here is a "su" for Plan9.
I don't know much of authentication scheme of Plan9,
so I used naive method using challenge/response.
Let me know if you have other methods.
Kenji Arisawa
E-mail: arisawa@aichi-u.ac.jp
/*
su: substitute user
usage: su [user]
I felt inconvenient to kill processes of none, so I wrote.
Su is the plan9 version of UNIX su.
Ref: Much of the codes comes from elsewhere.
1998/08/27
Kenji Arisawa (Kenar)
E-mail: arisawa@ar.aichi-u.ac.jp
*/
#include <u.h>
#include <libc.h>
#include <auth.h>
void error(char *s)
{ fprint(2,"%s\n", s);
exits(s);
}
int
writefile(char *name, char *buf, int len)
{
int f, n;
f = open(name, OWRITE);
if(f < 0)
return -1;
n = write(f, buf, len);
close(f);
return (n != len) ? -1 : 0;
}
void
prompt(char *p, char *b, int n)
{
char *e;
int i;
print("%s: ", p);
for(e = b+n; b < e;){
i = read(0, b, e-b);
if(i <= 0)
exits("hungup");
b += i;
if(*(b-1) == '\n'){
*(b-1) = 0;
return;
}
}
}
int
readln(char *prompt, char *line, int len)
{
char *p;
int fd, ctl, n, nr;
fd = open("/dev/cons", ORDWR);
if(fd < 0)
error("couldn't open cons");
ctl = open("/dev/consctl", OWRITE);
if(ctl < 0)
error("couldn't set raw mode");
write(ctl, "rawon", 5);
fprint(fd, "%s", prompt);
nr = 0;
p = line;
for(;;){
n = read(fd, p, 1);
if(n < 0){
close(fd);
close(ctl);
return -1;
}
if(n == 0 || *p == '\n' || *p == '\r'){
*p = '\0';
write(fd, "\n", 1);
close(fd);
close(ctl);
return nr;
}
if(*p == '\b'){
if(nr > 0){
nr--;
p--;
}
}else if(*p == 21){ /* cntrl-u */
fprint(fd, "\n%s", prompt);
nr = 0;
p = line;
}else{
nr++;
p++;
}
if(nr == len){
fprint(fd, "line too long; try again\n%s", prompt);
nr = 0;
p = line;
}
}
return -1;
}
/*
* authenticate by challenge
*/
int
challuser(char *user)
{
char nchall[NETCHLEN+32];
char response[NAMELEN];
Chalstate ch;
int m=5; /* max trial */
while(m-- > 0){
if(getchal(&ch, user) < 0) return -1;
sprint(nchall, "challenge: %s\r\nresponse", ch.chal);
prompt(nchall, response, sizeof response);
if(chalreply(&ch, response) == 0) break;
}
if(m < 0) return -1;
return 0;
}
/*
* authenticate by password
* there may be more elegant method
*/
int passuser(char *user)
{
char buf[32], passwd[32], key[DESKEYLEN];
Chalstate ch;
int n;
int m=5; /* max trial */
while(m-- > 0){
n = readln("Password: ", passwd, sizeof(passwd));
passwd[n] = 0;
if(n == 0) return -1;
passtokey(key, passwd);
if(getchal(&ch, user) < 0) return -1;
strcpy(buf,ch.chal);
n = strtol(buf, 0, 10);
sprint(buf, "%d", n);
netcrypt(key, buf);
if(chalreply(&ch, buf) == 0) break;
}
if(m < 0) return -1;
return 0;
}
int authuser(char *user){
char *s;
/* check the host where su is running */
s = getenv("service");
if(s && strcmp(s, "terminal") == 0){
if(passuser(user) < 0) return -1;
}
else{
/* we apply challenge and response */
if(challuser(user) < 0) return -1;
}
return 0;
}
void
main(int argc, char **argv)
{ int f;
char *user=0;
argv++;
if(*argv) user=*argv;
if(user){
if(authuser(user) < 0) {
print("authentication failure\r\n");
exits("authentication");
}
newns(user,0);
}
else{
/* set user to none */
if(writefile("/dev/user", "none", 4) < 0) exits("/dev/user");
newns("none",0);
}
putenv("prompt", "su% ");
execl("/bin/rc", "rc", "-i", 0);
}
^ permalink raw reply [flat|nested] only message in thread
only message in thread, other threads:[~1998-08-27 8:00 UTC | newest]
Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
1998-08-27 8:00 [9fans] su for plan9 arisawa
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).