add a proper login manager

This commit is contained in:
Lisa Milne 2023-12-17 17:20:10 +10:00
parent 7ceb503fee
commit e3a86643d2
3 changed files with 175 additions and 26 deletions

View file

@ -2167,26 +2167,9 @@ if (window.location.protocol == 'file:')
clite.commands.load('exp',function(args,env,io) {
var stdio = io.include('stdio');
var stdlib = io.include('stdlib');
var time = io.include('time');
var t = time.time();
stdio.printf('time is: %d\n',t);
var tm = time.gmtime(t);
stdio.printf('gmtime gives: %d %d %d %d %d %d %d %d %d\n',tm.tm_sec,tm.tm_min,tm.tm_hour,tm.tm_mday,tm.tm_mon,tm.tm_year,tm.tm_wday,tm.tm_yday,tm.tm_isdst);
stdio.printf('%s\n',time.ctime(t));
stdio.printf('Hello world\n');
stdio.printf('%d %d\n',stdlib.getuid(),stdlib.getgid());
stdio.printf('%#15x:%15o:%15.5f:%0$15.5f:%%:\n',10,12,8.123456789);
function rcb(data) {
stdio.write(io.stdout,data);
var u = stdlib.getpwnam(data);
if (u)
stdio.printf('%s %d %d\n',u.pw_name,u.pw_uid,u.pw_gid);
io.exit(0);
}
stdio.printf('%d %d %d\n',stdlib.getuid(),stdlib.getgid(),io.pid);
stdio.read(io.stdin,rcb);
return null;
return 0;
});
// insert commands above this line

View file

@ -540,12 +540,12 @@ license.txt:/etc/license:0:0:-rw-r--r--`;
clite.user.genGuest();
// create the login shell
// should really have init/getty exec the shell with the env data etc
var env = clite.user.getEnv(1);
var env = clite.user.getEnv(0);
var io = {
pid:0,
stdin:clite.io.open(1,'/dev/tty0',clite.io.flags.O_RDONLY),
stdout:clite.io.open(1,'/dev/tty0',clite.io.flags.O_WRONLY),
stderr:clite.io.open(1,'/dev/tty0',clite.io.flags.O_WRONLY),
stdin:clite.io.open(0,'/dev/tty0',clite.io.flags.O_RDONLY),
stdout:clite.io.open(0,'/dev/tty0',clite.io.flags.O_WRONLY),
stderr:clite.io.open(0,'/dev/tty0',clite.io.flags.O_WRONLY),
exit:null, // filled in by fork()
include:null, // filled in by fork()
};
@ -554,8 +554,8 @@ license.txt:/etc/license:0:0:-rw-r--r--`;
}
function init5(env,io) {
clite.tty.clear(0);
clite.proc.setLogin(io.pid,1);
clite.lib.exec('/bin/sh',['sh'],env,io);
//clite.proc.setLogin(io.pid,1);
clite.lib.exec('/bin/login',['login','guest'],env,io);
}
init1();
@ -836,6 +836,21 @@ clite.proc = {
proc.gid = proc.rgid;
return true;
}
clite.proc.dump = function() {
var r = '';
data.procs.forEach(function(p) {
r += '{\n';
r += ' ruid:'+p.ruid+',\n';
r += ' rgid:'+p.rgid+',\n';
r += ' uid:'+p.uid+',\n';
r += ' gid:'+p.gid+',\n';
r += ' gpid:'+p.gpid+',\n';
r += ' pid:'+p.pid+',\n';
r += ' ctty:'+p.ctty+'\n';
r += '}\n';
});
return r;
}
clite.proc.init = null;
return true;
},

View file

@ -87,7 +87,7 @@ Options:
}
if (stdlib.getuid() != 0) {
stdio.write(io.stdout,'password: ');
stdio.write(io.stdout,'Password: ');
term.ttyctrl('echo',false);
if (!stdio.read(io.stdin,doLogin)) {
term.ttyctrl('echo',true);
@ -411,4 +411,155 @@ Options:
return main(args);
},true);
clite.commands.load('login',function(args,env,io) {
var stdio = io.include('stdio');
var stdlib = io.include('stdlib');
var auth = io.include('auth');
var term = io.include('term');
var pw = null;
function help() {
stdio.printf(`
login - user login manager
Usage: login [OPTION]
Options:
-? Print this help information
`);
}
function doLogin(nenv,nio) {
let stdio = nio.include('stdio');
let stdlib = nio.include('stdlib');
if (!stdlib.setgid(pw.pw_gid)) {
stdio.fprintf(nio.stderr,'internal error (1) %d %d\n',stdlib.geteuid(),stdlib.getegid());
nio.exit(1);
return;
}
if (!stdlib.setuid(pw.pw_uid)) {
stdio.write(nio.stderr,'internal error (2)\n');
nio.exit(1);
return;
}
var r = stdlib.exec(pw.pw_shell,[pw.pw_shell],env,nio);
if (r == 0)
return;
stdio.write(nio.stderr,'internal error (3)\n');
nio.exit(1);
}
function preLogin() {
env.USER = pw.pw_name;
env.PWD = pw.pw_dir;
env.HOME = pw.pw_dir;
env.SHELL = pw.pw_shell;
var pid = stdlib.fork(env,io,doLogin);
if (pid < 1) {
getUser();
return;
}
stdlib.waitpid(pid,getUser);
}
function setPass(pass) {
if (pass == String.fromCharCode(4) || pass == 4) {
getUser();
return;
}
if (auth.checkpassuid(pw.pw_uid,pass)) {
preLogin();
return;
}
getUser();
}
function getPass() {
stdio.write(io.stdout,'Password: ');
term.ttyctrl('echo',false);
var r = stdio.read(io.stdin,function(p) {
term.ttyctrl('echo',true);
setPass(p);
});
if (!r)
getUser();
}
function setUser(name) {
if (name == String.fromCharCode(4) || name == 4) {
getUser();
return;
}
pw = stdlib.getpwnam(name);
if (!pw) {
getUser();
return;
}
if (name == 'guest') {
preLogin();
return;
}
getPass();
}
function getUser() {
term.clear();
stdio.write(io.stdout,'Username: ');
if (!stdio.read(io.stdin,setUser))
stdio.write(io.stderr,'internal error\n');
}
function main(args) {
let user = null;
for (var i=1; i<args.length; i++) {
if (args[i][0] == '-') {
for (var j=1; j<args[i].length; j++) {
switch (args[i][j]) {
case '?':
help();
return 0;
break;
default:
stdio.fprintf(io.stderr,'unknown argument: -%c\n',args[i][j]);
}
}
}else{
user = args[i];
}
}
if (!stdio.isatty(io.stdin) || !stdio.isatty(io.stdout)) {
stdio.fprintf(io.stderr,'invalid tty\n');
return 1;
}
if (stdlib.geteuid() != 0) {
stdio.fprintf(io.stderr,'requires root\n');
return 1;
}
if (user != null) {
setUser(user);
return null;
}
getUser();
return null;
}
return main(args);
});
}