mobileactivation: Allow passing activation response headers as required for iOS 11.2+

When activating in session mode - which is required for newer iOS versions -
we can now pass the activation response headers with the activation command.
For iOS 11.2+ this is mandatory or the activation will fail.
diff --git a/include/libimobiledevice/mobileactivation.h b/include/libimobiledevice/mobileactivation.h
index bb1f3f4..b7f8064 100644
--- a/include/libimobiledevice/mobileactivation.h
+++ b/include/libimobiledevice/mobileactivation.h
@@ -164,16 +164,18 @@
 
 /**
  * Activates the device with the given activation record in 'session' mode.
- * The activation record plist dictionary must be obtained using the
+ * The activation record plist must be obtained using the
  * activation protocol requesting from Apple's https webservice.
  *
  * @param client The mobileactivation client
- * @param activation_record The activation record plist dictionary
+ * @param activation_record The activation record in plist format
+ * @param headers A plist dictionary with the activation response headers
+ *     as returned from Apple's https webservice with the activation record
  *
  * @return MOBILEACTIVATION_E_SUCCESS on success, or an MOBILEACTIVATION_E_*
  *     error code otherwise.
  */
-mobileactivation_error_t mobileactivation_activate_with_session(mobileactivation_client_t client, plist_t activation_record);
+mobileactivation_error_t mobileactivation_activate_with_session(mobileactivation_client_t client, plist_t activation_record, plist_t headers);
 
 /**
  * Deactivates the device.
diff --git a/src/mobileactivation.c b/src/mobileactivation.c
index 433497a..010484e 100644
--- a/src/mobileactivation.c
+++ b/src/mobileactivation.c
@@ -124,6 +124,38 @@
 	return ret;
 }
 
+static mobileactivation_error_t mobileactivation_send_command_plist(mobileactivation_client_t client, plist_t command, plist_t *result)
+{
+	if (!client || !command)
+		return MOBILEACTIVATION_E_INVALID_ARG;
+
+	plist_t cmd = plist_dict_get_item(command, "Command");
+	char* command_str = NULL;
+	if (cmd) {
+		plist_get_string_val(cmd, &command_str);
+	}
+	if (!command_str)
+		return MOBILEACTIVATION_E_INVALID_ARG;
+
+	mobileactivation_error_t ret = MOBILEACTIVATION_E_UNKNOWN_ERROR;
+	*result = NULL;
+
+	ret = mobileactivation_error(property_list_service_send_binary_plist(client->parent, command));
+
+	plist_t dict = NULL;
+	ret = mobileactivation_error(property_list_service_receive_plist(client->parent, &dict));
+	if (!dict) {
+		debug_info("ERROR: Did not get reply for %s command", command_str);
+		free(command_str);
+		return MOBILEACTIVATION_E_PLIST_ERROR;
+	}
+
+	*result = dict;
+	ret = mobileactivation_check_result(dict, command_str);
+	free(command_str);
+	return ret;
+}
+
 static mobileactivation_error_t mobileactivation_send_command(mobileactivation_client_t client, const char* command, plist_t value, plist_t *result)
 {
 	if (!client || !command || !result)
@@ -138,18 +170,9 @@
 		plist_dict_set_item(dict, "Value", plist_copy(value));
 	}
 
-	ret = mobileactivation_error(property_list_service_send_binary_plist(client->parent, dict));
+	ret = mobileactivation_send_command_plist(client, dict, result);
 	plist_free(dict);
-	dict = NULL;
-
-	ret = mobileactivation_error(property_list_service_receive_plist(client->parent, &dict));
-	if (!dict) {
-		debug_info("ERROR: Did not get reply for %s command", command);
-		return MOBILEACTIVATION_E_PLIST_ERROR;
-	}
-
-	*result = dict;
-	return mobileactivation_check_result(dict, command);
+	return ret;
 }
 
 LIBIMOBILEDEVICE_API mobileactivation_error_t mobileactivation_get_activation_state(mobileactivation_client_t client, plist_t *state)
@@ -253,15 +276,22 @@
 	return ret;
 }
 
-LIBIMOBILEDEVICE_API mobileactivation_error_t mobileactivation_activate_with_session(mobileactivation_client_t client, plist_t activation_record)
+LIBIMOBILEDEVICE_API mobileactivation_error_t mobileactivation_activate_with_session(mobileactivation_client_t client, plist_t activation_record, plist_t headers)
 {
 	if (!client || !activation_record)
 		return MOBILEACTIVATION_E_INVALID_ARG;
 
 	plist_t result = NULL;
-	plist_t data = plist_data_from_plist(activation_record);
-	mobileactivation_error_t ret = mobileactivation_send_command(client, "HandleActivationInfoWithSessionRequest", data, &result);
-	plist_free(data);
+
+	plist_t dict = plist_new_dict();
+	plist_dict_set_item(dict, "Command", plist_new_string("HandleActivationInfoWithSessionRequest"));
+	plist_dict_set_item(dict, "Value", plist_data_from_plist(activation_record));
+	if (headers) {
+		plist_dict_set_item(dict, "ActivationResponseHeaders", plist_copy(headers));
+	}
+
+	mobileactivation_error_t ret = mobileactivation_send_command_plist(client, dict, &result);
+	plist_free(dict);
 	plist_free(result);
 	result = NULL;