Instalezi un profil, tunelul urcă și totul pare terminat. Apoi telefonul repornește, on-demand trezește conexiunea fără nicio aplicație în prim-plan, iar tunelul refuză să pornească. Profilul este încă acolo și parola este încă corectă, de aceea acest eșec trimite oamenii să caute în locul greșit. O Network Extension nu poate citi secretul din profil: are nevoie de o referință din breloc pe care o poate rezolva singură.

Parcursul de mai jos urmărește o singură încercare de conectare prin acea predare, de la interogarea care construiește referința până la repornirea care o testează.

Profilul păstrează un mâner, nu secretul

NEVPNProtocol expune passwordReference și sharedSecretReference dintr-un motiv. Când demonul pornește un tunel, s-ar putea să nu ruleze în procesul tău, așa că nu poate apela codul tău și cere o parolă. Citește o referință persistentă din breloc, o rezolvă în propriul context și aduce elementul singur.

Construiești acea referință cerând-o brelocului, ceea ce este o cerere diferită de cererea datelor:

let query: [String: Any] = [
  kSecClass as String: kSecClassGenericPassword,
  kSecAttrService as String: "vpn-credentials",
  kSecAttrAccount as String: "user",
  kSecReturnPersistentRef as String: true,
  kSecMatchLimit as String: kSecMatchLimitOne
]

Predă obiectul returnat protocolului, nu datele elementului. În practică profilul înregistrează unde locuiește secretul, motiv pentru care o copie de siguranță a configurației nu duplică parola în liniște într-un plist.

De ce API-ul răspunde -50

errSecParam înseamnă că cererea sau valoarea erau deformate pentru operațiune, și este eroarea văzută cel mai des când cererile de referință și cele de date se amestecă. Cererea de date în timp ce codul receptor așteaptă o referință, atribuirea de octeți bruti lui passwordReference sau interogarea cu un grup de acces pe care aplicația nu îl poate folosi, toate o produc.

Bibliotecile de înveliș invită la asta. Un ajutor care returnează octeți nu este interschimbabil cu unul care returnează o referință, așa că reparația este de obicei altă interogare, nu altă parolă.

Aceeași nepotrivire explică un profil care se salvează fără reclamație și apoi nu se conectează: ceea ce s-a stocat este un blob, nu un mâner, iar demonul nu are ce rezolva.

Se salvează bine, eșuează la conectare

Salvarea exersează contextul aplicației tale. Conectarea îl exersează pe cel al demonului, iar cele două nu au același acces. Un profil poate trece astfel toate testele din simulator și poate eșua la prima pornire on-demand.

Aceasta este și forma simptomului la repornire: funcționează cât timp aplicația este deschisă și moare când sistemul pornește tunelul singur.

Testează deliberat calea din fundal înainte de livrare. Declanșează o conexiune on-demand cu aplicația închisă, apoi citește consola dispozitivului, nu jurnalul aplicației, pentru că eșecul este înregistrat de procesul care a încercat să rezolve referința. Dacă consola arată că demonul respinge elementul, referința este bună și problema este accesibilitatea elementului.

Accesibilitatea decide dacă o repornire funcționează

Elementul trebuie să fie lizibil de orice proces de sistem care lansează tunelul, iar acesta este un public mai larg decât aplicația ta în prim-plan. Această constrângere alege atributul de accesibilitate pentru tine. Un element protejat până la prima deblocare este disponibil pentru o pornire din fundal după ce dispozitivul a fost deblocat o dată; un element care cere ca dispozitivul să fie deblocat chiar acum nu este.

Alegerea clasei mai stricte este tentantă și exact aceasta strică un profil on-demand pe un telefon blocat.

După ce schimbi clasa, recreează elementul în loc să editezi atributele celui existent, apoi salvează din nou protocolul cu o referință proaspătă. Modificările de atribute pe un element existent nu produc mereu comportamentul pe care documentația îl sugerează, iar un element reconstruit înlătură îndoiala.

Rotația este locul unde putrezesc profilele salvate

Schimbarea parolei în breloc nu schimbă automat ceea ce indică profilul salvat. Ștergerea elementului este mai rău: profilul păstrează o referință către ceva ce nu mai există, iar eșecul arată ca o respingere a autentificării.

Rotește într-o singură ordine. Actualizează elementul, interoghează o referință persistentă nouă, salvează din nou protocolul, apoi conectează-te cu aplicația închisă pentru a dovedi că demonul o mai poate rezolva. Ține parola utilizatorului și secretul comun în elemente separate, ca fiecare să rotească după propriul calendar, și nu înregistra niciodată dicționarul interogării sau referința însăși. Mânerul nu este un secret, dar este o hartă către unul.

Articole similare