Du installerar en profil, tunneln kommer upp och allt ser färdigt ut. Sedan startar telefonen om, on-demand väcker anslutningen utan någon app i förgrunden, och tunneln vägrar starta. Profilen finns kvar och lösenordet är fortfarande rätt, och det är därför det här felet skickar folk att leta på fel ställe. En Network Extension kan inte läsa din hemlighet från profilen: den behöver en nyckelringreferens som den själv kan lösa upp.

Genomgången nedan följer ett enda anslutningsförsök genom den överlämningen, från frågan som bygger referensen till omstarten som testar den.

Profilen lagrar ett handtag, inte hemligheten

NEVPNProtocol exponerar passwordReference och sharedSecretReference av en anledning. När daemonen startar en tunnel kör den kanske inte i din process, så den kan inte anropa din kod och be om ett lösenord. Den läser en varaktig nyckelringreferens, löser upp den i sin egen kontext och hämtar posten själv.

Du bygger referensen genom att fråga nyckelringen om den, vilket är en annan begäran än begäran om data:

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
]

Lämna det returnerade objektet till protokollet, inte postens data. I praktiken registrerar profilen var hemligheten bor, och därför duplicerar inte en säkerhetskopia av konfigurationen lösenordet tyst till en plist.

Varför API:t svarar -50

errSecParam betyder att begäran eller värdet var felformat för åtgärden, och det är felet man oftast ser när begärandena om referens och data blandas ihop. Att be om data medan mottagande kod väntar sig en referens, att tilldela råa byte till passwordReference eller att fråga med en åtkomstgrupp som appen inte kan använda, alla framkallar det.

Inpackningsbibliotek bjuder in till detta. En hjälpare som returnerar byte är inte utbytbar mot en som returnerar en referens, så reparationen är oftast en annan fråga och inte ett annat lösenord.

Samma oförenlighet förklarar en profil som sparas utan klagomål och sedan inte ansluter: det som sparades är en blob, inte ett handtag, och daemonen har inget att lösa upp.

Sparas fint, misslyckas vid anslutning

Sparande utövar appens kontext. Anslutning utövar daemonens, och de två har inte samma åtkomst. En profil kan därför klara alla tester i simulatorn och misslyckas vid den första on-demand-starten.

Det är också formen på omstartssymtomet: det fungerar medan appen är öppen och dör när systemet startar tunneln självt.

Testa bakgrundsvägen med avsikt före release. Utlös en on-demand-anslutning med appen stängd och läs sedan enhetskonsolen i stället för appens logg, eftersom felet registreras av processen som försökte lösa upp referensen. Om konsolen visar att daemonen avvisar posten är referensen okej och problemet är postens tillgänglighet.

Tillgänglighet avgör om en omstart fungerar

Posten måste vara läsbar för vilken systemprocess som helst som startar tunneln, och det är en bredare publik än din app i förgrunden. Den begränsningen väljer tillgänglighetsattributet åt dig. En post som skyddas till första upplåsningen är tillgänglig för en bakgrundsstart efter att enheten låsts upp en gång; en post som kräver att enheten är upplåst just nu är det inte.

Att välja den strängare klassen är frestande, och det är precis det som förstör en on-demand-profil på en låst telefon.

När du har bytt klass, återskapa posten i stället för att redigera attribut på den befintliga, och spara sedan protokollet igen med en färsk referens. Attributändringar på en befintlig post ger inte alltid det beteende som dokumentationen antyder, och en återuppbyggd post tar bort tvivlet.

Rotation är där sparade profiler ruttnar

Att ändra lösenordet i nyckelringen ändrar inte automatiskt vad den sparade profilen pekar på. Att radera posten är värre: profilen behåller en referens till något som inte längre finns, och felet ser ut som en avvisad autentisering.

Rotera i en enda ordning. Uppdatera posten, fråga efter en ny varaktig referens, spara protokollet igen och anslut sedan med appen stängd för att bevisa att daemonen fortfarande kan lösa upp den. Håll användarens lösenord och den delade hemligheten i separata poster så att var och en roterar enligt sitt eget schema, och logga aldrig frågeordboken eller referensen själv. Handtaget är inte en hemlighet, men det är en karta till en.

Relaterade artiklar