diff options
| -rw-r--r-- | include/libiphone/lockdown.h | 13 | ||||
| -rw-r--r-- | src/lockdown.c | 434 | ||||
| -rw-r--r-- | src/lockdown.h | 6 | 
3 files changed, 227 insertions, 226 deletions
| diff --git a/include/libiphone/lockdown.h b/include/libiphone/lockdown.h index e134f5f..f4b3f6a 100644 --- a/include/libiphone/lockdown.h +++ b/include/libiphone/lockdown.h @@ -47,6 +47,7 @@ extern "C" {  #define LOCKDOWN_E_ACTIVATION_FAILED        -13  #define LOCKDOWN_E_PASSWORD_PROTECTED       -14  #define LOCKDOWN_E_NO_RUNNING_SESSION       -15 +#define LOCKDOWN_E_INVALID_HOST_ID          -16  #define LOCKDOWN_E_UNKNOWN_ERROR           -256 @@ -59,13 +60,14 @@ typedef struct lockdownd_client_int *lockdownd_client_t;  lockdownd_error_t lockdownd_client_new(iphone_device_t device, lockdownd_client_t *client, const char *label);  lockdownd_error_t lockdownd_client_new_with_handshake(iphone_device_t device, lockdownd_client_t *client, const char *label);  lockdownd_error_t lockdownd_client_free(lockdownd_client_t client); -void lockdownd_client_set_label(lockdownd_client_t client, const char *label); +  lockdownd_error_t lockdownd_query_type(lockdownd_client_t client, char **type);  lockdownd_error_t lockdownd_get_value(lockdownd_client_t client, const char *domain, const char *key, plist_t *value);  lockdownd_error_t lockdownd_set_value(lockdownd_client_t client, const char *domain, const char *key, plist_t value);  lockdownd_error_t lockdownd_remove_value(lockdownd_client_t client, const char *domain, const char *key);  lockdownd_error_t lockdownd_start_service(lockdownd_client_t client, const char *service, int *port); -lockdownd_error_t lockdownd_stop_session(lockdownd_client_t client); +lockdownd_error_t lockdownd_start_session(lockdownd_client_t client, const char *host_id, char **session_id, int *ssl_enabled); +lockdownd_error_t lockdownd_stop_session(lockdownd_client_t client, const char *session_id);  lockdownd_error_t lockdownd_send(lockdownd_client_t client, plist_t plist);  lockdownd_error_t lockdownd_recv(lockdownd_client_t client, plist_t *plist);  lockdownd_error_t lockdownd_pair(lockdownd_client_t client, char *host_id); @@ -73,11 +75,14 @@ lockdownd_error_t lockdownd_validate_pair(lockdownd_client_t client, char *host_  lockdownd_error_t lockdownd_unpair(lockdownd_client_t client, char *host_id);  lockdownd_error_t lockdownd_activate(lockdownd_client_t client, plist_t activation_record);  lockdownd_error_t lockdownd_deactivate(lockdownd_client_t client); -lockdownd_error_t lockdownd_get_device_uuid(lockdownd_client_t control, char **uuid); -lockdownd_error_t lockdownd_get_device_name(lockdownd_client_t client, char **device_name);  lockdownd_error_t lockdownd_enter_recovery(lockdownd_client_t client);  lockdownd_error_t lockdownd_goodbye(lockdownd_client_t client); +/* Helper */ +void lockdownd_client_set_label(lockdownd_client_t client, const char *label); +lockdownd_error_t lockdownd_get_device_uuid(lockdownd_client_t control, char **uuid); +lockdownd_error_t lockdownd_get_device_name(lockdownd_client_t client, char **device_name); +  #ifdef __cplusplus  }  #endif diff --git a/src/lockdown.c b/src/lockdown.c index 11b4fe6..f78fbb4 100644 --- a/src/lockdown.c +++ b/src/lockdown.c @@ -123,69 +123,145 @@ 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. +/** gnutls callback for writing data to the device.   * - * @param control The lockdown client + * @param transport It's really the lockdownd client, but the method signature has to match + * @param buffer The data to send + * @param length The length of data to send in bytes   * - * @return an error code (LOCKDOWN_E_SUCCESS on success) + * @return The number of bytes sent   */ -lockdownd_error_t lockdownd_stop_session(lockdownd_client_t client) +static ssize_t lockdownd_ssl_write(gnutls_transport_ptr_t transport, char *buffer, size_t length)  { -	if (!client) -		return LOCKDOWN_E_INVALID_ARG; +	uint32_t bytes = 0; +	lockdownd_client_t client; +	client = (lockdownd_client_t) transport; +	log_dbg_msg(DBGMASK_LOCKDOWND, "%s: pre-send length = %zi\n", __func__, length); +	iphone_device_send(property_list_service_get_connection(client->parent), buffer, length, &bytes); +	log_dbg_msg(DBGMASK_LOCKDOWND, "%s: post-send sent %i bytes\n", __func__, bytes); +	return bytes; +} -	if (!client->session_id) { -		log_dbg_msg(DBGMASK_LOCKDOWND, "%s: no session_id given, cannot stop session\n", __func__); -		return LOCKDOWN_E_INVALID_ARG; -	} +/** gnutls callback for reading data from the device. + * + * @param transport It's really the lockdownd client, but the method signature has to match + * @param buffer The buffer to store data in + * @param length The length of data to read in bytes + * + * @return The number of bytes read + */ +static ssize_t lockdownd_ssl_read(gnutls_transport_ptr_t transport, char *buffer, size_t length) +{ +	int bytes = 0, pos_start_fill = 0; +	size_t tbytes = 0; +	int this_len = length; +	iphone_error_t res; +	lockdownd_client_t client; +	client = (lockdownd_client_t) transport; +	char *recv_buffer; -	lockdownd_error_t ret = LOCKDOWN_E_UNKNOWN_ERROR; +	log_debug_msg("%s: pre-read client wants %zi bytes\n", __func__, length); -	plist_t dict = plist_new_dict(); -	plist_dict_add_label(dict, client->label); -	plist_dict_insert_item(dict,"Request", plist_new_string("StopSession")); -	plist_dict_insert_item(dict,"SessionID", plist_new_string(client->session_id)); +	recv_buffer = (char *) malloc(sizeof(char) * this_len); -	log_dbg_msg(DBGMASK_LOCKDOWND, "%s: stopping session %s\n", __func__, client->session_id); +	/* repeat until we have the full data or an error occurs */ +	do { +		if ((res = iphone_device_recv(property_list_service_get_connection(client->parent), recv_buffer, this_len, (uint32_t*)&bytes)) != LOCKDOWN_E_SUCCESS) { +			log_debug_msg("%s: ERROR: iphone_device_recv returned %d\n", __func__, res); +			return res; +		} +		log_debug_msg("%s: post-read we got %i bytes\n", __func__, bytes); -	ret = lockdownd_send(client, dict); +		// increase read count +		tbytes += bytes; -	plist_free(dict); -	dict = NULL; +		// fill the buffer with what we got right now +		memcpy(buffer + pos_start_fill, recv_buffer, bytes); +		pos_start_fill += bytes; -	ret = lockdownd_recv(client, &dict); +		if (tbytes >= length) { +			break; +		} -	if (!dict) { -		log_dbg_msg(DBGMASK_LOCKDOWND, "%s: LOCKDOWN_E_PLIST_ERROR\n", __func__); -		return LOCKDOWN_E_PLIST_ERROR; +		this_len = length - tbytes; +		log_debug_msg("%s: re-read trying to read missing %i bytes\n", __func__, this_len); +	} while (tbytes < length); + +	if (recv_buffer) { +		free(recv_buffer);  	} -	ret = LOCKDOWN_E_UNKNOWN_ERROR; -	if (lockdown_check_result(dict, "StopSession") == RESULT_SUCCESS) { -		log_dbg_msg(DBGMASK_LOCKDOWND, "%s: success\n", __func__); +	return tbytes; +} + +/** Starts communication with lockdownd after the iPhone has been paired, + *  and if the device requires it, switches to SSL mode. + * + * @param client The lockdownd client + * + * @return an error code (LOCKDOWN_E_SUCCESS on success) + */ +static lockdownd_error_t lockdownd_ssl_start_session(lockdownd_client_t client) +{ +	lockdownd_error_t ret = LOCKDOWN_E_SSL_ERROR; +	uint32_t return_me = 0; + +	// Set up GnuTLS... +	log_dbg_msg(DBGMASK_LOCKDOWND, "%s: enabling SSL mode\n", __func__); +	errno = 0; +	gnutls_global_init(); +	gnutls_certificate_allocate_credentials(&client->ssl_certificate); +	gnutls_certificate_set_x509_trust_file(client->ssl_certificate, "hostcert.pem", GNUTLS_X509_FMT_PEM); +	gnutls_init(&client->ssl_session, GNUTLS_CLIENT); +	{ +		int protocol_priority[16] = { GNUTLS_SSL3, 0 }; +		int kx_priority[16] = { GNUTLS_KX_ANON_DH, GNUTLS_KX_RSA, 0 }; +		int cipher_priority[16] = { GNUTLS_CIPHER_AES_128_CBC, GNUTLS_CIPHER_AES_256_CBC, 0 }; +		int mac_priority[16] = { GNUTLS_MAC_SHA1, GNUTLS_MAC_MD5, 0 }; +		int comp_priority[16] = { GNUTLS_COMP_NULL, 0 }; + +		gnutls_cipher_set_priority(client->ssl_session, cipher_priority); +		gnutls_compression_set_priority(client->ssl_session, comp_priority); +		gnutls_kx_set_priority(client->ssl_session, kx_priority); +		gnutls_protocol_set_priority(client->ssl_session, protocol_priority); +		gnutls_mac_set_priority(client->ssl_session, mac_priority); +	} +	gnutls_credentials_set(client->ssl_session, GNUTLS_CRD_CERTIFICATE, client->ssl_certificate);	// this part is killing me. + +	log_dbg_msg(DBGMASK_LOCKDOWND, "%s: GnuTLS step 1...\n", __func__); +	gnutls_transport_set_ptr(client->ssl_session, (gnutls_transport_ptr_t) client); +	log_dbg_msg(DBGMASK_LOCKDOWND, "%s: GnuTLS step 2...\n", __func__); +	gnutls_transport_set_push_function(client->ssl_session, (gnutls_push_func) & lockdownd_ssl_write); +	log_dbg_msg(DBGMASK_LOCKDOWND, "%s: GnuTLS step 3...\n", __func__); +	gnutls_transport_set_pull_function(client->ssl_session, (gnutls_pull_func) & lockdownd_ssl_read); +	log_dbg_msg(DBGMASK_LOCKDOWND, "%s: GnuTLS step 4 -- now handshaking...\n", __func__); +	if (errno) +		log_dbg_msg(DBGMASK_LOCKDOWND, "%s: WARN: errno says %s before handshake!\n", __func__, strerror(errno)); +	return_me = gnutls_handshake(client->ssl_session); +	log_dbg_msg(DBGMASK_LOCKDOWND, "%s: GnuTLS handshake done...\n", __func__); + +	if (return_me != GNUTLS_E_SUCCESS) { +		log_dbg_msg(DBGMASK_LOCKDOWND, "%s: GnuTLS reported something wrong.\n", __func__); +		gnutls_perror(return_me); +		log_dbg_msg(DBGMASK_LOCKDOWND, "%s: oh.. errno says %s\n", __func__, strerror(errno)); +	} else { +		client->ssl_enabled = 1;  		ret = LOCKDOWN_E_SUCCESS; +		log_dbg_msg(DBGMASK_LOCKDOWND, "%s: SSL mode enabled\n", __func__);  	} -	plist_free(dict); -	dict = NULL; - -	free(client->session_id); -	client->session_id = NULL;  	return ret;  }  /** - * Shuts down the SSL session by first calling iphone_lckd_stop_session - * to cleanly close the lockdownd communication session, and then - * performing a close notify, which is done by "gnutls_bye". + * Shuts down the SSL session by performing a close notify, which is done + * by "gnutls_bye".   *   * @param client The lockdown client   *   * @return an error code (LOCKDOWN_E_SUCCESS on success)   */ -static lockdownd_error_t lockdownd_stop_ssl_session(lockdownd_client_t client) +static lockdownd_error_t lockdownd_ssl_stop_session(lockdownd_client_t client)  {  	if (!client) {  		log_dbg_msg(DBGMASK_LOCKDOWND, "%s: invalid argument!\n", __func__); @@ -194,19 +270,79 @@ static lockdownd_error_t lockdownd_stop_ssl_session(lockdownd_client_t client)  	lockdownd_error_t ret = LOCKDOWN_E_SUCCESS;  	if (client->ssl_enabled) { -		log_dbg_msg(DBGMASK_LOCKDOWND, "%s: stopping SSL session\n", __func__); -		ret = lockdownd_stop_session(client);  		log_dbg_msg(DBGMASK_LOCKDOWND, "%s: sending SSL close notify\n", __func__);  		gnutls_bye(client->ssl_session, GNUTLS_SHUT_RDWR);  	}  	if (client->ssl_session) {  		gnutls_deinit(client->ssl_session); -        } -        if (client->ssl_certificate) { +	} +	if (client->ssl_certificate) {  		gnutls_certificate_free_credentials(client->ssl_certificate); -        } +	}  	client->ssl_enabled = 0; +	if (client->session_id) +		free(client->session_id); +	client->session_id = NULL; + +	log_dbg_msg(DBGMASK_LOCKDOWND, "%s: SSL mode disabled\n", __func__); + +	return ret; +} + +/** + * Closes the lockdownd communication session, by sending the StopSession + * Request to the device. + * + * @see lockdownd_start_session + * + * @param control The lockdown client + * @param session_id The id of a running session + * + * @return an error code (LOCKDOWN_E_SUCCESS on success) + */ +lockdownd_error_t lockdownd_stop_session(lockdownd_client_t client, const char *session_id) +{ +	if (!client) +		return LOCKDOWN_E_INVALID_ARG; + +	if (!session_id) { +		log_dbg_msg(DBGMASK_LOCKDOWND, "%s: no session_id given, cannot stop session\n", __func__); +		return LOCKDOWN_E_INVALID_ARG; +	} + +	lockdownd_error_t ret = LOCKDOWN_E_UNKNOWN_ERROR; + +	plist_t dict = plist_new_dict(); +	plist_dict_add_label(dict, client->label); +	plist_dict_insert_item(dict,"Request", plist_new_string("StopSession")); +	plist_dict_insert_item(dict,"SessionID", plist_new_string(session_id)); + +	log_dbg_msg(DBGMASK_LOCKDOWND, "%s: stopping session %s\n", __func__, session_id); + +	ret = lockdownd_send(client, dict); + +	plist_free(dict); +	dict = NULL; + +	ret = lockdownd_recv(client, &dict); + +	if (!dict) { +		log_dbg_msg(DBGMASK_LOCKDOWND, "%s: LOCKDOWN_E_PLIST_ERROR\n", __func__); +		return LOCKDOWN_E_PLIST_ERROR; +	} + +	ret = LOCKDOWN_E_UNKNOWN_ERROR; +	if (lockdown_check_result(dict, "StopSession") == RESULT_SUCCESS) { +		log_dbg_msg(DBGMASK_LOCKDOWND, "%s: success\n", __func__); +		ret = LOCKDOWN_E_SUCCESS; +	} +	plist_free(dict); +	dict = NULL; + +	/* stop ssl session */ +	lockdownd_ssl_stop_session(client); +  	return ret;  } @@ -222,7 +358,8 @@ lockdownd_error_t lockdownd_client_free(lockdownd_client_t client)  		return LOCKDOWN_E_INVALID_ARG;  	lockdownd_error_t ret = LOCKDOWN_E_UNKNOWN_ERROR; -	lockdownd_stop_ssl_session(client); +	if (client->session_id) +		lockdownd_stop_session(client, client->session_id);  	if (client->parent) {  		lockdownd_goodbye(client); @@ -232,9 +369,6 @@ lockdownd_error_t lockdownd_client_free(lockdownd_client_t client)  		}  	} -	if (client->session_id) { -		free(client->session_id); -	}  	if (client->uuid) {  		free(client->uuid);  	} @@ -712,7 +846,7 @@ lockdownd_error_t lockdownd_client_new_with_handshake(iphone_device_t device, lo  	ret = lockdownd_validate_pair(client_loc, host_id);  	if (LOCKDOWN_E_SUCCESS == ret) { -		ret = lockdownd_start_ssl_session(client_loc, host_id); +		ret = lockdownd_start_session(client_loc, host_id, NULL, NULL);  		if (LOCKDOWN_E_SUCCESS != ret) {  			ret = LOCKDOWN_E_SSL_ERROR;  			log_debug_msg("%s: SSL Session opening failed.\n", __func__); @@ -1012,7 +1146,7 @@ lockdownd_error_t lockdownd_gen_pair_cert(gnutls_datum_t public_key, gnutls_datu  			asn1_delete_structure(&pkcs1);  	} -	/* now generate certifcates */ +	/* now generate certificates */  	if (LOCKDOWN_E_SUCCESS == ret && 0 != modulus.size && 0 != exponent.size) {  		gnutls_global_init(); @@ -1106,22 +1240,26 @@ lockdownd_error_t lockdownd_gen_pair_cert(gnutls_datum_t public_key, gnutls_datu   *  and if the device requires it, switches to SSL mode.   *   * @param client The lockdownd client - * @param HostID The HostID used with this phone + * @param host_id The HostID of the computer + * @param session_id The 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)   */ -lockdownd_error_t lockdownd_start_ssl_session(lockdownd_client_t client, const char *host_id) +lockdownd_error_t lockdownd_start_session(lockdownd_client_t client, const char *host_id, char **session_id, int *ssl_enabled)  { +	lockdownd_error_t ret = LOCKDOWN_E_SUCCESS;  	plist_t dict = NULL; -	uint32_t return_me = 0; -	lockdownd_error_t ret = LOCKDOWN_E_UNKNOWN_ERROR; +	if (!client || !host_id) +		ret = LOCKDOWN_E_INVALID_ARG; + +	/* if we have a running session, stop current one first */  	if (client->session_id) { -		free(client->session_id); -		client->session_id = NULL; +		lockdownd_stop_session(client, client->session_id);  	} -	/* Setup DevicePublicKey request plist */ +	/* setup request plist */  	dict = plist_new_dict();  	plist_dict_add_label(dict, client->label);  	plist_dict_insert_item(dict,"HostID", plist_new_string(host_id)); @@ -1144,184 +1282,48 @@ lockdownd_error_t lockdownd_start_ssl_session(lockdownd_client_t client, const c  		if (error_node && PLIST_STRING == plist_get_node_type(error_node)) {  			char *error = NULL;  			plist_get_string_val(error_node, &error); -  			if (!strcmp(error, "InvalidHostID")) { -				/* hostid is unknown. Pair and try again */ -				char *host_id_new = NULL; -				userpref_get_host_id(&host_id_new); - -				if (LOCKDOWN_E_SUCCESS == lockdownd_pair(client, host_id_new) ) { -					/* start session again */ -					plist_free(dict); -					dict = plist_new_dict(); -					plist_dict_add_label(dict, client->label); -					plist_dict_insert_item(dict,"HostID", plist_new_string(host_id_new)); -					plist_dict_insert_item(dict,"Request", plist_new_string("StartSession")); - -					ret = lockdownd_send(client, dict); -					plist_free(dict); -					dict = NULL; - -					ret = lockdownd_recv(client, &dict); -				} -				free(host_id_new); +				ret = LOCKDOWN_E_INVALID_HOST_ID;  			}  			free(error);  		} -	} - -	ret = LOCKDOWN_E_SSL_ERROR; - -	int session_ok = 0;  -	uint8_t UseSSL = 0; +	} else { +		uint8_t use_ssl = 0; -	if (lockdown_check_result(dict, "StartSession") == RESULT_SUCCESS) {  		plist_t enable_ssl = plist_dict_get_item(dict, "EnableSessionSSL");  		if (enable_ssl && (plist_get_node_type(enable_ssl) == PLIST_BOOLEAN)) { -			plist_get_bool_val(enable_ssl, &UseSSL); +			plist_get_bool_val(enable_ssl, &use_ssl);  		}  		log_dbg_msg(DBGMASK_LOCKDOWND, "%s: Session startup OK\n", __func__); -		session_ok = 1; -	} -	if (session_ok && !UseSSL) { -		client->ssl_enabled = 0; -		ret = LOCKDOWN_E_SUCCESS; -	} else if (session_ok) { -		// Set up GnuTLS... -		log_dbg_msg(DBGMASK_LOCKDOWND, "%s: Switching to SSL mode\n", __func__); -		errno = 0; -		gnutls_global_init(); -		//gnutls_anon_allocate_client_credentials(&anoncred); -		gnutls_certificate_allocate_credentials(&client->ssl_certificate); -		gnutls_certificate_set_x509_trust_file(client->ssl_certificate, "hostcert.pem", GNUTLS_X509_FMT_PEM); -		gnutls_init(&client->ssl_session, GNUTLS_CLIENT); -		{ -			int protocol_priority[16] = { GNUTLS_SSL3, 0 }; -			int kx_priority[16] = { GNUTLS_KX_ANON_DH, GNUTLS_KX_RSA, 0 }; -			int cipher_priority[16] = { GNUTLS_CIPHER_AES_128_CBC, GNUTLS_CIPHER_AES_256_CBC, 0 }; -			int mac_priority[16] = { GNUTLS_MAC_SHA1, GNUTLS_MAC_MD5, 0 }; -			int comp_priority[16] = { GNUTLS_COMP_NULL, 0 }; - -			gnutls_cipher_set_priority(client->ssl_session, cipher_priority); -			gnutls_compression_set_priority(client->ssl_session, comp_priority); -			gnutls_kx_set_priority(client->ssl_session, kx_priority); -			gnutls_protocol_set_priority(client->ssl_session, protocol_priority); -			gnutls_mac_set_priority(client->ssl_session, mac_priority); + +		if (ssl_enabled != NULL) +			*ssl_enabled = use_ssl; + +		/* store session id, we need it for StopSession */ +		plist_t session_node = plist_dict_get_item(dict, "SessionID"); +		if (session_node && (plist_get_node_type(session_node) == PLIST_STRING)) { +			plist_get_string_val(session_node, &client->session_id);  		} -		gnutls_credentials_set(client->ssl_session, GNUTLS_CRD_CERTIFICATE, client->ssl_certificate);	// this part is killing me. - -		log_dbg_msg(DBGMASK_LOCKDOWND, "%s: GnuTLS step 1...\n", __func__); -		gnutls_transport_set_ptr(client->ssl_session, (gnutls_transport_ptr_t) client); -		log_dbg_msg(DBGMASK_LOCKDOWND, "%s: GnuTLS step 2...\n", __func__); -		gnutls_transport_set_push_function(client->ssl_session, (gnutls_push_func) & lockdownd_secuwrite); -		log_dbg_msg(DBGMASK_LOCKDOWND, "%s: GnuTLS step 3...\n", __func__); -		gnutls_transport_set_pull_function(client->ssl_session, (gnutls_pull_func) & lockdownd_securead); -		log_dbg_msg(DBGMASK_LOCKDOWND, "%s: GnuTLS step 4 -- now handshaking...\n", __func__); -		if (errno) -			log_dbg_msg(DBGMASK_LOCKDOWND, "%s: WARN: errno says %s before handshake!\n", __func__, strerror(errno)); -		return_me = gnutls_handshake(client->ssl_session); -		log_dbg_msg(DBGMASK_LOCKDOWND, "%s: GnuTLS handshake done...\n", __func__); - -		if (return_me != GNUTLS_E_SUCCESS) { -			log_dbg_msg(DBGMASK_LOCKDOWND, "%s: GnuTLS reported something wrong.\n", __func__); -			gnutls_perror(return_me); -			log_dbg_msg(DBGMASK_LOCKDOWND, "%s: oh.. errno says %s\n", __func__, strerror(errno)); -			return LOCKDOWN_E_SSL_ERROR; +		if (client->session_id) { +			log_dbg_msg(DBGMASK_LOCKDOWND, "%s: SessionID: %s\n", __func__, client->session_id); +			if (session_id != NULL) +				*session_id = strdup(client->session_id);  		} else { -			client->ssl_enabled = 1; +			log_dbg_msg(DBGMASK_LOCKDOWND, "%s: Failed to get SessionID!\n", __func__); +		} +		log_dbg_msg(DBGMASK_LOCKDOWND, "%s: Enable SSL Session: %s\n", __func__, (use_ssl?"true":"false")); +		if (use_ssl) { +			ret = lockdownd_ssl_start_session(client); +		} else { +			client->ssl_enabled = 0;  			ret = LOCKDOWN_E_SUCCESS;  		}  	} -	/* store session id, we need it for StopSession */ -	plist_t session_node = plist_dict_get_item(dict, "SessionID"); -	if (session_node && (plist_get_node_type(session_node) == PLIST_STRING)) { -		plist_get_string_val(session_node, &client->session_id); -	} -	if (client->session_id) { -		log_dbg_msg(DBGMASK_LOCKDOWND, "%s: SessionID: %s\n", __func__, client->session_id); -	} else { -		log_dbg_msg(DBGMASK_LOCKDOWND, "%s: Failed to get SessionID!\n", __func__); -	} +  	plist_free(dict);  	dict = NULL; -	if (ret == LOCKDOWN_E_SUCCESS) -		return ret; - -	log_dbg_msg(DBGMASK_LOCKDOWND, "%s: Apparently failed negotiating with lockdownd.\n", __func__); -	return LOCKDOWN_E_SSL_ERROR; -} - -/** gnutls callback for writing data to the iPhone. - * - * @param transport It's really the lockdownd client, but the method signature has to match - * @param buffer The data to send - * @param length The length of data to send in bytes - * - * @return The number of bytes sent - */ -ssize_t lockdownd_secuwrite(gnutls_transport_ptr_t transport, char *buffer, size_t length) -{ -	uint32_t bytes = 0; -	lockdownd_client_t client; -	client = (lockdownd_client_t) transport; -	log_dbg_msg(DBGMASK_LOCKDOWND, "%s: called\n", __func__); -	log_dbg_msg(DBGMASK_LOCKDOWND, "%s: pre-send length = %zi\n", __func__, length); -	iphone_device_send(property_list_service_get_connection(client->parent), buffer, length, &bytes); -	log_dbg_msg(DBGMASK_LOCKDOWND, "%s: post-send sent %i bytes\n", __func__, bytes); -	return bytes; -} - -/** gnutls callback for reading data from the iPhone - * - * @param transport It's really the lockdownd client, but the method signature has to match - * @param buffer The buffer to store data in - * @param length The length of data to read in bytes - * - * @return The number of bytes read - */ -ssize_t lockdownd_securead(gnutls_transport_ptr_t transport, char *buffer, size_t length) -{ -	int bytes = 0, pos_start_fill = 0; -	size_t tbytes = 0; -	int this_len = length; -	iphone_error_t res; -	lockdownd_client_t client; -	client = (lockdownd_client_t) transport; -	char *recv_buffer; - -	log_debug_msg("%s: pre-read client wants %zi bytes\n", __func__, length); - -	recv_buffer = (char *) malloc(sizeof(char) * this_len); - -	// repeat until we have the full data or an error occurs. -	do { -		if ((res = iphone_device_recv(property_list_service_get_connection(client->parent), recv_buffer, this_len, (uint32_t*)&bytes)) != LOCKDOWN_E_SUCCESS) { -			log_debug_msg("%s: ERROR: usbmux_recv returned %d\n", __func__, res); -			return res; -		} -		log_debug_msg("%s: post-read we got %i bytes\n", __func__, bytes); - -		// increase read count -		tbytes += bytes; - -		// fill the buffer with what we got right now -		memcpy(buffer + pos_start_fill, recv_buffer, bytes); -		pos_start_fill += bytes; - -		if (tbytes >= length) { -			break; -		} - -		this_len = length - tbytes; -		log_debug_msg("%s: re-read trying to read missing %i bytes\n", __func__, this_len); -	} while (tbytes < length); - -	if (recv_buffer) { -		free(recv_buffer); -	} - -	return tbytes; +	return ret;  }  /** Command to start the desired service diff --git a/src/lockdown.h b/src/lockdown.h index d7a18b5..9da3872 100644 --- a/src/lockdown.h +++ b/src/lockdown.h @@ -42,10 +42,4 @@ lockdownd_error_t lockdownd_get_device_public_key(lockdownd_client_t client, gnu  lockdownd_error_t lockdownd_gen_pair_cert(gnutls_datum_t public_key, gnutls_datum_t * device_cert,  									   gnutls_datum_t * host_cert, gnutls_datum_t * root_cert); -/* SSL functions */ -lockdownd_error_t lockdownd_start_ssl_session(lockdownd_client_t client, const char *host_id); -ssize_t lockdownd_securead(gnutls_transport_ptr_t transport, char *buffer, size_t length); -ssize_t lockdownd_secuwrite(gnutls_transport_ptr_t transport, char *buffer, size_t length); - -  #endif | 
