summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGravatar Martin Szulecki2009-07-15 16:16:40 +0200
committerGravatar Martin Szulecki2009-07-15 16:16:40 +0200
commit654e58d4526f48d44361dcc81d6d0a1b79663b1d (patch)
tree07ca244107adb50a7d4bb0b09275cb7db7e71f4b
parenta68a82800f116706354adb97da1ef0cfd3e38a52 (diff)
downloadlibimobiledevice-654e58d4526f48d44361dcc81d6d0a1b79663b1d.tar.gz
libimobiledevice-654e58d4526f48d44361dcc81d6d0a1b79663b1d.tar.bz2
Implement lockdown set_value, remove_value and enter_recovery request API
-rw-r--r--include/libiphone/lockdown.h5
-rw-r--r--src/lockdown.c163
2 files changed, 163 insertions, 5 deletions
diff --git a/include/libiphone/lockdown.h b/include/libiphone/lockdown.h
index 805c90b..20ccf77 100644
--- a/include/libiphone/lockdown.h
+++ b/include/libiphone/lockdown.h
@@ -34,7 +34,9 @@ typedef struct lockdownd_client_int *lockdownd_client_t;
iphone_error_t lockdownd_new_client (iphone_device_t device, lockdownd_client_t *client);
iphone_error_t lockdownd_free_client(lockdownd_client_t client);
iphone_error_t lockdownd_query_type(lockdownd_client_t client);
-iphone_error_t lockdownd_get_value(lockdownd_client_t client, const char *domain, const char *key, plist_t *value_node);
+iphone_error_t lockdownd_get_value(lockdownd_client_t client, const char *domain, const char *key, plist_t *value);
+iphone_error_t lockdownd_set_value(lockdownd_client_t client, const char *domain, const char *key, plist_t value);
+iphone_error_t lockdownd_remove_value(lockdownd_client_t client, const char *domain, const char *key);
iphone_error_t lockdownd_start_service (lockdownd_client_t client, const char *service, int *port);
iphone_error_t lockdownd_stop_session(lockdownd_client_t client);
iphone_error_t lockdownd_send (lockdownd_client_t client, plist_t plist);
@@ -42,6 +44,7 @@ iphone_error_t lockdownd_recv (lockdownd_client_t client, plist_t *plist);
iphone_error_t lockdownd_pair(lockdownd_client_t client, char *uid, char *host_id);
iphone_error_t lockdownd_get_device_uid (lockdownd_client_t control, char **uid);
iphone_error_t lockdownd_get_device_name (lockdownd_client_t client, char **device_name);
+iphone_error_t lockdownd_enter_recovery(lockdownd_client_t client);
iphone_error_t lockdownd_goodbye(lockdownd_client_t client);
#ifdef __cplusplus
diff --git a/src/lockdown.c b/src/lockdown.c
index 24283cb..1a434aa 100644
--- a/src/lockdown.c
+++ b/src/lockdown.c
@@ -387,11 +387,11 @@ iphone_error_t lockdownd_query_type(lockdownd_client_t client)
* @param client an initialized lockdownd client.
* @param domain the domain to query on or NULL for global domain
* @param key the key name to request or NULL to query for all keys
- * @param value_node a plist node representing the result value node
+ * @param value a plist node representing the result value node
*
* @return an error code (IPHONE_E_SUCCESS on success)
*/
-iphone_error_t lockdownd_get_value(lockdownd_client_t client, const char *domain, const char *key, plist_t *value_node)
+iphone_error_t lockdownd_get_value(lockdownd_client_t client, const char *domain, const char *key, plist_t *value)
{
if (!client)
return IPHONE_E_INVALID_ARG;
@@ -427,7 +427,7 @@ iphone_error_t lockdownd_get_value(lockdownd_client_t client, const char *domain
return ret;
if (lockdown_check_result(dict, "GetValue") == RESULT_SUCCESS) {
- log_dbg_msg(DBGMASK_LOCKDOWND, "lockdownd_get_value(): success\n");
+ log_dbg_msg(DBGMASK_LOCKDOWND, "%s: success\n", __func__);
ret = IPHONE_E_SUCCESS;
}
if (ret != IPHONE_E_SUCCESS) {
@@ -446,7 +446,7 @@ iphone_error_t lockdownd_get_value(lockdownd_client_t client, const char *domain
if (!strcmp(result_key, "Value")) {
log_dbg_msg(DBGMASK_LOCKDOWND, "lockdownd_get_value(): has a value\n");
- *value_node = plist_copy(value_value_node);
+ *value = plist_copy(value_value_node);
}
free(result_key);
}
@@ -455,6 +455,126 @@ iphone_error_t lockdownd_get_value(lockdownd_client_t client, const char *domain
return ret;
}
+/** Sets a preferences value using a plist and optional domain and/or key name.
+ *
+ * @param client an initialized lockdownd client.
+ * @param domain the domain to query on or NULL for global domain
+ * @param key the key name to set the value or NULL to set a value dict plist
+ * @param value a plist node of any node type representing the value to set
+ *
+ * @return an error code (IPHONE_E_SUCCESS on success)
+ */
+iphone_error_t lockdownd_set_value(lockdownd_client_t client, const char *domain, const char *key, plist_t value)
+{
+ if (!client || !value)
+ return IPHONE_E_INVALID_ARG;
+
+ plist_t dict = NULL;
+ iphone_error_t ret = IPHONE_E_UNKNOWN_ERROR;
+
+ /* setup request plist */
+ dict = plist_new_dict();
+ if (domain) {
+ plist_add_sub_key_el(dict, "Domain");
+ plist_add_sub_string_el(dict, domain);
+ }
+ if (key) {
+ plist_add_sub_key_el(dict, "Key");
+ plist_add_sub_string_el(dict, key);
+ }
+ plist_add_sub_key_el(dict, "Request");
+ plist_add_sub_string_el(dict, "SetValue");
+
+ plist_add_sub_key_el(dict, "Value");
+ plist_add_sub_node(dict, value);
+
+ /* send to device */
+ ret = lockdownd_send(client, dict);
+
+ plist_free(dict);
+ dict = NULL;
+
+ if (ret != IPHONE_E_SUCCESS)
+ return ret;
+
+ /* Now get device's answer */
+ ret = lockdownd_recv(client, &dict);
+ if (ret != IPHONE_E_SUCCESS)
+ return ret;
+
+ if (lockdown_check_result(dict, "SetValue") == RESULT_SUCCESS) {
+ log_dbg_msg(DBGMASK_LOCKDOWND, "%s: success\n", __func__);
+ ret = IPHONE_E_SUCCESS;
+ }
+
+ if (ret != IPHONE_E_SUCCESS) {
+ plist_free(dict);
+ return ret;
+ }
+
+ plist_free(dict);
+ return ret;
+}
+
+/** Removes a preference node on the device by domain and/or key name
+ *
+ * @note: Use with caution as this could remove vital information on the device
+ *
+ * @param client an initialized lockdownd client.
+ * @param domain the domain to query on or NULL for global domain
+ * @param key the key name to remove or NULL remove all keys for the current domain
+ *
+ * @return an error code (IPHONE_E_SUCCESS on success)
+ */
+iphone_error_t lockdownd_remove_value(lockdownd_client_t client, const char *domain, const char *key)
+{
+ if (!client)
+ return IPHONE_E_INVALID_ARG;
+
+ plist_t dict = NULL;
+ iphone_error_t ret = IPHONE_E_UNKNOWN_ERROR;
+
+ /* setup request plist */
+ dict = plist_new_dict();
+ if (domain) {
+ plist_add_sub_key_el(dict, "Domain");
+ plist_add_sub_string_el(dict, domain);
+ }
+ if (key) {
+ plist_add_sub_key_el(dict, "Key");
+ plist_add_sub_string_el(dict, key);
+ }
+ plist_add_sub_key_el(dict, "Request");
+ plist_add_sub_string_el(dict, "RemoveValue");
+
+ /* send to device */
+ ret = lockdownd_send(client, dict);
+
+ plist_free(dict);
+ dict = NULL;
+
+ if (ret != IPHONE_E_SUCCESS)
+ return ret;
+
+ /* Now get device's answer */
+ ret = lockdownd_recv(client, &dict);
+ if (ret != IPHONE_E_SUCCESS)
+ return ret;
+
+ if (lockdown_check_result(dict, "RemoveValue") == RESULT_SUCCESS) {
+ log_dbg_msg(DBGMASK_LOCKDOWND, "%s: success\n", __func__);
+ ret = IPHONE_E_SUCCESS;
+ }
+
+ if (ret != IPHONE_E_SUCCESS) {
+ plist_free(dict);
+ return ret;
+ }
+
+ plist_free(dict);
+ return ret;
+}
+
/** Asks for the device's unique id. Part of the lockdownd handshake.
*
* @return an error code (IPHONE_E_SUCCESS on success)
@@ -672,6 +792,41 @@ iphone_error_t lockdownd_pair(lockdownd_client_t client, char *uid, char *host_i
}
/**
+ * Tells the device to immediately enter recovery mode.
+ *
+ * @param client The lockdown client
+ *
+ * @return an error code (IPHONE_E_SUCCESS on success)
+ */
+iphone_error_t lockdownd_enter_recovery(lockdownd_client_t client)
+{
+ if (!client)
+ return IPHONE_E_INVALID_ARG;
+
+ iphone_error_t ret = IPHONE_E_UNKNOWN_ERROR;
+
+ plist_t dict = plist_new_dict();
+ plist_add_sub_key_el(dict, "Request");
+ plist_add_sub_string_el(dict, "EnterRecovery");
+
+ log_dbg_msg(DBGMASK_LOCKDOWND, "%s: Telling device to enter recovery mode\n", __func__);
+
+ ret = lockdownd_send(client, dict);
+ plist_free(dict);
+ dict = NULL;
+
+ ret = lockdownd_recv(client, &dict);
+
+ if (lockdown_check_result(dict, "EnterRecovery") == RESULT_SUCCESS) {
+ log_dbg_msg(DBGMASK_LOCKDOWND, "%s: success\n", __func__);
+ ret = IPHONE_E_SUCCESS;
+ }
+ plist_free(dict);
+ dict = NULL;
+ return ret;
+}
+
+/**
* Performs the Goodbye Request to tell the device the communication
* session is now closed.
*