summaryrefslogtreecommitdiffstats
path: root/src/lockdown.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/lockdown.c')
-rw-r--r--src/lockdown.c247
1 files changed, 168 insertions, 79 deletions
diff --git a/src/lockdown.c b/src/lockdown.c
index 25a6c6a..515c58e 100644
--- a/src/lockdown.c
+++ b/src/lockdown.c
@@ -1,6 +1,6 @@
/*
* lockdown.c
- * libimobiledevice built-in lockdownd client
+ * com.apple.mobile.lockdownd service implementation.
*
* Copyright (c) 2008 Zach C. All Rights Reserved.
*
@@ -124,15 +124,14 @@ static void plist_dict_add_label(plist_t plist, const char *label)
}
/**
- * Closes the lockdownd communication session, by sending the StopSession
- * Request to the device.
+ * Closes the lockdownd session by sending the StopSession request.
*
* @see lockdownd_start_session
*
- * @param control The lockdown client
+ * @param client The lockdown client
* @param session_id The id of a running session
*
- * @return an error code (LOCKDOWN_E_SUCCESS on success)
+ * @return LOCKDOWN_E_SUCCESS on success, NP_E_INVALID_ARG when client is NULL
*/
lockdownd_error_t lockdownd_stop_session(lockdownd_client_t client, const char *session_id)
{
@@ -178,11 +177,13 @@ lockdownd_error_t lockdownd_stop_session(lockdownd_client_t client, const char *
return ret;
}
-/** Closes the lockdownd client and does the necessary housekeeping.
+/**
+ * Closes the lockdownd client session if one is running and frees up the
+ * lockdownd_client struct.
*
* @param client The lockdown client
*
- * @return an error code (LOCKDOWN_E_SUCCESS on success)
+ * @return LOCKDOWN_E_SUCCESS on success, NP_E_INVALID_ARG when client is NULL
*/
lockdownd_error_t lockdownd_client_free(lockdownd_client_t client)
{
@@ -229,12 +230,14 @@ void lockdownd_client_set_label(lockdownd_client_t client, const char *label)
}
}
-/** Polls the device for lockdownd data.
+/**
+ * Receives a plist from lockdownd.
*
- * @param control The lockdownd client
+ * @param client The lockdownd client
* @param plist The plist to store the received data
*
- * @return an error code (LOCKDOWN_E_SUCCESS on success)
+ * @return LOCKDOWN_E_SUCCESS on success, NP_E_INVALID_ARG when client or
+ * plist is NULL
*/
lockdownd_error_t lockdownd_receive(lockdownd_client_t client, plist_t *plist)
{
@@ -254,7 +257,8 @@ lockdownd_error_t lockdownd_receive(lockdownd_client_t client, plist_t *plist)
return ret;
}
-/** Sends lockdownd data to the device
+/**
+ * Sends a plist to lockdownd.
*
* @note This function is low-level and should only be used if you need to send
* a new type of message.
@@ -262,7 +266,8 @@ lockdownd_error_t lockdownd_receive(lockdownd_client_t client, plist_t *plist)
* @param client The lockdownd client
* @param plist The plist to send
*
- * @return an error code (LOCKDOWN_E_SUCCESS on success)
+ * @return LOCKDOWN_E_SUCCESS on success, NP_E_INVALID_ARG when client or
+ * plist is NULL
*/
lockdownd_error_t lockdownd_send(lockdownd_client_t client, plist_t plist)
{
@@ -279,13 +284,14 @@ lockdownd_error_t lockdownd_send(lockdownd_client_t client, plist_t plist)
return ret;
}
-/** Query the type of the service daemon. Depending on whether the device is
+/**
+ * Query the type of the service daemon. Depending on whether the device is
* queried in normal mode or restore mode, different types will be returned.
*
* @param client The lockdownd client
- * @param type The type returned by the service daemon. Can be NULL to ignore.
+ * @param type The type returned by the service daemon. Pass NULL to ignore.
*
- * @return an error code (LOCKDOWN_E_SUCCESS on success)
+ * @return LOCKDOWN_E_SUCCESS on success, NP_E_INVALID_ARG when client is NULL
*/
lockdownd_error_t lockdownd_query_type(lockdownd_client_t client, char **type)
{
@@ -325,14 +331,15 @@ lockdownd_error_t lockdownd_query_type(lockdownd_client_t client, char **type)
return ret;
}
-/** Retrieves a preferences plist using an optional domain and/or key name.
+/**
+ * Retrieves a preferences plist using an 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 request or NULL to query for all keys
- * @param value a plist node representing the result value node
+ * @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 A plist node representing the result value node
*
- * @return an error code (LOCKDOWN_E_SUCCESS on success)
+ * @return LOCKDOWN_E_SUCCESS on success, NP_E_INVALID_ARG when client is NULL
*/
lockdownd_error_t lockdownd_get_value(lockdownd_client_t client, const char *domain, const char *key, plist_t *value)
{
@@ -387,14 +394,16 @@ lockdownd_error_t lockdownd_get_value(lockdownd_client_t client, const char *dom
return ret;
}
-/** Sets a preferences value using a plist and optional domain and/or key name.
+/**
+ * Sets a preferences value using a plist and optional by 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 (LOCKDOWN_E_SUCCESS on success)
+ * @return LOCKDOWN_E_SUCCESS on success, NP_E_INVALID_ARG when client or
+ * value is NULL
*/
lockdownd_error_t lockdownd_set_value(lockdownd_client_t client, const char *domain, const char *key, plist_t value)
{
@@ -444,15 +453,16 @@ lockdownd_error_t lockdownd_set_value(lockdownd_client_t client, const char *dom
return ret;
}
-/** Removes a preference node on the device by domain and/or key name
+/**
+ * Removes a preference node 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
+ * @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 (LOCKDOWN_E_SUCCESS on success)
+ * @return LOCKDOWN_E_SUCCESS on success, NP_E_INVALID_ARG when client is NULL
*/
lockdownd_error_t lockdownd_remove_value(lockdownd_client_t client, const char *domain, const char *key)
{
@@ -501,9 +511,14 @@ lockdownd_error_t lockdownd_remove_value(lockdownd_client_t client, const char *
return ret;
}
-/** Asks for the device's unique id. Part of the lockdownd handshake.
+/**
+ * Returns the unique id of the device from lockdownd.
*
- * @return an error code (LOCKDOWN_E_SUCCESS on success)
+ * @param client An initialized lockdownd client.
+ * @param uuid Holds the unique id of the device. The caller is responsible
+ * for freeing the memory.
+ *
+ * @return LOCKDOWN_E_SUCCESS on success
*/
lockdownd_error_t lockdownd_get_device_uuid(lockdownd_client_t client, char **uuid)
{
@@ -521,9 +536,14 @@ lockdownd_error_t lockdownd_get_device_uuid(lockdownd_client_t client, char **uu
return ret;
}
-/** Askes for the device's public key. Part of the lockdownd handshake.
+/**
+ * Retrieves the public key of the device from lockdownd.
*
- * @return an error code (LOCKDOWN_E_SUCCESS on success)
+ * @param client An initialized lockdownd client.
+ * @param public_key Holds the public key of the device. The caller is
+ * responsible for freeing the memory.
+ *
+ * @return LOCKDOWN_E_SUCCESS on success
*/
lockdownd_error_t lockdownd_get_device_public_key(lockdownd_client_t client, gnutls_datum_t * public_key)
{
@@ -546,12 +566,14 @@ lockdownd_error_t lockdownd_get_device_public_key(lockdownd_client_t client, gnu
return ret;
}
-/** Askes for the device's name.
- *
- * @param client The pointer to the location of the new lockdownd_client
+/**
+ * Retrieves the name of the device from lockdownd set by the user.
*
+ * @param client An initialized lockdownd client.
+ * @param device_name Holds the name of the device. The caller is
+ * responsible for freeing the memory.
*
- * @return an error code (LOCKDOWN_E_SUCCESS on success)
+ * @return LOCKDOWN_E_SUCCESS on success
*/
lockdownd_error_t lockdownd_get_device_name(lockdownd_client_t client, char **device_name)
{
@@ -570,13 +592,17 @@ lockdownd_error_t lockdownd_get_device_name(lockdownd_client_t client, char **de
return ret;
}
-/** Creates a lockdownd client for the device.
+/**
+ * Creates a new lockdownd client for the device.
*
- * @param phone The device to create a lockdownd client for
+ * @note This function does not pair with the device or start a session. This
+ * has to be done manually by the caller after the client is created.
+ *
+ * @param device The device to create a lockdownd client for
* @param client The pointer to the location of the new lockdownd_client
- * @param label The label to use for communication. Usually the program name
+ * @param label The label to use for communication. Usually the program name.
*
- * @return an error code (LOCKDOWN_E_SUCCESS on success)
+ * @return LOCKDOWN_E_SUCCESS on success, NP_E_INVALID_ARG when client is NULL
*/
lockdownd_error_t lockdownd_client_new(idevice_t device, lockdownd_client_t *client, const char *label)
{
@@ -609,15 +635,18 @@ lockdownd_error_t lockdownd_client_new(idevice_t device, lockdownd_client_t *cli
return ret;
}
-/** Creates a lockdownd client for the device and starts initial handshake.
- * The handshake consists of query_type, validate_pair, pair and
- * start_session calls.
+/**
+ * Creates a new lockdownd client for the device and starts initial handshake.
+ * The handshake consists out of query_type, validate_pair, pair and
+ * start_session calls. It uses the internal pairing record management.
*
- * @param phone The device to create a lockdownd client for
+ * @param device The device to create a lockdownd client for
* @param client The pointer to the location of the new lockdownd_client
- * @param label The label to use for communication. Usually the program name
+ * @param label The label to use for communication. Usually the program name.
+ * Pass NULL to disable sending the label in requests to lockdownd.
*
- * @return an error code (LOCKDOWN_E_SUCCESS on success)
+ * @return LOCKDOWN_E_SUCCESS on success, NP_E_INVALID_ARG when client is NULL,
+ * LOCKDOWN_E_INVALID_CONF if configuration data is wrong
*/
lockdownd_error_t lockdownd_client_new_with_handshake(idevice_t device, lockdownd_client_t *client, const char *label)
{
@@ -690,6 +719,14 @@ lockdownd_error_t lockdownd_client_new_with_handshake(idevice_t device, lockdown
return ret;
}
+/**
+ * Returns a new plist from the supplied lockdownd pair record. The caller is
+ * responsible for freeing the plist.
+ *
+ * @param pair_record The pair record to create a plist from.
+ *
+ * @return A pair record plist from the device, NULL if pair_record is not set
+ */
static plist_t lockdownd_pair_record_to_plist(lockdownd_pair_record_t pair_record)
{
if (!pair_record)
@@ -712,6 +749,17 @@ static plist_t lockdownd_pair_record_to_plist(lockdownd_pair_record_t pair_recor
return dict;
}
+/**
+ * Generates a new pairing record plist and required certificates for the
+ * supplied public key of the device and the host_id of the caller's host
+ * computer.
+ *
+ * @param public_key The public key of the device.
+ * @param host_id The HostID to use for the pair record plist.
+ * @param pair_record_plist Holds the generated pair record.
+ *
+ * @return LOCKDOWN_E_SUCCESS on success
+ */
static lockdownd_error_t generate_pair_record_plist(gnutls_datum_t public_key, char *host_id, plist_t *pair_record_plist)
{
lockdownd_error_t ret = LOCKDOWN_E_UNKNOWN_ERROR;
@@ -743,7 +791,8 @@ static lockdownd_error_t generate_pair_record_plist(gnutls_datum_t public_key, c
return ret;
}
-/** Function used internally by lockdownd_pair() and lockdownd_validate_pair()
+/**
+ * Function used internally by lockdownd_pair() and lockdownd_validate_pair()
*
* @param client The lockdown client to pair with.
* @param pair_record The pair record to use for pairing. If NULL is passed, then
@@ -751,10 +800,17 @@ static lockdownd_error_t generate_pair_record_plist(gnutls_datum_t public_key, c
* generated automatically when pairing is done for the first time.
* @param verb This is either "Pair", "ValidatePair" or "Unpair".
*
- * @return an error code (LOCKDOWN_E_SUCCESS on success)
+ * @return LOCKDOWN_E_SUCCESS on success, NP_E_INVALID_ARG when client is NULL,
+ * LOCKDOWN_E_PLIST_ERROR if the pair_record certificates are wrong,
+ * LOCKDOWN_E_PAIRING_FAILED if the pairing failed,
+ * LOCKDOWN_E_PASSWORD_PROTECTED if the device is password protected,
+ * LOCKDOWN_E_INVALID_HOST_ID if the device does not know the caller's host id
*/
static lockdownd_error_t lockdownd_do_pair(lockdownd_client_t client, lockdownd_pair_record_t pair_record, const char *verb)
{
+ if (!client)
+ return LOCKDOWN_E_INVALID_ARG;
+
lockdownd_error_t ret = LOCKDOWN_E_UNKNOWN_ERROR;
plist_t dict = NULL;
plist_t dict_record = NULL;
@@ -855,15 +911,18 @@ static lockdownd_error_t lockdownd_do_pair(lockdownd_client_t client, lockdownd_
}
/**
- * Pairs the device with the given HostID.
- * It's part of the lockdownd handshake.
+ * Pairs the device using the supplied pair record.
*
* @param client The lockdown client to pair with.
* @param pair_record The pair record to use for pairing. If NULL is passed, then
* the pair records from the current machine are used. New records will be
* generated automatically when pairing is done for the first time.
*
- * @return an error code (LOCKDOWN_E_SUCCESS on success)
+ * @return LOCKDOWN_E_SUCCESS on success, NP_E_INVALID_ARG when client is NULL,
+ * LOCKDOWN_E_PLIST_ERROR if the pair_record certificates are wrong,
+ * LOCKDOWN_E_PAIRING_FAILED if the pairing failed,
+ * LOCKDOWN_E_PASSWORD_PROTECTED if the device is password protected,
+ * LOCKDOWN_E_INVALID_HOST_ID if the device does not know the caller's host id
*/
lockdownd_error_t lockdownd_pair(lockdownd_client_t client, lockdownd_pair_record_t pair_record)
{
@@ -871,17 +930,21 @@ lockdownd_error_t lockdownd_pair(lockdownd_client_t client, lockdownd_pair_recor
}
/**
- * Pairs the device with the given HostID. The difference to lockdownd_pair()
- * is that the specified host will become trusted host of the device.
- * It's part of the lockdownd handshake.
+ * Validates if the device is paired with the given HostID. If succeeded them
+ * specified host will become trusted host of the device indicated by the
+ * lockdownd preference named TrustedHostAttached. Otherwise the host must because
+ * paired using lockdownd_pair() first.
*
* @param client The lockdown client to pair with.
* @param pair_record The pair record to validate pairing with. If NULL is
- * passed, then the pair records from the current machine are used.
- * New records will be generated automatically when pairing is done
- * for the first time.
+ * passed, then the pair record is read from the internal pairing record
+ * management.
*
- * @return an error code (LOCKDOWN_E_SUCCESS on success)
+ * @return LOCKDOWN_E_SUCCESS on success, NP_E_INVALID_ARG when client is NULL,
+ * LOCKDOWN_E_PLIST_ERROR if the pair_record certificates are wrong,
+ * LOCKDOWN_E_PAIRING_FAILED if the pairing failed,
+ * LOCKDOWN_E_PASSWORD_PROTECTED if the device is password protected,
+ * LOCKDOWN_E_INVALID_HOST_ID if the device does not know the caller's host id
*/
lockdownd_error_t lockdownd_validate_pair(lockdownd_client_t client, lockdownd_pair_record_t pair_record)
{
@@ -890,13 +953,17 @@ lockdownd_error_t lockdownd_validate_pair(lockdownd_client_t client, lockdownd_p
/**
* Unpairs the device with the given HostID and removes the pairing records
- * from the device and host.
+ * from the device and host if the internal pairing record management is used.
*
* @param client The lockdown client to pair with.
* @param pair_record The pair record to use for unpair. If NULL is passed, then
* the pair records from the current machine are used.
*
- * @return an error code (LOCKDOWN_E_SUCCESS on success)
+ * @return LOCKDOWN_E_SUCCESS on success, NP_E_INVALID_ARG when client is NULL,
+ * LOCKDOWN_E_PLIST_ERROR if the pair_record certificates are wrong,
+ * LOCKDOWN_E_PAIRING_FAILED if the pairing failed,
+ * LOCKDOWN_E_PASSWORD_PROTECTED if the device is password protected,
+ * LOCKDOWN_E_INVALID_HOST_ID if the device does not know the caller's host id
*/
lockdownd_error_t lockdownd_unpair(lockdownd_client_t client, lockdownd_pair_record_t pair_record)
{
@@ -908,7 +975,7 @@ lockdownd_error_t lockdownd_unpair(lockdownd_client_t client, lockdownd_pair_rec
*
* @param client The lockdown client
*
- * @return an error code (LOCKDOWN_E_SUCCESS on success)
+ * @return LOCKDOWN_E_SUCCESS on success, NP_E_INVALID_ARG when client is NULL
*/
lockdownd_error_t lockdownd_enter_recovery(lockdownd_client_t client)
{
@@ -939,12 +1006,12 @@ lockdownd_error_t lockdownd_enter_recovery(lockdownd_client_t client)
}
/**
- * Performs the Goodbye Request to tell the device the communication
- * session is now closed.
+ * Sends the Goodbye request to lockdownd signaling the end of communication.
*
* @param client The lockdown client
*
- * @return an error code (LOCKDOWN_E_SUCCESS on success)
+ * @return LOCKDOWN_E_SUCCESS on success, NP_E_INVALID_ARG when client is NULL,
+ * LOCKDOWN_E_PLIST_ERROR if the device did not acknowledge the request
*/
lockdownd_error_t lockdownd_goodbye(lockdownd_client_t client)
{
@@ -978,10 +1045,18 @@ lockdownd_error_t lockdownd_goodbye(lockdownd_client_t client)
return ret;
}
-/** Generates the device certificate from the public key as well as the host
- * and root certificates.
+/**
+ * Generates the device certificate from the public key as well as the host
+ * and root certificates.
*
- * @return an error code (LOCKDOWN_E_SUCCESS on success)
+ * @param public_key The public key of the device to use for generation.
+ * @param odevice_cert Holds the generated device certificate.
+ * @param ohost_cert Holds the generated host certificate.
+ * @param oroot_cert Holds the generated root certificate.
+ *
+ * @return LOCKDOWN_E_SUCCESS on success, NP_E_INVALID_ARG when a parameter is NULL,
+ * LOCKDOWN_E_INVALID_CONF if the internal configuration system failed,
+ * LOCKDOWN_E_SSL_ERROR if the certificates could not be generated
*/
lockdownd_error_t lockdownd_gen_pair_cert(gnutls_datum_t public_key, gnutls_datum_t * odevice_cert,
gnutls_datum_t * ohost_cert, gnutls_datum_t * oroot_cert)
@@ -1116,15 +1191,18 @@ lockdownd_error_t lockdownd_gen_pair_cert(gnutls_datum_t public_key, gnutls_datu
return ret;
}
-/** Starts communication with lockdownd after the device has been paired,
- * and if the device requires it, switches to SSL mode.
+/**
+ * Opens a session with lockdownd and switches to SSL mode if device wants it.
*
* @param client The lockdownd client
* @param host_id The HostID of the computer
- * @param session_id The session_id of the created session
+ * @param session_id The new session_id of the created session
* @param ssl_enabled Whether SSL communication is used in the session
*
- * @return an error code (LOCKDOWN_E_SUCCESS on success)
+ * @return LOCKDOWN_E_SUCCESS on success, NP_E_INVALID_ARG when a client or
+ * host_id is NULL, LOCKDOWN_E_PLIST_ERROR if the response plist had errors,
+ * LOCKDOWN_E_INVALID_HOST_ID if the device does not know the supplied HostID,
+ * LOCKDOWN_E_SSL_ERROR if enabling SSL communication failed
*/
lockdownd_error_t lockdownd_start_session(lockdownd_client_t client, const char *host_id, char **session_id, int *ssl_enabled)
{
@@ -1212,13 +1290,17 @@ lockdownd_error_t lockdownd_start_session(lockdownd_client_t client, const char
return ret;
}
-/** Command to start the desired service
+/**
+ * Requests to start a service and retrieve it's port on success.
*
* @param client The lockdownd client
* @param service The name of the service to start
* @param port The port number the service was started on
- * @return an error code (LOCKDOWN_E_SUCCESS on success)
+ * @return LOCKDOWN_E_SUCCESS on success, NP_E_INVALID_ARG if a parameter
+ * is NULL, LOCKDOWN_E_INVALID_SERVICE if the requested service is not known
+ * by the device, LOCKDOWN_E_START_SERVICE_FAILED if the service could not because
+ * started by the device
*/
lockdownd_error_t lockdownd_start_service(lockdownd_client_t client, const char *service, uint16_t *port)
{
@@ -1300,10 +1382,15 @@ lockdownd_error_t lockdownd_start_service(lockdownd_client_t client, const char
*
* @see http://iphone-docs.org/doku.php?id=docs:protocols:activation
*
- * @param control The lockdown client
+ * @param client The lockdown client
* @param activation_record The activation record plist dictionary
*
- * @return an error code (LOCKDOWN_E_SUCCESS on success)
+ * @return LOCKDOWN_E_SUCCESS on success, NP_E_INVALID_ARG when client or
+ * activation_record is NULL, LOCKDOWN_E_NO_RUNNING_SESSION if no session is
+ * open, LOCKDOWN_E_PLIST_ERROR if the received plist is broken,
+ * LOCKDOWN_E_ACTIVATION_FAILED if the activation failed,
+ * LOCKDOWN_E_INVALID_ACTIVATION_RECORD if the device reports that the
+ * activation_record is invalid
*/
lockdownd_error_t lockdownd_activate(lockdownd_client_t client, plist_t activation_record)
{
@@ -1357,12 +1444,14 @@ lockdownd_error_t lockdownd_activate(lockdownd_client_t client, plist_t activati
}
/**
- * Deactivates the device, returning it to the locked
- * “Activate with iTunes” screen.
+ * Deactivates the device, returning it to the locked “Activate with iTunes”
+ * screen.
*
- * @param control The lockdown client
+ * @param client The lockdown client
*
- * @return an error code (LOCKDOWN_E_SUCCESS on success)
+ * @return LOCKDOWN_E_SUCCESS on success, NP_E_INVALID_ARG when client is NULL,
+ * LOCKDOWN_E_NO_RUNNING_SESSION if no session is open,
+ * LOCKDOWN_E_PLIST_ERROR if the received plist is broken
*/
lockdownd_error_t lockdownd_deactivate(lockdownd_client_t client)
{