-
-
Notifications
You must be signed in to change notification settings - Fork 145
Description
At first, I used OpenSSL 3.5.0, and I thought it was a version issue. I compiled 3.0.13 to be consistent with my Linux platform version. The verification still failed, but the code can be used normally on the Linux platform. However, the activation function cannot be used normally on the Windows platform. Why is this? What else did I miss
`int activate_device()
{
mobileactivation_client_t ma = NULL;
idevice_activation_request_t request = NULL;
idevice_activation_response_t response = NULL;
int session_mode = 0;
plist_t p_version = NULL;
uint32_t product_version = 0;
const char *response_title = NULL;
const char *response_description = NULL;
plist_t record = NULL;
plist_dict_iter iter = NULL;
plist_t fields = NULL;
int interactive = 1;
char *field_key = NULL;
char *field_label = NULL;
char input[1024];
COREX_LOG("check product version ");
// 输出openssl版本
COREX_LOG("OpenSSL 版本: " + std::string(SSLeay_version(SSLEAY_VERSION)));
if (lockdownd_get_value(lockdownd_client, NULL, "ProductVersion", &p_version) == LOCKDOWN_E_SUCCESS)
{
int vers[3] = {0, 0, 0};
char *s_version = NULL;
plist_get_string_val(p_version, &s_version);
if (s_version && sscanf(s_version, "%d.%d.%d", &vers[0], &vers[1], &vers[2]) >= 2)
{
product_version = ((vers[0] & 0xFF) << 16) | ((vers[1] & 0xFF) << 8) | (vers[2] & 0xFF);
}
free(s_version);
}
plist_free(p_version);
if (product_version >= 0x0A0200)
{
/* The activation server will not acknowledge the activation for iOS >= 10.2 anymore. Let's warn the user about this. */
plist_t state = NULL;
lockdownd_get_value(lockdownd_client, NULL, "ActivationState", &state);
if (state)
{
char *state_str = NULL;
plist_get_string_val(state, &state_str);
if (state_str && strcmp(state_str, "Unactivated") != 0)
{
COREX_LOG("NOTE: This device appears to be already activated. The server might report an error 'Device Unknown' instead of acknowledging the activation.\n");
}
free(state_str);
plist_free(state);
}
}
else
{
COREX_LOG("Error product version not supported");
}
COREX_LOG("start mobileactivation server");
// check if we should use the new mobileactivation service
lockdownd_service_descriptor_t svc = NULL;
if (lockdownd_start_service(lockdownd_client, MOBILEACTIVATION_SERVICE_NAME, &svc) == LOCKDOWN_E_SUCCESS)
{
mobileactivation_error_t maerr = mobileactivation_client_new(device, svc, &ma);
lockdownd_service_descriptor_free(svc);
svc = NULL;
if (maerr != MOBILEACTIVATION_E_SUCCESS)
{
COREX_LOG("Failed to connect to %s\n");
return -1;
}
}
// create activation request from mobileactivation
plist_t ainfo = NULL;
if ((product_version >= 0x0A0000) || (mobileactivation_create_activation_info(ma, &ainfo) != MOBILEACTIVATION_E_SUCCESS))
{
session_mode = 1;
}
mobileactivation_client_free(ma);
ma = NULL;
if (session_mode)
{
COREX_LOG("Send request to ideviceactivation");
/* first grab session blob from device required for drmHandshake */
plist_t blob = NULL;
if (mobileactivation_client_start_service(device, &ma, "ideviceactivation") != MOBILEACTIVATION_E_SUCCESS)
{
COREX_LOG("Failed to connect to %s\n");
return -1;
}
if (mobileactivation_create_activation_session_info(ma, &blob) != MOBILEACTIVATION_E_SUCCESS)
{
COREX_LOG("Failed to get ActivationSessionInfo from mobileactivation\n");
return -1;
}
mobileactivation_client_free(ma);
ma = NULL;
/* create drmHandshake request with blob from device */
if (idevice_activation_drm_handshake_request_new(IDEVICE_ACTIVATION_CLIENT_MOBILE_ACTIVATION, &request) != IDEVICE_ACTIVATION_E_SUCCESS)
{
COREX_LOG("Failed to create drmHandshake request.\n");
return -1;
}
idevice_activation_request_set_fields(request, blob);
plist_free(blob);
// 无需设置URL
// if (signing_service_url)
// {
// idevice_activation_request_set_url(request, signing_service_url);
// }
/* send request to server and get response */
if (idevice_activation_send_request(request, &response) != IDEVICE_ACTIVATION_E_SUCCESS)
{
COREX_LOG("Failed to get drmHandshake result from activation server.\n");
return -1;
}
plist_t handshake_response = NULL;
idevice_activation_response_get_fields(response, &handshake_response);
idevice_activation_response_free(response);
response = NULL;
/* use handshake response to get activation info from device */
if (mobileactivation_client_start_service(device, &ma, "ideviceactivation") != MOBILEACTIVATION_E_SUCCESS)
{
COREX_LOG("Failed to connect to %s\n");
return -1;
}
if ((mobileactivation_create_activation_info_with_session(ma, handshake_response, &ainfo) != MOBILEACTIVATION_E_SUCCESS) || !ainfo || (plist_get_node_type(ainfo) != PLIST_DICT))
{
COREX_LOG("Failed to get ActivationInfo from mobileactivation\n");
return -1;
}
mobileactivation_client_free(ma);
ma = NULL;
}
else if (!ainfo || plist_get_node_type(ainfo) != PLIST_DICT)
{
COREX_LOG("Failed to get ActivationInfo from mobileactivation\n");
return -1;
}
/* create activation request */
if (idevice_activation_request_new(IDEVICE_ACTIVATION_CLIENT_MOBILE_ACTIVATION, &request) != IDEVICE_ACTIVATION_E_SUCCESS)
{
COREX_LOG("Failed to create activation request.");
return -1;
}
/* add activation info to request */
plist_t request_fields = plist_new_dict();
plist_dict_set_item(request_fields, "activation-info", ainfo);
plist_print(ainfo);
const char *url = NULL;
idevice_activation_request_get_url(request, &url);
COREX_LOG("activation request url: " + std::string(url ? url : ""));
idevice_activation_request_set_fields(request, request_fields);
lockdownd_client_free(lockdownd_client);
lockdownd_client = NULL;
while (1)
{
if (idevice_activation_send_request(request, &response) != IDEVICE_ACTIVATION_E_SUCCESS)
{
COREX_LOG("Failed to send request or retrieve response.");
return -1;
}
if (idevice_activation_response_has_errors(response))
{
COREX_LOG("Activation server reports errors.");
idevice_activation_response_get_title(response, &response_title);
if (response_title)
{
COREX_LOG("response_title" + std::string("\t") + response_title);
}
idevice_activation_response_get_description(response, &response_description);
if (response_description)
{
COREX_LOG("response_description" + std::string("\t") + response_description);
}
return -1;
}
idevice_activation_response_get_activation_record(response, &record);
if (record)
{
if (LOCKDOWN_E_SUCCESS != lockdownd_client_new_with_handshake(device, &lockdownd_client, "ideviceactivation"))
{
COREX_LOG("Failed to connect to lockdownd");
return -1;
}
// use_mobileactivation 模式
if (true)
{
svc = NULL;
if (lockdownd_start_service(lockdownd_client, MOBILEACTIVATION_SERVICE_NAME, &svc) != LOCKDOWN_E_SUCCESS)
{
COREX_LOG(std::string("Failed to start service ") + MOBILEACTIVATION_SERVICE_NAME);
return -1;
}
mobileactivation_error_t maerr = mobileactivation_client_new(device, svc, &ma);
lockdownd_service_descriptor_free(svc);
svc = NULL;
if (maerr != MOBILEACTIVATION_E_SUCCESS)
{
COREX_LOG(std::string("Failed to connect to ") + MOBILEACTIVATION_SERVICE_NAME);
return -1;
}
if (session_mode)
{
plist_t headers = NULL;
idevice_activation_response_get_headers(response, &headers);
if (MOBILEACTIVATION_E_SUCCESS != mobileactivation_activate_with_session(ma, record, headers))
{
plist_free(headers);
COREX_LOG("Failed to activate device with record.");
return -1;
}
plist_free(headers);
}
else
{
if (MOBILEACTIVATION_E_SUCCESS != mobileactivation_activate(ma, record))
{
COREX_LOG("Failed to activate device with record.");
return -1;
}
}
}
else
{
// activate device using lockdown
if (LOCKDOWN_E_SUCCESS != lockdownd_activate(lockdownd_client, record))
{
plist_t state = NULL;
lockdownd_get_value(lockdownd_client, NULL, "ActivationState", &state);
int success = 0;
if (state && plist_get_node_type(state) == PLIST_STRING)
{
char *strval = NULL;
plist_get_string_val(state, &strval);
if (strval && strcmp(strval, "Unactivated"))
{
success = 1;
}
free(strval);
}
if (!success)
{
COREX_LOG("Failed to activate device with record.");
return -1;
}
}
}
// set ActivationStateAcknowledged if we succeeded
if (LOCKDOWN_E_SUCCESS != lockdownd_set_value(lockdownd_client, NULL, "ActivationStateAcknowledged", plist_new_bool(1)))
{
COREX_LOG("Failed to set ActivationStateAcknowledged on device.");
return -1;
}
break;
}
else
{
if (idevice_activation_response_is_activation_acknowledged(response))
{
COREX_LOG("Activation server reports that device is already activated.");
return -1;
}
idevice_activation_response_get_title(response, &response_title);
if (response_title)
{
COREX_LOG(std::string("Server reports: ") + response_title);
}
idevice_activation_response_get_description(response, &response_description);
if (response_description)
{
COREX_LOG(std::string("Server reports: ") + response_description);
}
idevice_activation_response_get_fields(response, &fields);
if (!fields || plist_dict_get_size(fields) == 0)
{
COREX_LOG("Unknown error.");
return -1;
}
plist_dict_new_iter(fields, &iter);
if (!iter)
{
COREX_LOG("Unknown error.");
return -1;
}
idevice_activation_request_free(request);
request = NULL;
if (idevice_activation_request_new(
IDEVICE_ACTIVATION_CLIENT_MOBILE_ACTIVATION, &request) != IDEVICE_ACTIVATION_E_SUCCESS)
{
COREX_LOG("Could not create new request.");
return -1;
}
idevice_activation_request_set_fields_from_response(request, response);
int interactive_count = 0;
do
{
field_key = NULL;
plist_dict_next_item(fields, iter, &field_key, NULL);
if (field_key)
{
if (idevice_activation_response_field_requires_input(response, field_key))
{
idevice_activation_response_get_label(response, field_key, &field_label);
if (interactive)
{
char *field_placeholder = NULL;
int secure = idevice_activation_response_field_secure_input(response, field_key);
idevice_activation_response_get_placeholder(response, field_key, &field_placeholder);
// 保持输入提示用printf
printf("input %s", field_label ? field_label : field_key);
if (field_placeholder)
{
printf(" (%s)", field_placeholder);
free(field_placeholder);
}
printf(": ");
fflush(stdout);
fflush(stdin);
get_user_input(input, 1023, secure);
}
else
{
COREX_LOG(std::string("Server requires input for '") + (field_label ? field_label : field_key) + "' but we're not running interactively.");
strcpy(input, "");
interactive_count++;
}
idevice_activation_request_set_field(request, field_key, input);
if (field_label)
{
free(field_label);
field_label = NULL;
}
}
}
} while (field_key);
free(iter);
iter = NULL;
idevice_activation_response_free(response);
response = NULL;
if (interactive_count > 0 && !interactive)
{
COREX_LOG("Failed to activate device.");
return -1;
}
}
}
COREX_LOG("Successfully activated device.");
return 0;
}`