Are there new device identifiers in iOS 10? - ios

Has anyone found a new way to uniquely identify a device in iOS 10? I haven't seen any documentation mentioning changes in that area and I wanted to ask before I surrendered to identifier for vendor.

If you're submitting to the store, the only real identifier you have left is the Advertising Identifier for the AdSupport framework.
If you want to go down the rabbit hole a little further and potentially go into some unsafe API territory, you could hook into IOKit and try to get the battery identifier on the device. This is taken from Anthony Agatiello gist of UIDevice extensions:
- (NSString *)batteryID {
void *IOKit = dlopen("/System/Library/Frameworks/IOKit.framework/Versions/A/IOKit", RTLD_LAZY);
NSParameterAssert(IOKit);
mach_port_t *kIOMasterPortDefault = dlsym(IOKit, "kIOMasterPortDefault");
NSParameterAssert(kIOMasterPortDefault);
CFMutableDictionaryRef (*IOServiceNameMatching)(const char *name) = dlsym(IOKit, "IOServiceNameMatching");
NSParameterAssert(IOServiceNameMatching);
mach_port_t (*IOServiceGetMatchingService)(mach_port_t masterPort, CFDictionaryRef matching) = dlsym(IOKit, "IOServiceGetMatchingService");
NSParameterAssert(IOServiceGetMatchingService);
kern_return_t (*IORegistryEntryCreateCFProperties)(mach_port_t entry, CFMutableDictionaryRef *properties, CFAllocatorRef allocator, UInt32 options) = dlsym(IOKit, "IORegistryEntryCreateCFProperties");
NSParameterAssert(IORegistryEntryCreateCFProperties);
kern_return_t (*IOObjectRelease)(mach_port_t object) = dlsym(IOKit, "IOObjectRelease");
NSParameterAssert(IOObjectRelease);
CFMutableDictionaryRef properties = NULL;
mach_port_t service = IOServiceGetMatchingService(*kIOMasterPortDefault, IOServiceNameMatching("charger"));
IORegistryEntryCreateCFProperties(service, &properties, kCFAllocatorDefault, 0);
IOObjectRelease(service);
service = 0;
NSDictionary *dictionary = (__bridge NSDictionary *)properties;
NSData *batteryIDData = [dictionary objectForKey:#"battery-id"];
CFRelease(properties);
properties = NULL;
dlclose(IOKit);
return [NSString stringWithUTF8String:[batteryIDData bytes]];
}
This still works on iOS 10.

Related

SecItemAdd on OS X not working, on iOS is

I have a problem.
I have working Code for iOS to add a private Key to the Keychain by SecItemAdd. It works without any error.
On OS X with the same attributes and values, it does not work.
Any ideas, whats the problem. Here is the part of the Code:
NSData * keyData = ...
NSString * name = #"TestKey"
NSString * keyID = #"TestKey"
const id keys[] = {
(__bridge id)(kSecClass),
(__bridge id)(kSecAttrKeyClass),
(__bridge id)(kSecAttrLabel),
(__bridge id)(kSecAttrApplicationLabel),
(__bridge id)(kSecAttrIsPermanent),
(__bridge id)(kSecAttrAccessible),
(__bridge id)(kSecValueData) };
const id values[] = {
(__bridge id)(kSecClassKey),
(__bridge id)(kSecAttrKeyClassPrivate),
name,
keyID,
(id)kCFBooleanTrue,
(__bridge id)(kSecAttrAccessibleAfterFirstUnlock),
keyData };
NSMutableDictionary * attributes = [[NSMutableDictionary alloc] initWithObjects:values forKeys:keys count:ATTR_COUNT(keys)];
CFTypeRef result;
NSError * error = nil;
OSStatus osStatus = SecItemAdd((__bridge CFDictionaryRef)attributes, &result);
The error is:
25303 (errKCNoSuchAttr / errSecNoSuchAttr: / The attribute does not
exist.).)
The Error code specifies The attribute does not exist, it is due to the attribute : kSecAttrKeyClass. Try removing this attribute, and use tag names to distinguish the different keys. I was also getting similar issue in my code.
Which OS X version are you trying to support? OS X Keychain Services are different than iOS Keychain Services. For example, kSecClass is only available as of OS X 10.7, and kSecAttrAccessible 10.9.

IPConfiguration apple80211Open() crashes on iOS8

I am trying to read RSSI of iPhone WIFI connection to AP.
Using Xcode 6.1.1 with iPhone6+ ios 8.1.3
Code below crashes at apple80211Open() and gets EXC_BAD_ACCESS (code=1, address= 0) on iOS 8. (code works on iOS 7.1)
This is for app that is NOT for Apple Store -- for adhoc distribution only.
=================================================================
void *libHandle;
void *airportHandle;
int (*apple80211Open)(void *);
int (*apple80211Bind)(void *, NSString *);
int (*apple80211Close)(void *);
int (*apple80211GetInfoCopy)(void *, CFDictionaryRef *);
NSMutableDictionary *infoDict = [NSMutableDictionary new];
NSDictionary * tempDictionary;
libHandle = dlopen("/System/Library/SystemConfiguration/IPConfiguration.bundle/IPConfiguration", RTLD_LAZY);
char *dlerror_error;
if (libHandle == NULL && (dlerror_error = dlerror()) != NULL) {
NSLog(#"%s", dlerror_error);
}
apple80211Open = dlsym(libHandle, "Apple80211Open");
apple80211Bind = dlsym(libHandle, "Apple80211BindToInterface");
apple80211Close = dlsym(libHandle, "Apple80211Close");
apple80211GetInfoCopy = dlsym(libHandle, "Apple80211GetInfoCopy");
apple80211Open(&airportHandle);
apple80211Bind(airportHandle, #"en0");
CFDictionaryRef info = NULL;
apple80211GetInfoCopy(airportHandle, &info);
tempDictionary = (__bridge NSDictionary *)info;
apple80211Close(airportHandle);
[infoDict setObject:(tempDictionary[#"RSSI"])[#"RSSI_CTL_AGR"] ? (tempDictionary[#"RSSI"])[#"RSSI_CTL_AGR"] : #"0" forKey:#"RSSI"];
[infoDict setObject:tempDictionary[#"BSSID"] ? tempDictionary[#"BSSID"] : #"null" forKey:#"BSSID"];
[infoDict setObject:tempDictionary[#"SSID_STR"] ? tempDictionary[#"SSID_STR"] : #"null" forKey:#"SSID"];
[infoDict setObject:tempDictionary[#"RATE"] ? tempDictionary[#"RATE"] : #"0" forKey:#"SPEED"];
That's because Apple removed the 80211 framework from within IPConfiguration. The symbols can't be found, dlsym returns NULL, and - a crash (you should always check return values, you know).
To begin with, this was a private framework. In new versions of iOS (8+), it's deprecated in favor of MobileWifi, and the use of entitlements (and XPC) so as to have /usr/libexec/wifid to all the work.
There's more detail on this in this article: http://newosxbook.com/articles/11208ellpA.html
The Apple80211 API was removed from IPConfiguration at some point e.g. iOS 11 & 12, but came back in iOS 13 and as of today the methods are all still there and working in iOS 13.4.1. What I expect is the reason you were unable to get it working is likely since iOS 8 you need the com.apple.wlan.authentication entitlement as mentioned here.
There is currently a sneaky way to use this entitlement in apps (for your own use), but it will stop working in iOS 13.5.

Accessing certificates pushed by MDM

I wanted to know is there a way to access certificate pushed by MDM server through your app?
A few years later - is there still no way to access the MDM issued X.509 certificates?
I'm using this code, but getting zero results. And as far as google helps, there is also no way to see if there is any cert at all?
CFTypeRef certificateRef = NULL; // 1
const char *certLabelString = "XenMobile MDM";
CFStringRef certLabel = CFStringCreateWithCString(
NULL, certLabelString,
kCFStringEncodingUTF8);
const void *keys[] = { kSecClass, kSecAttrLabel, kSecReturnRef };
const void *values[] = { kSecClassCertificate, certLabel, kCFBooleanTrue };
CFDictionaryRef dict = CFDictionaryCreate(NULL, keys,
values, 3,
NULL, NULL);
status = SecItemCopyMatching(dict, &certificateRef);
if (status == errSecItemNotFound) {
_UILabelINFO.text = #"error The item cannot be found (errSecItemNotFound) :";
_UILabelINFO.text = [_UILabelINFO.text stringByAppendingString:(__bridge NSString *)(certLabel)];
} else {
_UILabelINFO.text = #"retrieved keychain reference";
}

What is the simplest way to retrieve the device serial number of an iOS device using MonoTouch?

Does MonoTouch have a simple mechanism for retrieving the device serial number (not UDID) of an iOS device? Is there a third-party library which I can use to obtain this?
In case it matters, I'm looking to use this functionality in an in-house application and am not concerned with the App Store approval process.
UPDATE: from iOS 8, we cannot retrieve the serial number of our iDevice.
To retrieve iphone serial number from Monotouch, you can use this technic:
Create a static library .a from XCode that have a function to get serial number
In MonoDevelop, create a binding project to bind you .a library into C# classes/functions (http://docs.xamarin.com/guides/ios/advanced_topics/binding_objective-c_libraries)
In your application, you call this binding library (in step 2).
For detail:
STEP 1. In my library.a, I have a class DeviceInfo, here is the implementation to get Serial number
#import "DeviceInfo.h"
#import <dlfcn.h>
#import <mach/port.h>
#import <mach/kern_return.h>
#implementation DeviceInfo
- (NSString *) serialNumber
{
NSString *serialNumber = nil;
void *IOKit = dlopen("/System/Library/Frameworks/IOKit.framework/IOKit", RTLD_NOW);
if (IOKit)
{
mach_port_t *kIOMasterPortDefault = dlsym(IOKit, "kIOMasterPortDefault");
CFMutableDictionaryRef (*IOServiceMatching)(const char *name) = dlsym(IOKit, "IOServiceMatching");
mach_port_t (*IOServiceGetMatchingService)(mach_port_t masterPort, CFDictionaryRef matching) = dlsym(IOKit, "IOServiceGetMatchingService");
CFTypeRef (*IORegistryEntryCreateCFProperty)(mach_port_t entry, CFStringRef key, CFAllocatorRef allocator, uint32_t options) = dlsym(IOKit, "IORegistryEntryCreateCFProperty");
kern_return_t (*IOObjectRelease)(mach_port_t object) = dlsym(IOKit, "IOObjectRelease");
if (kIOMasterPortDefault && IOServiceGetMatchingService && IORegistryEntryCreateCFProperty && IOObjectRelease)
{
mach_port_t platformExpertDevice = IOServiceGetMatchingService(*kIOMasterPortDefault, IOServiceMatching("IOPlatformExpertDevice"));
if (platformExpertDevice)
{
CFTypeRef platformSerialNumber = IORegistryEntryCreateCFProperty(platformExpertDevice, CFSTR("IOPlatformSerialNumber"), kCFAllocatorDefault, 0);
if (CFGetTypeID(platformSerialNumber) == CFStringGetTypeID())
{
serialNumber = [NSString stringWithString:(__bridge NSString*)platformSerialNumber];
CFRelease(platformSerialNumber);
}
IOObjectRelease(platformExpertDevice);
}
}
dlclose(IOKit);
}
return serialNumber;
}
#end
STEP 2. In ApiDefinition.cs of my Binding Library project in Monotouch, I add this binding:
[BaseType (typeof (NSObject))]
public interface DeviceInfo {
[Export ("serialNumber")]
NSString GetSerialNumber ();
}
STEP 3. In my application, I import Reference to Binding library project in step 2, then add
using MyBindingProject;
...
string serialNumber = "";
try {
DeviceInfo nativeDeviceInfo = new DeviceInfo ();
NSString temp = nativeDeviceInfo.GetSerialNumber();
serialNumber = temp.ToString();
} catch (Exception ex) {
Console.WriteLine("Cannot get serial number {0} - {1}",ex.Message, ex.StackTrace);
}
Hope that helps. Don't hesitate if you have any question.

IOS Get Proxy Settings

In my project i am using libcurl to download data over internet. The problem is that libcurl doesn't detect the proxy settings of the wifi connection.
I must set manually the settings for libcurl so i'm wondering how can a get the proxy settings of a wifi connection. I found some clues about informations in the KeyChain but i was unable to retrieve them.
Do you know if there is a way to get this settings so i can set them for libcurl ?
Thanks !
I found the response !
Using this bit of code seems to work :
std::string getProxyName()
{
CFDictionaryRef dicRef = CFNetworkCopySystemProxySettings();
const CFStringRef proxyCFstr = (const CFStringRef)CFDictionaryGetValue(dicRef, (const void*)kCFNetworkProxiesHTTPProxy);
char buffer[4096];
memset(buffer, 0, 4096);
if (CFStringGetCString(proxyCFstr, buffer, 4096, kCFStringEncodingUTF8))
{
return std::string(buffer);
}
return "";
}
int CDownloadThread::getProxyPort()
{
CFDictionaryRef dicRef = CFNetworkCopySystemProxySettings();
const CFNumberRef portCFnum = (const CFNumberRef)CFDictionaryGetValue(dicRef, (const void*)kCFNetworkProxiesHTTPPort);
SInt32 port;
if (CFNumberGetValue(portCFnum, kCFNumberSInt32Type, &port))
{
return port;
}
return -1;
}
I haven't try with automatic proxy configuration yet but i hope it's working !
It will give IP address as String.
(NSString *)proxyName
{
CFDictionaryRef dicRef = CFNetworkCopySystemProxySettings();
const CFStringRef proxyCFstr = (const CFStringRef)CFDictionaryGetValue(dicRef,
(const void*)kCFNetworkProxiesHTTPProxy);
return (__bridge NSString *)proxyCFstr;
}

Resources