Профіль VPN у iOS: passwordReference, а не пароль
Спасылка на звязку ключоў — гэта дэскрыптар, а не сакрэт. Перадача байтаў тлумачыць памылку -50, збой пры перазагрузцы і пастку ратацыі ў захаваных профілях VPN.
Вы ўсталёўваеце профіль, тунель узнікае, і ўсё выглядае скончаным. Затым тэлефон перазагружаецца, on-demand будзіць злучэнне без праграмы на пярэднім плане, і тунель адмаўляецца запускацца. Профіль усё яшчэ на месцы, і пароль усё яшчэ правільны, таму гэтая памылка адпраўляе людзей шукаць не там. Network Extension не можа прачытаць вашу таямніцу з профілю: яму патрэбна спасылка на звязку ключоў, якую ён можа развязаць сам.
Разбор ніжэй прасочвае адну спробу злучэння праз гэтую перадачу: ад запыту, які будуе спасылку, да перазагрузкі, якая яе правярае.
Профіль захоўвае дэскрыптар, а не таямніцу
NEVPNProtocol адкрывае passwordReference і sharedSecretReference не проста так. Калі дэман запускае тунель, ён можа не працаваць унутры вашага працэсу, таму не можа выклікаць ваш код і папрасіць пароль. Ён чытае пастаянную спасылку на звязку ключоў, развязвае яе ў сваім кантэксце і сам атрымлівае элемент.
Вы будуеце гэтую спасылку, пытаючыся пра яе ў звязкі ключоў; гэта іншы запыт, чым запыт даных:
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
]Перадайце вернуты аб’ект пратаколу, а не даныя элемента. На практыцы профіль запісвае, дзе жыве таямніца, таму рэзервовая копія канфігурацыі не дубліруе пароль моўчкі ў plist.
Чаму API адказвае -50
errSecParam азначае, што запыт або значэнне былі няправільныя для аперацыі, і гэта памылка, якую часцей за ўсё бачаць, калі запыты спасылкі і даных блытаюцца. Запыт даных, калі код, што прымае, чакае спасылку, прысваенне сырых байтаў passwordReference або запыт з групай доступу, якую праграма не можа выкарыстаць, — усё гэта спараджае яе.
Бібліятэкі-абгорткі запрашаюць да гэтага. Памочнік, які вяртае байты, не ўзаемазамяняльны з тым, што вяртае спасылку, таму выпраўленне звычайна — іншы запыт, а не іншы пароль.
Тая ж неадпаведнасць тлумачыць профіль, які захоўваецца без скаргаў і потым не можа падключыцца: захаванае — гэта блоб, а не дэскрыптар, і дэману няма чаго развязваць.
Захоўваецца добра, зрываецца пры падключэнні
Захаванне выконваецца ў кантэксце вашай праграмы. Падключэнне — у кантэксце дэмана, і ў іх розны доступ. Таму профіль можа прайсці ўсе тэсты ў сімулятары і зваліцца на першым запуску on-demand.
Такая ж форма ў сімптома перазагрузкі: працуе, пакуль праграма адкрыта, і памірае, калі сістэма запускае тунель сама.
Праверце фонавы шлях свядома перад выпускам. Выклічце on-demand злучэнне з закрытай праграмай, потым чытайце кансоль прылады, а не журнал праграмы, бо памылку запісвае працэс, які спрабаваў развязаць спасылку. Калі кансоль паказвае, што дэман адхіляе элемент, спасылка слушная, а праблема ў даступнасці элемента.
Даступнасць вырашае, ці спрацуе перазагрузка
Элемент павінен быць чытэльным для таго сістэмнага працэсу, які запускае тунель, а гэта шырэйшая аўдыторыя, чым ваша праграма на пярэднім плане. Гэтае абмежаванне само выбірае атрыбут даступнасці. Элемент, абаронены да першага разблакіравання, даступны фонаваму запуску пасля таго, як прыладу разблакіравалі адзін раз; элемент, які патрабуе, каб прылада была разблакіравана зараз, — не.
Выбраць больш строгі клас спакусліва, і менавіта гэта ламае профіль on-demand на заблакіраваным тэлефоне.
Пасля змены класа стварыце элемент нанова, а не рэдагуйце атрыбуты існуючага, потым перазахавайце пратакол з новай спасылкай. Змены атрыбутаў існуючага элемента не заўсёды даюць паводзіны, якія мае на ўвазе дакументацыя, а пераствораны элемент здымае сумненні.
Ратацыя — там, дзе гніюць захаваныя профілі
Змена пароля ў звязцы ключоў не змяняе аўтаматычна тое, на што паказвае захаваны профіль. Выдаленне элемента горш: профіль захоўвае спасылку на тое, чаго ўжо няма, і памылка выглядае як адмова аўтэнтыфікацыі.
Ратуйце ў адным парадку. Абнавіце элемент, запытайце новую пастаянную спасылку, перазахавайце пратакол, потым падключыцеся з закрытай праграмай, каб даказаць, што дэман усё яшчэ можа яе развязаць. Трымайце пароль карыстальніка і агульную таямніцу ў асобных элементах, каб кожны ратаваўся па сваім графіку, і ніколі не лагуйце слоўнік запыту або саму спасылку. Дэскрыптар — не таямніца, але гэта карта да яе.