Ce poate crea NEVPNManager pe iOS (și ce nu poate)
API-ul VPN din iOS construiește o singură configurație deținută de aplicație din trei clase de protocol. L2TP, PPTP și profilurile semnate nu fac parte din această suprafață.
Când construiești un ecran VPN într-o aplicație iOS, prima surpriză este că lista de protocoale din aplicația Setări nu este lista API-ului. Framework-ul Network Extension permite aplicației tale să creeze o singură configurație VPN personală, deținută de acea aplicație, și acceptă doar câteva obiecte de protocol. Tot restul la care oamenii se așteaptă, de la L2TP la un profil descărcat, se află în afara acestei suprafețe sau este privat pentru Apple. Eșecurile care urmează nu sunt de obicei bug-uri, este API-ul care refuză o sarcină pe care nu a primit-o niciodată.
Mitul: API-ul este un editor de Setări
Se crede că, din moment ce iOS poate configura profiluri IKEv1, IKEv2, L2TP și IPsec, o aplicație poate crea oricare dintre ele programatic. Nu poate. Framework-ul expune exact un singur slot de configurare aplicației apelante, iar acel slot acceptă doar un set mic de clase de protocol publice. Tot restul la care oamenii se așteaptă, de la L2TP la un profil descărcat, se află în afara acestei suprafețe sau este privat pentru Apple.
Eșecurile care urmează nu sunt de obicei bug-uri. Este API-ul care refuză o sarcină pe care nu a primit-o niciodată, iar soluția este să proiectezi ecranul în jurul a ceea ce deține API-ul.
Trei obiecte de protocol și cele care nu există
Opțiunile tale sunt IKEv1 prin NEVPNProtocolIPSec, IKEv2 prin NEVPNProtocolIKEv2, și NETunnelProviderProtocol dacă livrezi propria extensie de tunel de pachete. Referința NEVPNManager listează obiectele de protocol acceptate. L2TP și PPTP nu apar niciodată în acea listă pentru că Apple nu a publicat clase pentru ele. Încercarea oricăruia se termină la salvare cu o eroare sau, mai rău, cu o configurație pe care sistemul refuză în liniște să o folosească.
Codul desktop urmează alte reguli. Pe macOS, SCNetworkInterfaceCreateWithInterface stivuește un tip de interfață precum L2TP peste IPv4 și îl atașează la un serviciu de rețea, iar networksetup -connectpppoeservice pornește rezultatul. Sunt necesare drepturi de administrator și un instrument auxiliar, deoarece secretul partajat și parola ajung în trousseaua sistemului. Copiază acest design pe iOS și nimic nu se compilează.
Transmite o referință la trousseau, nu parola
Niciuna dintre cele două clase IKE nu acceptă o parolă ca text. Cele două proprietăți passwordReference și sharedSecretReference vor o referință persistentă la trousseau, pe care o obții din SecItemCopyMatching cerând kSecReturnPersistentRef. Trecerea datelor elementului sau introducerea unui șir în câmp produce un eșec la salvare sau o conexiune cu credențiale goale. Referința este durabilă doar cât elementul din trousseau din spatele ei, de aceea elementul trebuie să existe înainte ca configurația să fie asamblată. Creează-l în aceeași tranzacție cu salvarea și elimini o întreagă clasă de bug-uri de ordonare.
Autentificarea prin certificat urmează o altă rută: identityData plus identityDataPassword pentru un blob PKCS#12. Livrarea acelui blob în pachetul aplicației este un obicei preluat din codul exemplu, nu o decizie de lansare, deoarece parola călătorește cu el și fiecare copie a aplicației poartă aceeași identitate.
Dreptul și disponibilitatea condiționează totul
Managerul poate să nu existe deloc, iar motivul este provisionarea. Identificatorul aplicației tale are nevoie de capacitatea Network Extension împreună cu dreptul pentru VPN personal, iar profilul care semnează build-ul trebuie să le poarte pe amândouă.
Sari peste asta și instanța partajată returnează nil, sau salvarea eșuează cu o eroare care nu menționează niciodată dreptul. Disponibilitatea este cealaltă poartă. Dacă țintești ceva mai vechi decât iOS 8, simbolul lipsește la rulare, așa că eșecul este un crash sau un manager nil, nu un manager fără configurație. Verifică mediul de rulare și dreptul înainte de a depana graful de obiecte.
Încarcă, modifică, salvează, apoi urmărește ordinea la cerere
Tratează ciclul de viață ca încărcare, modificare, salvare și nu sări niciodată peste încărcare. Până când loadFromPreferences nu se termină, managerul nu deține nimic și obiectul de protocol nu poate fi citit sau înlocuit.
O a doua salvare înlocuiește configurația în loc să adauge alta, așa că o salvare pe jumătate poate deteriora un profil care funcționa. Regulile la cerere formează un tablou ordonat, iar acea ordine este politica. Pune o regulă de conectare de oriunde înaintea regulii de deconectare și unei deconectări manuale îi urmează o reconectare imediată, ceea ce pare un defect dar urmează evaluarea documentată.
Mută regula de deconectare în față când acțiunea utilizatorului trebuie să câștige. Ce rămâne în afara controlului aplicației contează la fel de mult. Rutele vin din tunel sau din politica serverului, nu dintr-o preferință pe care o setezi tu, iar un furnizor de tunel de pachete le raportează la pornire. Aplicația nu poate lista sau edita profiluri instalate de alte aplicații sau profiluri de configurare, așa că nu promite un ecran care arată fiecare VPN de pe dispozitiv.