Uno dei progetti iOS su cui ho lavorato sulla comunicazione richiesta con le stampanti su SMB. A quanto pare, iOS non ha assolutamente alcun supporto per SMB. Esistono soluzioni per Linux e Android, ma il porting di queste funzionalità su iOS è apparso piuttosto difficile. Dopo molti tentativi, ho finito per implementare me stesso SMB. Quindi ho estratto quel codice come progetto separato (smb4ios). Ecco alcuni documenti da esso, nel caso tu sia interessato a come funziona SMB.
Prima di tutto, cos'è SMB. Inizialmente (come nel 1980) era un protocollo per accedere alle condivisioni di file. Da allora, le condivisioni di file si sono evolute molto, ma SMB no. Perché è ancora rilevante allora, chiedi? Perché è parte integrante di Windows. Non esiste uno "standard SMB", c'è solo "il modo in cui SMB funziona su Windows". Quindi, quando parliamo di SMB, siamo interessati non solo a SMB (livello file system), ma anche a NetBIOS (livello di trasporto), NTLM (autenticazione) e RPC. Ormai sono tutti un po 'cresciuti l'uno nell'altro, formando una mostruosa creatura cipolla a strati. Quindi, dal punto di vista dell'implementazione, dovrai gestirli tutti simultaneamente.
Iniziamo con TCP. TCP è un protocollo di rete di basso livello. Quando si desidera inviare alcuni dati alla rete e ad altri computer, si crea un socket TCP, lo si collega a un indirizzo e si bloccano i dati lì. La presa si occupa di imballaggio e consegna.
SMB è un protocollo di trasporto, un po 'come HTTP. Dovresti sapere che HTTP è fondamentalmente quando inviamo alcune informazioni extra su TCP per descrivere quale tipo di contenuto verrà scambiato. SMB è lo stesso, ma su NetBIOS.
NetBIOS è fondamentalmente una versione molto vecchia di TCP. OSX e iOS non hanno un'implementazione per questo. Fortunatamente, è semplice e può essere implementato su TCP. Quindi, questo codice è SMB su NetBIOS su TCP (noto anche come NBT).
SMB è stato anche chiamato CIFS su qualche punto, sono la stessa cosa. C'è anche SMB 2, che non funziona su Windows XP, quindi è irrilevante per me.
Ora, la prima cosa di cui abbiamo bisogno è trovare i server SMB nella nostra rete. Questo è fatto dalle query dei nomi NetBIOS. Fondamentalmente invia una trasmissione UDP a un indirizzo broadcast (come 255.255.255.255) e chiede "chi ha questo nome?". Quindi qualcuno nella rete può rispondere con il suo IP. C'è un ragazzo principale nella rete NetBIOS con un nome predefinito "master browser", chiediamo prima il suo IP. Quindi possiamo chiedergli chi altri sa, ed è così che otteniamo domini, gruppi e IP del server.
Ora che abbiamo un IP, possiamo collegarci un socket TCP ed eseguire messaggi SMB.
La prima cosa che il server vorrà è per noi accedere a un utente. Effettua il login inviando pacchetti NTLM all'interno dei messaggi della sessione SMB.
NTLM è quando si utilizza la crittografia estremamente complicata per codificare e decodificare nome utente, password, ecc. Ho usato una libreria di terze parti per questo (vedi link sotto).
Dopo il login, hai praticamente aperto una sessione remota con una macchina Windows e puoi eseguire le funzioni dell'API di Windows proprio come faresti normalmente, se tu fossi un'applicazione Windows C ++. Lo fai inviando i comandi RPC nei messaggi Transazione SMB.
In breve: RPC è un codice di funzione API di Windows più il buffer dei parametri, che viene inserito nel messaggio SMB. Puoi chiamare funzioni come EnumAll, OpenPrinter, ecc.
Ulteriori dettagli: Normalmente, per chiamare una funzione con determinati parametri, è necessario premere questi parametri per impilarli. Il che logicamente significa che tutte le strutture e le variabili C pulite con cui tu, l'umano, lavori, sono compresse in un buffer di memoria e che quel buffer viene decompresso nello stesso schema di strutture e roba all'interno della funzione (non ciò che realmente accade). In RPC, basta fornire il codice funzione e il buffer. Il che per alcune persone significa che dovresti replicare le strutture C e poi imballarle nello stesso modo. Ma a mio parere, nulla ti impedisce di scaricare i tuoi dati direttamente in byte, purché il risultato finale binario sia lo stesso.
Ed è così che funziona: si trova l'IP con NetBIOS, si connette via SMB, si invia l'autenticazione NTLM, quindi si eseguono i comandi RPC. Usa Wireshark, è un grande aiuto, e non sarei in nessun posto senza.
References:
SMB: [MS-SMB] al link
RAP: [MS-RAP] al link
DCE-RPC: link
NetBIOS: RFC 1001 e 1002 (ti sfido a leggerlo e non impazzire), link
NTLM: link (la libreria che ho usato)