Konsola mingetty logowanie bez hasła
0. Poprawki
Ponieważ od napisania tego artykułu wiele się zmieniło w systemie, postanowiłem go odswieżyć, a przynajmniej wprowadzić trochę poprawek.
- groupmod nie działa juz tak jak poprzednio, brak opcji -A
- mingetty też się zmieniło, --login zostało przerobione na --loginprog
- zródło progrmu zostało dostosowane do standardowego mingetty, które nie ma opcji --logopts
1. Wstęp
Mojego komputera nikt poza mną nie dotyka, więc wpadłem na pomysł, aby nie używać w ogóle haseł podczas logowania w konsoli.Skopiowałem rozwiązanie z knoppiksa (kawałek inittab) :
1:12345:respawn:/bin/bash -login >/dev/tty1 2>&1 </dev/tty1
Same wady. Może spełnia świetnie się to rozwiązanie w dystrybucji live, ale nie w systemie postawionym na dysku.
- Trzeba było zlinkować na twardo /root/.bashrc z /.bashrc - nie chciało mi sie robic 2 plików stąd link, a potrzeba pliku w / jest taka, że $HOME tak zalogowanego roota to właśnie /.
- Z tego samego powodu trzeba było linkować na twardo /root/.bash_history z /.bash_history
- Trzeba było dopisać do .bashrc "source /etc/profile ; export HOME=/root ; cd ~". Bez sensu.
- Nie było możliwości wyboru logującego się użytkownika. Był root i koniec.
- Prosty terminal bez virtuali (/dev/vcsX), efekt taki ze wykonanie jakiegokolwiek polecenia pod np. mc powodowalo, ukazanie sie napisu "Wciśnij klawisz...". Niby nic, ale wole wiedzeć, że coś w tle jest i że to nie zniknie.
- Brak prompta pod mc. Też niby nic, ale ladniej by wyglądał ;p
Pkt 5 i 6 nie chciało mi sie samemu poprawiac, więc zarzuciłem pomysł.
Potem przszła kolej na bezpośrednie wywołanie /bin/login:
1:12345:respawn:/bin/login -f root
Wad sporo odpadło, ale pozostały nadal nr. 4 i 5.
Potem był przypadek...
2. Budowa /etc/inittab
Domyślnie, w inittab w większości dystrybucji jest sobie 6 opisanych konsol. Dla mingetty podstawowy konfig wygląda tak:
1:12345:respawn:/sbin/mingetty tty1
Są tu 4 pola rozdzielone dwukropkami. Pierwsze pole oznacza numer konsoli (tu 1, czyli sprawa dotyczy tty1). Następnie są opisane runlevele (poziomy pracy), w których dana konsola ma być uaktywniana (tu 1,2,3,4 oraz 5). Potem jest opis wykonania polecenia z następnego pola (respawn - czyli jak przeszkadzajki w doomie na najwyższym poziomie, co umrze zostanie wskrzeszone). Na koniec polecenie i jego parametry (/sbin/mingetty tty1)
Jeśli porównać to z wcześniej pokazanymi wpisami, to juz mniej więcej wiadomo o co chodzi.
3a. Parametry spatchowanego mingetty
Dwa z punktu widzenia artykułu najważniejsze --login (--loginprog w nowszych wersjach) oraz --logopts. W manie są dobrze opisane, więc nie będę ich tłumaczył. Chcę tylko wskazać na możliwośc rozwinięcia powyższego wywołania mingetty z inittaba. Na razie bez zmiany funkcjonalności:
1:12345:respawn:/sbin/mingetty --login /bin/login tty1
1:12345:respawn:/sbin/mingetty --logopts "-- \\u" tty1
1:12345:respawn:/sbin/mingetty --login /bin/login --logopts "-- \\u" tty1
Tak wygląda rozwinięcie wg. tego co jest w manie napisane. Ciąg '\u' oznacza nazwę wpisanego w polu login użytkownika. Ta nazwa jest przekazywana z mingetty do login, aby login wiedział o czyje hasło się pytać.
3b. Parametry niespatchowanego mingetty
--loginprog. Więcej nam nie będzie potrzeba. Po poprawieniu zródełka, działa on równiez z tą wersją mingetty.
2. Parametr /bin/login
Jednym, jedynym się zajmę, mianowicie opcją -f. Ogólnie oznacza ona logowanie bez pytania o hasło. Sprostowanie w stosunku do mana:
- Nie jest prawdą jakoby nie można było się zalogować na roota przy użyciu tej opcji.
- Jest taką samą kalumnią, że nie działa na linuksie :)
4a. Logowanie bez hasła podejście pierwsze mingetty z poprawkami
Zmierzam do tego :
1:12345:respawn:/sbin/mingetty --loginprog /bin/login --logopts "-f -- \\u" tty1
Lub
1:12345:respawn:/sbin/mingetty --logopts "-f -- \\u" tty1
Mamy więc logowanie w konsoli na dowolnego użytkownika, bez podawania hasła.
Co oznacza podwójny minus ? Oznacza on koniec opcji/przełączników, a początek parametrów. Wyobraźmy sobie użytkownika o loginie -f. Niech mingetty poda parametry do /bin/login: "-f -f". Jak /bin/login ma to zinterpretować ? jako podwójną opcje ? Otóz te dwa znaczki powodują, że każdy następny parametr za nimi nie będzie uznawany za opcję/przełącznik.
przykład :
touch -f && ls -l -f && rm -f
To się wywali juz na touch. Touch wyrzuci coś w stylu 'touch: brak argumentu plikowego', a właśnie taki plik chcemy stworzyć.
touch -- -f && ls -l -- -f && rm -- -f
To stworzy plik -f, pokaże go oraz wykasuje (Faszczu, kłaniam się nisko ;p).
Właściwie, można już na tym skoczyć i sam w tym punkcie skończyłem. Nikt poza mną mojego kompa nie rusza. Nie mam małej siostry która nie pamięta swojego hasła, i która powinna móc sie zalogować na swoje konto, ale nie na konto roota.
Dalsza część jest właśnie dla takich ludzi :)
4b. Logowanie bez hasła podejście pierwsze mingetty bez poprawek
Umarł w butach. Krótko: potrzebny jest przełącznik --logopts, niewystępujący w standardowym mingetty.
5. nopasslogin.c
Potem wyjaśnię. Najpierw kod, wersja poprawiona:
#include <grp.h>
#include <unistd.h>
#include <stdio.h>
#ifndef GROUPNAME
#define GROUPNAME "nopasslogin"
// domyslna naza grupy jesli nie podana jako argument wywolania
#endif
#ifndef ACCEPT
#define ACCEPT 1
// wszyscy z grupy moga sie logowac bez hasla
#endif
int main(int argc,char** argv){
if(argc<2){ // w stosunku do poprzedniej wersji wymagany jest tylko jeden argument
printf(
"usage : nopasslogin [[~]group] user\n\n"
"normally everyone, who belongs to group can log in without password\n"
"if you put ~ before groupname, users belonging to that group will not\n"
"be able to log in without password, BUT everyone else will be!\n\n"
"the default behavior is to accept all users from group "GROUPNAME" if no group is specified.\n"
);
return -1;
}
char* grpname=GROUPNAME; // domyslna nazwa grupy
int revgrp=!ACCEPT; // domyslne zachowanie
int usr=1;
if(argc>2){
if(strcmp(*(argv+1),"--")){ // jesli pierwszym argumentem programu nie jest '--'
revgrp=**(argv+1)=='~'; // to znaczy ze mamy spatchowane mingetty i mozna przekazywac parametry
grpname=*(argv+1)+revgrp; // wiec pobieramy przekaana nawe grupy
}
usr++; // nazwa uzytkownika jest w nastepnym argumencie
}
struct group* gr=getgrnam(grpname);
if(gr){
int canlog=revgrp;
char** s=gr->gr_mem;
while(s && *s)
if(!strcmp(*s++,*(argv+usr))){
canlog^=1;
break;
}
if(canlog)execlp("/bin/login","login","-f","--",*(argv+usr),0);
}
execlp("/bin/login","login","--",*(argv+usr),0);
return 0;
}
Parametry wywołania:
nopasslogin [[~]group] user
Przede wszystkim ukłon w kierunku standardowego mingetty.
Program przyjmie 3 możliwe sposoby wywołania
- nopasslogin -- uzytkownik
Standardowe parametry ze standardowego mingetty. Domyślna grupa i zachowanie. - nopasslogin [
]nazwagrupy uzytkownik]nazwagrupy \u"
Niestandardowe mingetty, uzyta opcja --logopts "[ - nopasslogin uzytkownik
Niestandardowe mingetty, użyta opcja --logopts "\u". Domyślna grupa i zachowanie
Jeśli podana zostanie nawa grupy, to program ten działa na 2 sposoby:
- Gdy podać mu nazwę grupy bez tyldy bezpośrednio przed nią (nopasslogin grupa user) program sprawdza, czy podany jako parametr 2 user nalezy do grupy. Jeśli należy umozliwia mu logowanie bez hasła.
- Gdy podać mu nazwę grupy poprzedzoną tyldą (nopasslogin ~grupa user) program loguje bez pytania o hasło wszystkich SPOZA uzytkowników należących do tej grupy.
Samemu trzeba zdecydować, którą politykę wybrać.
5. Grupa
Tworzenie grupy wykonuje się za pomocą groupadd. Niech grupa nazywa się nopassgroup jeśli ktoś zdecyduje się używać logowania bez hasła dla wymienionych w grupie, oraz needpassgroup dla tych którzy w grupie chcą umieszczać tych, którzy muszą podać hasło przy logowaniu. Aby dodać użytkowników do grupy można użyc programu groupmod. A więc:
groupadd nopassgroup
groupmod nopassgroup -A user1,user2,user3
Tak jak pisałem w punkcie 0. groupmod starciło przełącznik -A, więc aby zmienić zawartość grupy najprościej jest wyedytować plik /etc/group
Lub
groupadd needpassgroup
groupmod needpassgroup -A user1,user2,user3
6. Kompilacja programu
Z roota :
gcc nopasslogin.c -o /usr/local/bin/nopasslogin && strip /usr/local/bin/nopasslogin
Można się pokusić o optymalizację, ustwaienie procesora i temu podobne, tylko nie ma to głębszego sensu, ponieważ ten program ma właściwie wykonać jedną rzecz a potem odpalić następny i umrzeć. Stripowanie mu całkowicie wystarczy.
7. Logowanie bez hasła podejście drugie
Dla mingetty po poprawkach:
1:12345:respawn:/sbin/mingetty --loginprog /usr/local/bin/nopasslogin --logopts "nopassgroup \\u" tty1
Lub
1:12345:respawn:/sbin/mingetty --login /usr/local/bin/nopasslogin --logopts "~needpassgroup \\u" tty1
Zaś dla mingetty bez poprawek:
1:12345:respawn:/sbin/mingetty --loginprog /usr/local/bin/nopasslogin" tty1
Tak mogą wyglądać pojedyncze wpisy dla tty1 w /etc/inittab.
dla wszystkich konsoli zmienia się odpowiednio pierwszą literkę oraz ostatni numer przy "tty"
8. Na koniec
Inspiracją był ten opis: http://fatcat.ftj.agh.edu.pl/~nelchael/files/minidm/miniDM.html, ale ponieważ było to robione dla agetty, Po drugie agetty można pominąc, aby mieć autologin, co pokazałem juz w pierwszym punkcie. Po trzecie domyślne niespatchowane mingetty nie ma autologina, ale jak widać pytanie o uzytkownika można bardzo fajnie spożytkować. Po czwarte. pisanie pod *niksy to na serio spora zabawa :)
Załącznik: File:nopass.zip