RiccardoRobb / Remote-management-system

Client - Server (Linux/Windows).The file named readme is written in Italian.

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Sviluppo di un sistema per la gestione remota

Il sistema consiste di un server installato sulla macchina "target" e di un client installato sulla macchina di "controllo".

Il sistema funziona sia su Windows, sia su Linux anche in modalità mista (server Windows, client Linux e viceversa).

Il server viene attivato in modalità daemon sotto Linux e come applicazione da linea comandi sotto Windows.

Il client ed il server interagiscono attraverso un semplice protocollo testuale di tipo richiesta-risposta sincrono (dopo l'invio di una richiesta non si può inviare un'altra richiesta fino a quando non arriva la risposta).

Il server ed il client implementano un semplice protocollo di autenticazione che permette solamente a client autorizzati di effettuare richieste al server.

Il server al momento dell'avvio richiede all'utente tramite linea comando l'inserimento di una passphrase con cui generare un token T_s che dovrà essere utilizzato dai client per l'autenticazione. Qualora il server venga avviato con l'opzione (-s) stampa su stdout il token di autenticazione non appena questo è stato generato. Al termine del processo di generazione del token, di seguito descritto, il buffer utilizzato per leggere la passphrase deve essere azzerato. Al termine di queste operazioni, il server si mette in attesa di connessioni sulla porta TCP 8888, modificabile sia tramite opzione (-p) da linea comandi alla partenza, sia tramite file di configurazione letto alla partenza (opzione -c).

Il server crea inizialmente un pool di thread per gestire le richieste. Il numero di thread è specificabile da linea comandi (opzione -n) o da file di configurazione. Ogni thread alla fine della operazioni necessarie per gestire una richiesta rientra nel pool. Se nessun thread è disponibile per gestire una richiesta, la richiesta rimane in sospeso fino a quando un thread non è disponibile.

Ogni thread deve loggare sul file di log del server(opzione -l) le richieste che arrivano dai client autenticati (quindi solo le richieste che arrivano dai client dopo che hanno ricevuto il codice 200 a seguito del comando AUTH.); il file di log contiene una riga per ogni richiesta. Ogni riga contiene le seguenti informazioni:

  • id del thread che ha ricevuto la richiesta;

  • indirizzo IP e porta del client;

  • il tipo di richiesta (LSF, EXEC, DOWNLOAD, SIZE, UPLOAD);

  • un marcatore temporale (timestamp) che identifichi quando è arrivata la richiesta.

Per garantire l'accesso concorrente in scrittura al file di log, utilizzare un meccanismo di lock a scelta tra quelli visti durante il corso. Nella relazione finale, motivare la scelta.

In ambiente Unix/Linux il server, mentre è in esecuzione, è in grado di rileggere il file di configurazione e, se necessario, modificare la porta TCP ed il numero massimo di thread. La rilettura è attivata quando il server riceve il segnale SIGHUP. Qualora non venga fornito un file di configurazione all'avvio del server, la ricezione del segnale SIGHUP non produrrà alcun effetto.

Il server quando viene avviato può ricevere i seguenti parametri opzionali:

  • -p porta TCP su cui stare in ascolto (valore di default 8888);

  • -n numero massimo di thread per gestire le richieste (valore di default 10);

  • -c path file di configurazione;

  • -s stampa su stdout il token T_s quando viene generato;

  • -l path file di log (valore di default /tmp/server.log)

Il protocollo di comunicazione tra server e client supporta i seguenti comandi:

  • HELO

  • AUTH: <enc1;enc2>: come calcolare enc1 ed enc2 è definito nella descrizione del protocollo di autenticazione.

  • LSF <path>: richiede la lista di file e directory contenuti in path (non entra nelle eventuali sottocartelle).

  • EXEC <cmd num_args [args...] >: richiede che venga eseguito sul server il comando specificato da cmd [args..] e ritorna lo stdout del programma se questo termina correttamente (valore di ritorno = 0) oppure il valore di ritorno nel caso ci sia stato un errore. I comandi lanciati da EXEC non devono essere interattivi.

  • DOWNLOAD <path;size>: richiede che il server si prepari a ricevere un file di size byte e lo salvi sul path specificato.

  • SIZE <path>: richiede la dimensione in byte del file indicato da path. É un comando ausiliario che va utilizzato prima del comando UPLOAD per conoscere la dimensione in byte del file.

  • UPLOAD <path,size>: richiede che il server invii i primi size byte del contenuto del file identificato da path.

Il server invia i seguenti codici di risposta al client

200: indica che l'operazione è andata a buon fine.

300: indica che il server invierà ulteriore output. Utilizzato per indicare l'invio della lista dei file come risposta dei comandi LSF e EXEC(vedi seguito), per l’invio della challenge di autenticazione come risposta del comando HELO e per l'invio della size del comando SIZE.

400: indica che l'operazione ha prodotto un errore. Ad esempio il path non esiste, oppure il comando non esiste.


Il server in risposta al comando HELO invia il codice 300 e a seguire un unsigned long int che rappresenta la challenge di autenticazione, come descritta in seguito nel protocollo di autenticazione.

In riposta al comando SIZE invia il codice 300 e a seguire un unsigned long int che rappresenta la size in byte del file richiesto.

In risposta al comando LSF, il server invia il codice 300 e, a seguire, la lista dei file come una serie di record testuali (un record per ogni file) aventi la seguente struttura: "dimensione (in byte)" "path del file". I record di aggiornamento sono separati tra di loro dalla sequenza "\r\n" e la file della lista è indicata dalla sequenza " \r\n.\r\n".

In risposta al comando EXEC, il server invia il codice 300 e, a seguire, lo stdout se il programma ha terminato correttamente oppure il valore di ritorno nel caso ci sia stato un errore. Il server invia il contenuto dello stdout una linea alla volta e alla fine conclude con la sequenza " \r\n.\r\n"; nel caso in cui il server invii il valore di ritorno lo invia su una linea, terminata con la sequenza " \r\n.\r\n".

Il server deve supportare almeno i seguenti comandi tramite la richiesta EXEC :

  • copy <src> [<src>...] <dst>: copia src in dst. Se ci sono più src, dst deve essere una directory

  • remove <file> [<file>...] : rimuove il/i file che sono passati come argomenti

  • whoami: stampa utente

  • printworkdir: ritorna la working directory

  • sort <file>: stampa il contenuto di file ordinato lessicograficamente


Il protocollo di autenticazione prevede la definizione della funzione unsigned long int generateToken(const char *passphrase), in grado di generare un token a partire da una passphrase di lunghezza variabile; è richiesto che, data la stessa passphrase in input venga generato lo stesso output. Il protocollo di autenticazione prevede i seguenti passi:

  1. Il server chiama la funzione generateToken per calcolare, a partire dalla server-passphrase, il token T_s che identifica il server;

  2. Ogni client utilizza la funzione generateToken per calcolare il token T_s utilizzando la server-passphrase ed un token T_c_i a partire dalla client_i-passphrase.

  3. Il client invia un messaggio di HELO a cui il server risponde con un codice di risposta 300 ed invia poi un unsigned long int che contiene la challenge. Il valore che viene inviato dal server è calcolato effettuando lo XOR del token T_s e della challenge, un unsigned long int scelto dal server in maniera random.

  4. Il client estrae la challenge, utilizzando il valore di T_s che ha calcolato al passo 2. Invia poi al server un messaggio AUTH <enc1;enc2> dove
    enc1_c=(T_s XOR challenge XOR T_c_i ) e enc2_c=(T_c_i XOR challenge).

  5. Il server estrae da enc1 la chiave T_c_i e la utilizza per verificare da enc2 la challenge; se il valore è corretto risponde con un codice 200 altrimenti con un codice 400 e chiude la comunicazione.

I comandi del client sono specificati da linea comandi utilizzando le seguenti opzioni (o con equivalenti sottocomandi):

-l <path> richiede la lista dei file presenti nella cartella (corrisponde al comando LST);

-e <cmd [args ...]> richiede che venga eseguito sul server il comando specificato da cmd [args..] e che venga ritornato il valore di ritorno di esecuzione del comando (corrisponde al comando EXEC);

-d <src-path> <dest-path> richiede che il server si prepari a ricevere il file identificato da <src-path> (client) e lo salvi su <dest-path> (server) (corrisponde al comando DOWNLOAD);

-u <src-path> <dest-path> richiede che il server invii identificato da <src-path> (server) e che questo venga salvato su <dest-path> (client) (corrisponde al comando UPLOAD).

Quando un client viene avviato richiede, oltre all'opzione relativa al comando da inviare al server, anche 2 parametri obbligatori, l'indirizzo ip del server (opzione -h) e la porta su cui il server è in ascolto (opzione -p).

Prima di stabilire la connessione con il server, ogni client richede l'inserimento di due passphrase: quella utilizzata all'avvio del server server-passphrase, ed una specifica per ogni client, client-passphrase (es. i-esimo client avrà la passphrase client_i-passphrase). Queste passphrase saranno utilizzate per la procedura di autenticazione. Il primo messaggio che il client deve inviare dopo l'avvenuta connessione è un messaggio di HELO per ricevere la challenge da utilizzare nel messaggio AUTH. Dopo che l'autenticazione è andata a buon fine il client può inviare la richiesta al server.

About

Client - Server (Linux/Windows).The file named readme is written in Italian.


Languages

Language:C 99.0%Language:Makefile 0.5%Language:Batchfile 0.5%