summaryrefslogtreecommitdiffstats
path: root/src/lockdown.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/lockdown.c')
-rw-r--r--src/lockdown.c106
1 files changed, 42 insertions, 64 deletions
diff --git a/src/lockdown.c b/src/lockdown.c
index 2d85a03..73a8bbc 100644
--- a/src/lockdown.c
+++ b/src/lockdown.c
@@ -88,7 +88,6 @@ iphone_lckd_client_t new_lockdownd_client(iphone_device_t phone)
control->ssl_session = (gnutls_session_t *) malloc(sizeof(gnutls_session_t));
control->in_SSL = 0;
- control->gtls_buffer_hack_len = 0;
return control;
}
@@ -179,7 +178,6 @@ static void iphone_lckd_stop_SSL_session(iphone_lckd_client_t client)
free(client->ssl_session);
}
client->in_SSL = 0;
- client->gtls_buffer_hack_len = 0; // dunno if required?!
return;
}
@@ -459,6 +457,10 @@ iphone_error_t iphone_lckd_new_client(iphone_device_t device, iphone_lckd_client
char *host_id = NULL;
iphone_lckd_client_t client_loc = new_lockdownd_client(device);
+ if (!client_loc) {
+ log_debug_msg("FATAL: lockdownd client could not be created!\n");
+ return IPHONE_E_UNKNOWN_ERROR;
+ }
if (IPHONE_E_SUCCESS != lockdownd_hello(client_loc)) {
log_debug_msg("Hello failed in the lockdownd client.\n");
ret = IPHONE_E_NOT_ENOUGH_DATA;
@@ -969,77 +971,53 @@ ssize_t lockdownd_secuwrite(gnutls_transport_ptr_t transport, char *buffer, size
ssize_t lockdownd_securead(gnutls_transport_ptr_t transport, char *buffer, size_t length)
{
int bytes = 0, pos_start_fill = 0;
- char *hackhackhack = NULL;
+ int tbytes = 0;
+ int this_len = length;
+ iphone_error_t res;
iphone_lckd_client_t control;
control = (iphone_lckd_client_t) transport;
+ char *recv_buffer;
+
log_debug_msg("lockdownd_securead() called\nlength = %zi\n", length);
- // Buffering hack! Throw what we've got in our "buffer" into the stream first, then get more.
- if (control->gtls_buffer_hack_len > 0) {
- if (length > control->gtls_buffer_hack_len) { // If it's asking for more than we got
- length -= control->gtls_buffer_hack_len; // Subtract what we have from their requested length
- pos_start_fill = control->gtls_buffer_hack_len; // set the pos to start filling at
- memcpy(buffer, control->gtls_buffer_hack, control->gtls_buffer_hack_len); // Fill their buffer partially
- free(control->gtls_buffer_hack); // free our memory, it's not chained anymore
- control->gtls_buffer_hack_len = 0; // we don't have a hack buffer anymore
- log_debug_msg("Did a partial fill to help quench thirst for data\n");
- } else if (length < control->gtls_buffer_hack_len) { // If it's asking for less...
- control->gtls_buffer_hack_len -= length; // subtract what they're asking for
- memcpy(buffer, control->gtls_buffer_hack, length); // fill their buffer
- hackhackhack = (char *) malloc(sizeof(char) * control->gtls_buffer_hack_len); // strndup is NOT a good solution -- concatenates \0!!!! Anyway, make a new "hack" buffer.
- memcpy(hackhackhack, control->gtls_buffer_hack + length, control->gtls_buffer_hack_len); // Move what's left into the new one
- free(control->gtls_buffer_hack); // Free the old one
- control->gtls_buffer_hack = hackhackhack; // And make it the new one.
- hackhackhack = NULL;
- log_debug_msg("Quenched the thirst for data; new hack length is %i\n", control->gtls_buffer_hack_len);
- return length; // hand it over.
- } else { // length == hack length
- memcpy(buffer, control->gtls_buffer_hack, length); // copy our buffer into theirs
- free(control->gtls_buffer_hack); // free our "obligation"
- control->gtls_buffer_hack_len = 0; // free our "obligation"
- log_debug_msg("Satiated the thirst for data; now we have to eventually receive again.\n");
- return length; // hand it over
- }
- }
- // End buffering hack!
- char *recv_buffer = (char *) malloc(sizeof(char) * (length * 1000)); // ensuring nothing stupid happens
log_debug_msg("pre-read\nclient wants %zi bytes\n", length);
- iphone_mux_recv(control->connection, recv_buffer, (length * 1000), &bytes);
- log_debug_msg("post-read\nwe got %i bytes\n", bytes);
- if (bytes < 0) {
- log_debug_msg("lockdownd_securead(): uh oh\n");
- log_debug_msg
- ("I believe what we have here is a failure to communicate... libusb says %s but strerror says %s\n",
- usb_strerror(), strerror(errno));
- return bytes + 28; // an errno
- }
- if (bytes >= length) {
- if (bytes > length) {
+
+ recv_buffer = (char *) malloc(sizeof(char) * this_len);
+
+ // repeat until we have the full data or an error occurs.
+ do {
+ if ((res = iphone_mux_recv(control->connection, recv_buffer, this_len, &bytes)) != IPHONE_E_SUCCESS) {
+ log_debug_msg("%s: ERROR: iphone_mux_recv returned %d\n", __func__, res);
+ return res;
+ }
+ log_debug_msg("post-read\nwe got %i bytes\n", bytes);
+
+ if (bytes < 0) {
+ log_debug_msg("lockdownd_securead(): uh oh\n");
log_debug_msg
- ("lockdownd_securead: Client deliberately read less data than was there; resorting to GnuTLS buffering hack.\n");
- if (!control->gtls_buffer_hack_len) { // if there's no hack buffer yet
- //control->gtls_buffer_hack = strndup(recv_buffer+length, bytes-length); // strndup is NOT a good solution!
- control->gtls_buffer_hack_len += bytes - length;
- control->gtls_buffer_hack = (char *) malloc(sizeof(char) * control->gtls_buffer_hack_len);
- memcpy(control->gtls_buffer_hack, recv_buffer + length, control->gtls_buffer_hack_len);
- } else { // if there is.
- control->gtls_buffer_hack =
- realloc(control->gtls_buffer_hack, control->gtls_buffer_hack_len + (bytes - length));
- memcpy(control->gtls_buffer_hack + control->gtls_buffer_hack_len, recv_buffer + length, bytes - length);
- control->gtls_buffer_hack_len += bytes - length;
- }
+ ("I believe what we have here is a failure to communicate... libusb says %s but strerror says %s\n",
+ usb_strerror(), strerror(errno));
+ return bytes; // + 28; // an errno
}
- memcpy(buffer + pos_start_fill, recv_buffer, length);
- free(recv_buffer);
- if (bytes == length) {
- log_debug_msg("Returning how much we received.\n");
- return bytes;
- } else {
- log_debug_msg("Returning what they want to hear.\nHack length: %i\n", control->gtls_buffer_hack_len);
- return length;
+ // 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("re-read\ntrying to read missing %i bytes\n", this_len);
+ } while (tbytes < length);
+ if (recv_buffer) {
+ free(recv_buffer);
}
- return bytes;
+
+ return tbytes;
}
/** Command to start the desired service