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.

  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

0 komentarzy