Instalujesz profil, tunel się podnosi i wszystko wygląda na gotowe. Potem telefon się restartuje, on-demand budzi połączenie bez aplikacji na pierwszym planie, a tunel odmawia startu. Profil nadal jest, a hasło nadal jest poprawne, dlatego ten błąd wysyła ludzi do szukania w złym miejscu. Network Extension nie potrafi odczytać twojej tajemnicy z profilu: potrzebuje odwołania do pęku kluczy, które samodzielnie rozwiąże.

Poniższy opis śledzi jedną próbę połączenia przez to przekazanie, od zapytania, które buduje odwołanie, do restartu, który je sprawdza.

Profil przechowuje uchwyt, a nie tajemnicę

NEVPNProtocol udostępnia passwordReference i sharedSecretReference nie bez powodu. Gdy demon uruchamia tunel, może nie działać w twoim procesie, więc nie może wywołać twojego kodu i poprosić o hasło. Odczytuje trwałe odwołanie do pęku kluczy, rozwiązuje je we własnym kontekście i sam pobiera element.

Budujesz to odwołanie, pytając o nie pęk kluczy, co jest innym żądaniem niż żądanie danych:

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
]

Przekaż zwrócony obiekt protokołowi, a nie dane elementu. W praktyce profil zapisuje, gdzie mieszka tajemnica, dlatego kopia zapasowa konfiguracji nie duplikuje hasła po cichu do plist.

Dlaczego API odpowiada -50

errSecParam oznacza, że żądanie lub wartość były źle ukształtowane dla tej operacji, i to jest błąd najczęściej widziany, gdy żądania odwołania i danych się mieszają. Proszenie o dane, gdy odbierający kod oczekuje odwołania, przypisanie surowych bajtów do passwordReference albo zapytanie z grupą dostępu, której aplikacja nie może użyć, wszystkie go powodują.

Biblioteki opakowujące do tego zachęcają. Pomocnik zwracający bajty nie jest wymienny z tym, który zwraca odwołanie, więc naprawą jest zwykle inne zapytanie, a nie inne hasło.

Ta sama niezgodność wyjaśnia profil, który zapisuje się bez skargi, a potem nie łączy: zapisane jest blobem, nie uchwytem, a demon nie ma czego rozwiązywać.

Zapisuje się dobrze, zawodzi przy połączeniu

Zapis ćwiczy kontekst twojej aplikacji. Połączenie ćwiczy kontekst demona, a oba nie mają tego samego dostępu. Profil może więc przejść wszystkie testy w symulatorze i zawieść przy pierwszym starcie on-demand.

Taki jest też kształt objawu po restarcie: działa, dopóki aplikacja jest otwarta, i ginie, gdy system sam uruchamia tunel.

Przetestuj świadomie ścieżkę w tle przed wydaniem. Wywołaj połączenie on-demand przy zamkniętej aplikacji, a potem czytaj konsolę urządzenia, nie log aplikacji, bo błąd zapisuje proces, który próbował rozwiązać odwołanie. Jeśli konsola pokazuje, że demon odrzuca element, odwołanie jest w porządku, a problemem jest dostępność elementu.

Dostępność decyduje, czy restart zadziała

Element musi być czytelny dla każdego procesu systemowego, który uruchamia tunel, a to szersza publiczność niż twoja aplikacja na pierwszym planie. To ograniczenie wybiera za ciebie atrybut dostępności. Element chroniony do pierwszego odblokowania jest dostępny dla startu w tle po jednorazowym odblokowaniu urządzenia; element wymagający, by urządzenie było odblokowane teraz, nie jest.

Wybór surowszej klasy kusi i właśnie on psuje profil on-demand na zablokowanym telefonie.

Po zmianie klasy utwórz element od nowa, zamiast edytować atrybuty istniejącego, a potem zapisz protokół ponownie ze świeżym odwołaniem. Zmiany atrybutów istniejącego elementu nie zawsze dają zachowanie, które sugeruje dokumentacja, a odtworzony element usuwa wątpliwość.

Rotacja to miejsce, w którym gniją zapisane profile

Zmiana hasła w pęku kluczy nie zmienia automatycznie tego, na co wskazuje zapisany profil. Usunięcie elementu jest gorsze: profil trzyma odwołanie do czegoś, czego już nie ma, a awaria wygląda jak odrzucenie uwierzytelnienia.

Rotuj w jednej kolejności. Zaktualizuj element, odczytaj nowe trwałe odwołanie, zapisz protokół ponownie, a potem połącz się przy zamkniętej aplikacji, by dowieść, że demon nadal potrafi je rozwiązać. Trzymaj hasło użytkownika i wspólną tajemnicę w osobnych elementach, aby każde rotowało według własnego harmonogramu, i nigdy nie loguj słownika zapytania ani samego odwołania. Uchwyt nie jest tajemnicą, ale jest mapą do niej.

Powiązane artykuły