Do spisu tresci tematu 9

9.3.2.6. Sprawdzanie tozsamosci




Spis tresci


Wprowadzenie

System SUN RPC oferuje trzy rodzaje sprawdzania tozsamosci:
   - bez kontroli tozsamosci
   - kontrola tozsamosci na zasadach Unixa
   - kontrola tozsamosci na zasadach DES
Pierwszy rodzaj jest stosowany domyslnie. Kontrola na zasadach Unixa powoduje, ze kazde proba wykonania operacji RPC powoduje przeslanie do serwera nastepujacych informacji:czasu, nazwy stacji lokalnej, obowiazujacego identyfikatora uzytkownika i grupy(grup dla systemu 4.3BSD). Ze sprawdzania tozsamosci na zasadach DES mozna korzystac w wersji SUN RPC zwanej RPCSRC 4.0

Struktury danych

Struktury uzywane przez funkcje tworzace i sprawdzajace listy uwierzytelniajace klienta:
- AUTH - glowna struktura wykorzystywana do autentyfikacji, zdefiniowana w pliku include/rpc/auth.h:
   typedef struct{ 
      struct opaque_auth ah_cred; /* dane autentyfikacji 
      struct opaque_auth ah_verf; /* dane do weryfikacji 
      union des_block ah_key; 
      struct auth_ops{ 
           void (*ah_nextverf)(); 
	   int (*ah_marshal)(); 
	   int (*ah_validate)();  /*zapisuje dane autentyfikacji na zmienna 
	   int (*ah_verf)() 
	   int (*ah_refresh)();   /*odswierza dane sluzace do autenyfikacji
	   void (*ah_destroy)();  /*funkcja niszczaca strukture 
	   } *ah_ops; 
      caddr_t ah_private;         /*dane prywatne klienta 
      } AUTH 
- pakiet kontrolny wypelniany przez klienta:
struct opaque_auth{ 
    enum_t oa_flavor; /* jaki jest to rordzaj kontroli AUTH_NONE/AUTH_UNIX/...
    caddr_t oa_base;  /* adres pozostalych danych kontrolnych
    u_int oa_lenght;  /* rozmiar oa_base,nie moze byc wiekszy niz MAX_AUTH_BYTES
    } 
W Linuxie wyrozniamy cztery rodzaje kontroli (autentyfikacji), okreslone sa one przez nastepujace stale:
#define AUTH_NONE   0   /* brak kontroli
#define AUTH_NULL   0
#define AUTH_UNIX   1   /* w stylu Unixa 
#define AUTH_SHORT  2   /* (dla tej stalej nie znalazlem zadnej funkcji, ktora 
                        /* kodowalaby ten rodzaj informacji kontrolnej) 
#define AUTH_DES    3   /* w stylu DES (Data Encryption Standard)

Funkcje, implementacja i dodatkowe struktury


authnone_create()

Do pierwszego rodzaju autentyfikacji uzywana jest funkcja:
   AUTH *authnone_create()

zwracajaca wskaznik do struktury AUTH. Funkcja ta uzywa dodatkowej struktury
static struct authnone_private { 
    AUTH no_client; 
    char marshalled_client[MAX_MARSHEL_SIZE]; /* maksymalnie 20 bajtow
    u_int mcnt;                               /* wielkosc marshalled_client 
    } *authnone_private; 
Jezeli struktura ta nie byla jeszcze zainicjalizowana to funkcja przydziela jej pamiec i wypelnia ja zerami. Na zmienne no_client -> ah_cred i ah_verf przypisuje watrosc _null_auth. Nastepnie tworzy potok XDR "w pamieci" na buforze marshalled_client i koduje do niego, przy pomocy filtrow XDR, te dwie zmienne, w kolejnym kroku pobiera przy pomocy funkcji XDR_GETPOS(xdrs) rozmiar zapisanych danych zapisujac go na zmienna mcnt, niszczy potok XDR i jako rezultat zwraca wskaznik do zmiennej no_client.

authunix_create()

Kolejna funkcja jest funkcja kreujaca pakiet identyfikacyjny w stylu UNIX'a.
AUTH *authunix_create(machname, uid, gid, len, aup_gids)
    char *machname;  /*nazwa serwera klienta 
    int uid;         /*identyfikator uzytkownika 
    int gid;         /*identyfikator grupy uzytkownika 
    int len; 
    int *aup_gids; 
Funkcja ta uzywa dodatkowych struktur
AUTH *auth; 
struct audata { 
    struct opaque_auth au_origcred;  /* oryginalne listy uwierzytelniajace
    struct opaque_auth au_shcred; 
    u_long au_shfaults; 
    char au_marshed[MAX_AUTH_BYTES]; 
    u_int au_mpos;                   /* wielkosc potoku XDR po dokonaniu 
                                     /* wsystkich operacji kodujacych 
    } *au; 
oraz 
    struct authunix_parms { 
       u_long aup_time;        /* czas 
       char *aup_machname;     /* nazwa lokalnej stacji
       uid_t aup_uid;          /* efektywny identyfikator klienta
       gid_t aup_gid;          /* efektywny identyfikator grupy klienta
       u_int aup_len; 
       gid_t *aup_gids;        /* pozostale grupy do ktorych nalezy klient
    } aup; 
Funkcja na poczatku przydziela miejsce w pamieci na struktury audata i AUTH. Nastepnie na zmienna auth->ah_private przypisuje wskaznik do au oraz zmiennym auth->ah_verf i au->au_shcred wartosc _null_auth. Przypisuje zmiennej aup wartosci przekazane do funkcji oraz czas. W kolejnym kroku tworzy potok XDR "w pamieci" na lokalnym buforze i przy pomocy filtru XDR koduje do niego informacje zawarta w aup. Pobiera wielkosc zapisanych danych do potoku XDR i umieszcza ja na zmiennej au->au_origcred.oa_length, oa_flafor przypisuje wartosc AUTH_UNIX, zmiennej au->au_origcred.oa_base przydziela pamiec i zapisuje do niej zakodowany bufor z potoku XDR. Cala ta strukture (au->au_origcred) przypisuje zmiennej auth->ah_cred i wywoluje funkcje marshal_new_auth(auth), ktora z kolei przy pomocy nowego potoku XDR na zmienna au->au_marshed koduje struktury auth->ah_cred i ah_verf oraz ustawia wartosc au->au_mpos na wielkosc tak zapisanego bufora au_marshed. Po wyjsciu z tej funkcji zwracana jest wartosc auth.

authunix_create_default()

Trzecia jest bezparametrowa funkcja
   AUTH *authunix_create_default() 
Wykorzystuje ona wczesniej opisana funkcje authunix_create() z tym, ze sama ustawia parametry do jej wywolania.

authdes_create()

Czwartym sposobem jest kontrola w stylu DES (Data Encryption Standard), korzysta sie w niej z funkcji
AUTH *authdes_create(servername, window, syncaddr, ckey)
      char *servername;           /* sieciowa nazwa serwera 
      u_int window;               /* czas do zycia 
      struct sockaddr *syncaddr;  /*opcjonalny adres serwera synchronizujacego 
      des_block *ckey; 
gdzie typ des_block jest zdefiniowany nastepujaco
    typedef union des_block { 
      struct { 
	    u_int32 high; 
	    u_int32 low; 
	    } key; 
      char c[8]; 
      } des_block; 
oraz z dodatkowej struktury:
   struct ad_private { 
      char *ad_fullname;            /* pelna nazwa klienta 
      u_int ad_fullnamelen; 
      char *ad_servername;          /* pelna nazwa serwera 
      u_int ad_servernamelen;
      u_int ad_window; 
      bool_t ad_dosync;             /* synchronizowac? 
      struct sockaddr ad_syncaddr;  /* zdalny serwer do synchronizacji
      struct timeval ad_timediff; 
      u_long ad_nickname;           /* pseudo serwera klienta 
      struct authdes_cred ad_cred;  /* dane autentyfikacji 
      struct authdes_verf ad_verf;  /* dane do weryfikacji 
      struct timeval ad_timestamp;  /* czas wyslania 
      des_block ad_xkey;            /* zakodowany klucz konwersacyjny 
      } *ad; 
AUTH *auth; 
Funkcja na poczatku przydziela pamiec na wszystkie struktury, nastepnie wszystkie je wypelnia odpowiednimi danymi. Ustawia zmienne auth->ah_cred.oa_flavor auth->ah_verf.oa_flavor na AUTH_DES oraz na ah_private przypisuje wskaznik do struktury ad_private. Dokladny opis dzialania funkcji znajduje sie w artykule RFC 1057.

Bibliografia

  1. Biblioteka LIBC, pliki: ./rpc/*
  2. R. Stevens: ,,Programowanie zastosowan sieciowych''
  3. M. Gabbasi, B. Dupouy: ,,Przetwarzanie rozproszone w systemie UNIX''
  4. RFC 1057 - RPC


Autor: Pawel Glebocki