Z pogranicza » Linux

Konsola mingetty logowanie bez hasła

  • 2008-07-14 13:29
  • 0 komentarzy
  • 2482 odsłony
  • Oceń ten tekst jako pierwszy

0. Poprawki


Ponieważ od napisania tego artykułu wiele się zmieniło w systemie, postanowiłem go odswieżyć, a przynajmniej wprowadzić trochę poprawek.

1. groupmod nie działa juz tak jak poprzednio, brak opcji -A
2. mingetty też się zmieniło, --login zostało przerobione na --loginprog
3. 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.
1. 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 /.
2. Z tego samego powodu trzeba było linkować na twardo /root/.bash_history z /.bash_history
3. Trzeba było dopisać do .bashrc "source /etc/profile ; export HOME=/root ; cd ~". Bez sensu.
4. Nie było możliwości wyboru logującego się użytkownika. Był root i koniec.
5. 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.
6. 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:
1. Nie jest prawdą jakoby nie można było się zalogować na roota przy użyciu tej opcji.
2. 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
1. nopasslogin -- uzytkownik
  Standardowe parametry ze standardowego mingetty. Domyślna grupa i zachowanie.
2. nopasslogin [~]nazwagrupy uzytkownik
  Niestandardowe mingetty, uzyta opcja --logopts "[~]nazwagrupy \\u"
3. 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:

1. 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.
2. 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