Приветствую, коллеги!
Многие из Вас, кто разрабатывает приложения под мобильные платформы на iOS, сталкивались с проблемой недоступности многих ключевых данных.
Одним из таких параметров является текущий режим шифрования в Wi-Fi сети.
Так как этот параметр явно можно получить только «нелегальным» способом через Private Framework, считается что узнать его стандартными методами невозможно.
Это не так. Я хочу продемонстрировать вам walkaround, работающий на iOS 5 (но закрытый, увы, на iOS6).
Реальностью является то, что программно этот параметр действительно получить нельзя. Но он довольно просто получается по «вторичным половым признакам».
Конечно же, вы обращали внимание на то, что в логах вашего устройства протоколируется момент подключения к сети сообщениями подобного вида:
Oct 5 11:37:58 ISOX-iPhone kernel[0] <Debug>: 023881.292007 wlan.N[2599] AppleBCMWLAN Joined BSS: @ 0x80eb1400, BSSID = some_mac_address, rssi = -30, rate = 54 (100%), channel = 3, encryption = 0x8, ap = 1, failures = 0, age = 0, ssid[ 6] = "pretty_ssid"
Как вы можете видеть, это сообщение ASL, отправленное «kernel» с уровнем «debug». В нем присутствует необходимый параметр «encryption», который определяет текущий режим шифрования.
Соответственно, нашей задачей является получение этого сообщения и обработка внутри программы легальными методами.
Для этого нам потребуется поработать с ASL системой iOS (не забудьте про #import <asl.h>).
aslmsg asl, message;
aslresponse searchResult;
int i;
const char *key, *val;
NSMutableArray *result_dicts = [NSMutableArray array];
// Создаем подключение к ASL
asl = asl_new(ASL_TYPE_QUERY);
if (!asl)
{
NSLog(@"Failed creating ASL query");
}
// Задаем фильтр поиска по отправителю
asl_set_query(asl, "Sender", "kernel", ASL_QUERY_OP_EQUAL);
// Задаем фильтр поиска по подстроке
asl_set_query(asl, "Message", "AppleBCMWLAN Joined BSS:", ASL_QUERY_OP_PREFIX|ASL_QUERY_OP_EQUAL);
searchResult = asl_search(NULL, asl);
while (NULL != (message = aslresponse_next(searchResult)))
{
NSMutableDictionary *tmpDict = [NSMutableDictionary dictionary];
for (i = 0; (NULL != (key = asl_key(message, i))); i++)
{
NSString *keyString = [NSString stringWithUTF8String:(char *)key];
val = asl_get(message, key);
NSString *string = [NSString stringWithUTF8String:val];
[tmpDict setObject:string forKey:keyString];
}
// Собираем все результаты
[result_dicts addObject:tmpDict];
}
aslresponse_free(searchResult);
asl_free(asl);
В результаты вы получите массив словарей вида:
{
ASLMessageID = 723;
Facility = kern;
Level = 7;
Message = "AppleBCMWLAN Joined BSS: @ 0xc1985200, BSSID = some_mac_address, rssi = -42, rate = 54 (100%), channel = 3, encryption = 0x8, ap = 1, failures = 0, age = 1, ssid[ 6] = "pretty_ssid"";
PID = 0;
Sender = kernel;
Time = 1349423438;
}
Последнее сообщение, отсортированное по параметру «Time», будет являться верным.
Проблема решена: у вас есть значение текущего режима шифрования. Получить ее из строки Message не составит труда.
Следующий закономерный вопрос, — что оно означает?
Для этого потребовалось произвести небольшой поиск по исходным кодам драйверов Wi-Fi устройств.
Расшифровка значений следующая (при переводе значения в десятичную систему исчисления):
case 0: "None"
case 1: "WEP"
case 2: "WPA"
case 4: "WPA PSK"
case 6: "WPA2"
case 8: "WPA2 PSK"
case 10: "LEAP"
case 12: "80211X"
case 14: "WPS"
Задача решена, — получено значение шифования сети без использования Private Framework.
Конечно же, не обходится без минусов: время жизни сообщений довольно мало и требуется постоянное наблюдение над ASL.
К сожалению, Apple закрыла доступ к лог-сообщениям ядра на 6-й прошивке. Что же, — придется искать новый способ.
Спасибо за внимание. Надеюсь, я рассказал Вам что-то интересное.
Автор: isox