diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/iphone.c | 3 | ||||
| -rw-r--r-- | src/lockdown.c | 6 | ||||
| -rw-r--r-- | src/lockdown.h | 2 | ||||
| -rw-r--r-- | src/usbmux.c | 170 | ||||
| -rw-r--r-- | src/usbmux.h | 9 | 
5 files changed, 96 insertions, 94 deletions
| diff --git a/src/iphone.c b/src/iphone.c index f3b7202..9027e35 100644 --- a/src/iphone.c +++ b/src/iphone.c @@ -42,7 +42,6 @@ int  iphone_get_device ( iphone_device_t *device  ){  	struct usb_bus *bus, *busses;  	struct usb_device *dev;  	iphone_device_t phone = (iphone_device_t)malloc(sizeof(struct iphone_device_int)); -	usbmux_version_header *version = version_header();  	// Initialize the struct  	phone->device = NULL; @@ -126,7 +125,7 @@ int  iphone_get_device ( iphone_device_t *device  ){  	if (debug) fprintf(stderr, "get_iPhone(): Unknown error.\n");  	free_iPhone(phone);  	free(version); -	return IPHONE_E_NO_DEVICE; // if it got to this point it's gotta be bad +	return IPHONE_E_UNKNOWN_ERROR; // if it got to this point it's gotta be bad  }  /** Cleans up an iPhone structure, then frees the structure itself.   diff --git a/src/lockdown.c b/src/lockdown.c index bc70d53..e8626bc 100644 --- a/src/lockdown.c +++ b/src/lockdown.c @@ -77,8 +77,8 @@ char *lockdownd_generate_hostid() {  iphone_lckd_client_t new_lockdownd_client(iphone_device_t phone) {  	if (!phone) return NULL;  	iphone_lckd_client_t control = (iphone_lckd_client_t)malloc(sizeof(struct iphone_lckd_client_int)); -	control->connection = mux_connect(phone, 0x0a00, 0xf27e); -	if (!control->connection) { + +	if (IPHONE_E_SUCCESS != iphone_mux_new_client ( phone, 0x0a00, 0xf27e, &control->connection)) {  		free(control);  		return NULL;  	} @@ -100,7 +100,7 @@ void iphone_lckd_free_client( iphone_lckd_client_t client ) {  		mux_close_connection(client->connection);  	} -	if (client->ssl_session) gnutls_deinit(*control->ssl_session); +	if (client->ssl_session) gnutls_deinit(*client->ssl_session);  	free(client->ssl_session);  	free(client);  } diff --git a/src/lockdown.h b/src/lockdown.h index 1c83ab3..f22d7db 100644 --- a/src/lockdown.h +++ b/src/lockdown.h @@ -33,7 +33,7 @@  struct iphone_lckd_client_int { -	usbmux_connection *connection; +	iphone_umux_client_t connection;  	gnutls_session_t *ssl_session;  	int in_SSL;  	char *gtls_buffer_hack; diff --git a/src/usbmux.c b/src/usbmux.c index a4a859a..48cb963 100644 --- a/src/usbmux.c +++ b/src/usbmux.c @@ -29,8 +29,8 @@  extern int debug; -static usbmux_connection **connlist = NULL; -static int connections = 0; +static iphone_umux_client_t *connlist = NULL; +static int clients = 0;  /** Creates a USBMux packet for the given set of ports.   *  @@ -76,10 +76,10 @@ usbmux_version_header *version_header() {   *    * @param connection The connection to delete from the tracking list.   */ -void delete_connection(usbmux_connection *connection) { -	usbmux_connection **newlist = (usbmux_connection**)malloc(sizeof(usbmux_connection*) * (connections - 1)); +void delete_connection(iphone_umux_client_t connection) { +	iphone_umux_client_t *newlist = (iphone_umux_client_t*)malloc(sizeof(iphone_umux_client_t) * (clients - 1));  	int i = 0, j = 0; -	for (i = 0; i < connections; i++) { +	for (i = 0; i < clients; i++) {  		if (connlist[i] == connection) continue;  		else {  			newlist[j] = connlist[i]; @@ -88,7 +88,7 @@ void delete_connection(usbmux_connection *connection) {  	}  	free(connlist);  	connlist = newlist; -	connections--; +	clients--;  	if (connection->recv_buffer) free(connection->recv_buffer);  	if (connection->header) free(connection->header);  	connection->r_len = 0; @@ -101,59 +101,64 @@ void delete_connection(usbmux_connection *connection) {   * @param connection The connection to add to the global list of connections.   */ -void add_connection(usbmux_connection *connection) { -	usbmux_connection **newlist = (usbmux_connection**)realloc(connlist, sizeof(usbmux_connection*) * (connections+1)); -	newlist[connections] = connection; +void add_connection(iphone_umux_client_t connection) { +	iphone_umux_client_t* newlist = (iphone_umux_client_t*)realloc(connlist, sizeof(iphone_umux_client_t) * (clients+1)); +	newlist[clients] = connection;  	connlist = newlist; -	connections++; +	clients++;  }  /** Initializes a connection on phone, with source port s_port and destination port d_port   * - * @param phone The iPhone to initialize a connection on. - * @param s_port The source port - * @param d_port The destination port -- 0xf27e for lockdownd.  - * - * @return A mux TCP header for the connection which is used for tracking and data transfer. - */  -usbmux_connection *mux_connect(iphone_device_t phone, uint16 s_port, uint16 d_port) { -	if (!phone || !s_port || !d_port) return NULL; + * @param device The iPhone to initialize a connection on. + * @param src_port The source port + * @param dst_port The destination port -- 0xf27e for lockdownd.  + * @param client A mux TCP header for the connection which is used for tracking and data transfer. + * @return IPHONE_E_SUCCESS on success, an error code otherwise. + */ +int iphone_mux_new_client ( iphone_device_t device, uint16_t src_port, uint16_t dst_port, iphone_umux_client_t *client ){ +	if (!device || !src_port || !dst_port) +		return IPHONE_E_INVALID_ARG; +  	int bytes = 0;  	// Initialize connection stuff -	usbmux_connection *new_connection = (usbmux_connection*)malloc(sizeof(usbmux_connection)); -	new_connection->header = new_mux_packet(s_port, d_port); +	iphone_umux_client_t new_connection = (iphone_umux_client_t)malloc(sizeof(struct iphone_umux_client_int)); +	new_connection->header = new_mux_packet(src_port, dst_port); +  	// blargg  	if (new_connection && new_connection->header) {  		new_connection->header->tcp_flags = 0x02;  		new_connection->header->length = htonl(new_connection->header->length);  		new_connection->header->length16 = htons(new_connection->header->length16); -		if (send_to_phone(phone, (char*)new_connection->header, sizeof(usbmux_tcp_header)) >= 0) { +		if (send_to_phone(device, (char*)new_connection->header, sizeof(usbmux_tcp_header)) >= 0) {  			usbmux_tcp_header *response;  			response = (usbmux_tcp_header*)malloc(sizeof(usbmux_tcp_header)); -			bytes = recv_from_phone(phone, (char*)response, sizeof(*response)); +			bytes = recv_from_phone(device, (char*)response, sizeof(*response));  			if (response->tcp_flags != 0x12) {  				free(response); -				return NULL; +				return IPHONE_E_UNKNOWN_ERROR;  			} else {  				free(response); +  				if (debug) printf("mux_connect: connection success\n");  				new_connection->header->tcp_flags = 0x10;  				new_connection->header->scnt = 1;  				new_connection->header->ocnt = 1; -				new_connection->phone = phone; +				new_connection->phone = device;  				new_connection->recv_buffer = NULL;  				new_connection->r_len = 0;  				add_connection(new_connection); -				return new_connection; +				*client = new_connection; +				return IPHONE_E_SUCCESS;  			}  		} else { -			return NULL; +			return IPHONE_E_NOT_ENOUGH_DATA;  		}  	}  	// if we get to this point it's probably bad -	return NULL; +	return IPHONE_E_UNKNOWN_ERROR;  }  /** Cleans up the given USBMux connection. @@ -161,56 +166,59 @@ usbmux_connection *mux_connect(iphone_device_t phone, uint16 s_port, uint16 d_po   *    * @param connection The connection to close.   */ -void mux_close_connection(usbmux_connection *connection) { -	if (!connection || !connection->phone) return; +void iphone_mux_free_client ( iphone_umux_client_t client ) { +	if (!client || !client->phone) return; -	connection->header->tcp_flags = 0x04; -	connection->header->scnt = htonl(connection->header->scnt); -	connection->header->ocnt = htonl(connection->header->ocnt); +	client->header->tcp_flags = 0x04; +	client->header->scnt = htonl(client->header->scnt); +	client->header->ocnt = htonl(client->header->ocnt);  	int bytes = 0; -	bytes = usb_bulk_write(connection->phone->device, BULKOUT, (char*)connection->header, sizeof(usbmux_tcp_header), 800); +	bytes = usb_bulk_write(client->phone->device, BULKOUT, (char*)client->header, sizeof(usbmux_tcp_header), 800);  	if(debug && bytes < 0)  		printf("mux_close_connection(): when writing, libusb gave me the error: %s\n", usb_strerror()); -	bytes = usb_bulk_read(connection->phone->device, BULKIN, (char*)connection->header, sizeof(usbmux_tcp_header), 800); +	bytes = usb_bulk_read(client->phone->device, BULKIN, (char*)client->header, sizeof(usbmux_tcp_header), 800);  	if(debug && bytes < 0)  		printf("get_iPhone(): when reading, libusb gave me the error: %s\n", usb_strerror()); -	delete_connection(connection); +	delete_connection(client);  } +  /** Sends the given data over the selected connection. - *  - * @param connection The connection we're sending data on. + * + * @param phone The iPhone to send to. + * @param client The client we're sending data on.   * @param data A pointer to the data to send.   * @param datalen How much data we're sending.   *   * @return The number of bytes sent, minus the header (28), or -1 on error.   */ -int mux_send(usbmux_connection *connection, const char *data, uint32 datalen) { -	if (!connection->phone || !connection || !data || datalen == 0) return -1; -	// connection->scnt and connection->ocnt should already be in host notation... + +int iphone_mux_send ( iphone_umux_client_t client, const char *data, uint32_t datalen ) { +	if (!client->phone || !client || !data || datalen == 0) return -1; +	// client->scnt and client->ocnt should already be in host notation...  	// we don't need to change them juuuust yet.   	int bytes = 0;  	if (debug) printf("mux_send(): client wants to send %i bytes\n", datalen);  	char *buffer = (char*)malloc(sizeof(usbmux_tcp_header) + datalen + 2); // allow 2 bytes of safety padding  	// Set the length and pre-emptively htonl/htons it -	connection->header->length = htonl(sizeof(usbmux_tcp_header) + datalen); -	connection->header->length16 = htons(sizeof(usbmux_tcp_header) + datalen); +	client->header->length = htonl(sizeof(usbmux_tcp_header) + datalen); +	client->header->length16 = htons(sizeof(usbmux_tcp_header) + datalen);  	// Put scnt and ocnt into big-endian notation -	connection->header->scnt = htonl(connection->header->scnt); -	connection->header->ocnt = htonl(connection->header->ocnt); +	client->header->scnt = htonl(client->header->scnt); +	client->header->ocnt = htonl(client->header->ocnt);  	// Concatenation of stuff in the buffer. -	memcpy(buffer, connection->header, sizeof(usbmux_tcp_header)); +	memcpy(buffer, client->header, sizeof(usbmux_tcp_header));  	memcpy(buffer+sizeof(usbmux_tcp_header), data, datalen);  	// We have a buffer full of data, we should now send it to the phone.  	if (debug) printf("actually sending %zi bytes of data at %p\n", sizeof(usbmux_tcp_header)+datalen, buffer); -	bytes = send_to_phone(connection->phone, buffer, sizeof(usbmux_tcp_header)+datalen); +	bytes = send_to_phone(client->phone, buffer, sizeof(usbmux_tcp_header)+datalen);  	if (debug) printf("mux_send: sent %i bytes!\n", bytes);  	// Now that we've sent it off, we can clean up after our sloppy selves.  	if (debug) { @@ -222,12 +230,12 @@ int mux_send(usbmux_connection *connection, const char *data, uint32 datalen) {  	if (buffer) free(buffer);  	// Re-calculate scnt and ocnt -	connection->header->scnt = ntohl(connection->header->scnt) + datalen; -	connection->header->ocnt = ntohl(connection->header->ocnt); +	client->header->scnt = ntohl(client->header->scnt) + datalen; +	client->header->ocnt = ntohl(client->header->ocnt);  	// Revert lengths -	connection->header->length = ntohl(connection->header->length); -	connection->header->length16 = ntohs(connection->header->length16); +	client->header->length = ntohl(client->header->length); +	client->header->length16 = ntohs(client->header->length16);  	// Now return the bytes.  	if (bytes < sizeof(usbmux_tcp_header)+datalen) { @@ -247,52 +255,52 @@ int mux_send(usbmux_connection *connection, const char *data, uint32 datalen) {   *   * @return How many bytes were read, or -1 if something bad happens.   */ -int mux_recv(usbmux_connection *connection, char *data, uint32 datalen) { +int iphone_mux_recv ( iphone_umux_client_t client, char *data, uint32_t datalen ) {  	/*  	 * Order of operation: -	 * 1.) Check if the connection has a pre-received buffer. +	 * 1.) Check if the client has a pre-received buffer.  	 * 2.) If so, fill data with the buffer, as much as needed.  	 * 	a.) Return quickly if the buffer has enough  	 * 	b.) If the buffer is only part of the datalen, get the rest of datalen (and if we can't, just return)  	 * 3.) If not, receive directly from the phone.   	 * 	a.) Check incoming packet's ports. If proper, follow proper buffering and receiving operation. -	 * 	b.) If not, find the connection the ports belong to and fill that connection's buffer, then return mux_recv with the same args to try again. +	 * 	b.) If not, find the client the ports belong to and fill that client's buffer, then return mux_recv with the same args to try again.  	 */  	if (debug) printf("mux_recv: datalen == %i\n", datalen);  	int bytes = 0, i = 0, complex = 0, offset = 0;  	char *buffer = NULL;  	usbmux_tcp_header *header = NULL; -	if (connection->recv_buffer) { -		if (connection->r_len >= datalen) { -			memcpy(data, connection->recv_buffer, datalen); -			if (connection->r_len == datalen) { +	if (client->recv_buffer) { +		if (client->r_len >= datalen) { +			memcpy(data, client->recv_buffer, datalen); +			if (client->r_len == datalen) {  				// reset everything -				free(connection->recv_buffer); -				connection->r_len = 0; -				connection->recv_buffer = NULL; +				free(client->recv_buffer); +				client->r_len = 0; +				client->recv_buffer = NULL;  			} else { -				buffer = (char*)malloc(sizeof(char) * (connection->r_len - datalen)); -				memcpy(buffer, connection->recv_buffer+datalen, (connection->r_len - datalen)); -				connection->r_len -= datalen; -				free(connection->recv_buffer); -				connection->recv_buffer = buffer; +				buffer = (char*)malloc(sizeof(char) * (client->r_len - datalen)); +				memcpy(buffer, client->recv_buffer+datalen, (client->r_len - datalen)); +				client->r_len -= datalen; +				free(client->recv_buffer); +				client->recv_buffer = buffer;  			}  			// Since we were able to fill the data straight from our buffer, we can just return datalen. See 2a above.  			return datalen;  		} else { -			memcpy(data, connection->recv_buffer, connection->r_len); -			free(connection->recv_buffer); // don't need to deal with anymore, but... -			offset = connection->r_len; // see #2b, above -			connection->r_len = 0; +			memcpy(data, client->recv_buffer, client->r_len); +			free(client->recv_buffer); // don't need to deal with anymore, but... +			offset = client->r_len; // see #2b, above +			client->r_len = 0;  		}  	} // End of what to do if we have a pre-buffer. See #1 and #2 above.   	buffer = (char*)malloc(sizeof(char) * 131072); // make sure we get enough ;)  	// See #3. -	bytes = recv_from_phone(connection->phone, buffer, 131072); +	bytes = recv_from_phone(client->phone, buffer, 131072);  	if (bytes < 28) {  		free(buffer);  		if (debug) printf("mux_recv: Did not even get the header.\n"); @@ -300,10 +308,10 @@ int mux_recv(usbmux_connection *connection, char *data, uint32 datalen) {  	}  	header = (usbmux_tcp_header*)buffer; -	if (header->sport != connection->header->dport || header->dport != connection->header->sport) { +	if (header->sport != client->header->dport || header->dport != client->header->sport) {  		// Ooooops -- we got someone else's packet.  		// We gotta stick it in their buffer. (Take that any old way you want ;) ) -		for (i = 0; i < connections; i++) { +		for (i = 0; i < clients; i++) {  			if (connlist[i]->header->sport == header->dport && connlist[i]->header->dport == header->sport) {  				// we have a winner.  				char *nfb = (char*)malloc(sizeof(char) * (connlist[i]->r_len + (bytes - 28))); @@ -312,7 +320,7 @@ int mux_recv(usbmux_connection *connection, char *data, uint32 datalen) {  					free(connlist[i]->recv_buffer);  				}  				connlist[i]->r_len += bytes - 28; -				//connlist[i]->recv_buffer = (char*)realloc(connlist[i]->recv_buffer, sizeof(char) * connection->r_len); // grow their buffer +				//connlist[i]->recv_buffer = (char*)realloc(connlist[i]->recv_buffer, sizeof(char) * client->r_len); // grow their buffer  				connlist[i]->recv_buffer = nfb;  				nfb = NULL; // A cookie for you if you can guess what "nfb" means.   				complex = connlist[i]->r_len - (bytes - 28); @@ -324,7 +332,7 @@ int mux_recv(usbmux_connection *connection, char *data, uint32 datalen) {  		// Free our buffer and continue.  		free(buffer);  		buffer = NULL; -		return mux_recv(connection, data, datalen); // recurse back in to try again +		return mux_recv(client, data, datalen); // recurse back in to try again  	}  	// The packet was absolutely meant for us if it hits this point. @@ -333,18 +341,18 @@ int mux_recv(usbmux_connection *connection, char *data, uint32 datalen) {  	if ((bytes-28) > datalen) {  		// Copy what we need into the data, buffer the rest because we can.  		memcpy(data+offset, buffer+28, datalen); // data+offset: see #2b, above -		complex = connection->r_len + (bytes-28) - datalen; -		connection->recv_buffer = (char*)realloc(connection->recv_buffer, (sizeof(char) * complex)); -		connection->r_len = complex; -		complex = connection->r_len - (bytes-28) - datalen; -		memcpy(connection->recv_buffer+complex, buffer+28+datalen, (bytes-28) - datalen); +		complex = client->r_len + (bytes-28) - datalen; +		client->recv_buffer = (char*)realloc(client->recv_buffer, (sizeof(char) * complex)); +		client->r_len = complex; +		complex = client->r_len - (bytes-28) - datalen; +		memcpy(client->recv_buffer+complex, buffer+28+datalen, (bytes-28) - datalen);  		free(buffer); -		connection->header->ocnt += bytes-28; +		client->header->ocnt += bytes-28;  		return datalen;  	} else {  		// Fill the data with what we have, and just return.  		memcpy(data+offset, buffer+28, bytes-28); // data+offset: see #2b, above -		connection->header->ocnt += bytes-28; +		client->header->ocnt += bytes-28;  		free(buffer);  		return (bytes-28);  	} diff --git a/src/usbmux.h b/src/usbmux.h index 831f0fd..da8a361 100644 --- a/src/usbmux.h +++ b/src/usbmux.h @@ -43,12 +43,12 @@ typedef struct {  	uint16 window, nullnull, length16;  } usbmux_tcp_header; -typedef struct { +struct iphone_umux_client_int {  	usbmux_tcp_header *header;  	iphone_device_t phone;  	char *recv_buffer;  	int r_len; -} usbmux_connection; +};  usbmux_tcp_header *new_mux_packet(uint16 s_port, uint16 d_port); @@ -58,10 +58,5 @@ typedef struct {  usbmux_version_header *version_header(); -usbmux_connection *mux_connect(iphone_device_t phone, uint16 s_port, uint16 d_port); -void mux_close_connection(usbmux_connection *connection); -int mux_send(usbmux_connection *connection, const char *data, uint32 datalen); -int mux_recv(usbmux_connection *connection, char *data, uint32 datalen); -  #endif | 
