diff options
| author | 2009-07-26 19:34:22 -0700 | |
|---|---|---|
| committer | 2009-07-26 19:34:22 -0700 | |
| commit | eea538c94f01f8054f69f059614f19400187a472 (patch) | |
| tree | 209a12dc8c8eaece15b8153d15e689c8c2147ab6 /src | |
| parent | 8ebfd7d8eea89bb27e4e6dbb1f37fd90d98b439c (diff) | |
| parent | 19c9750d670435ce430f0fc85a55faf127bdfbf9 (diff) | |
| download | libimobiledevice-eea538c94f01f8054f69f059614f19400187a472.tar.gz libimobiledevice-eea538c94f01f8054f69f059614f19400187a472.tar.bz2 | |
Merge commit 'martin-s/martin'
[#46 state:resolved]
Diffstat (limited to 'src')
| -rw-r--r-- | src/AFC.c | 703 | ||||
| -rw-r--r-- | src/AFC.h | 61 | ||||
| -rw-r--r-- | src/MobileSync.c | 55 | ||||
| -rw-r--r-- | src/MobileSync.h | 4 | ||||
| -rw-r--r-- | src/NotificationProxy.c | 100 | ||||
| -rw-r--r-- | src/NotificationProxy.h | 12 | ||||
| -rw-r--r-- | src/iphone.c | 37 | ||||
| -rw-r--r-- | src/iphone.h | 2 | ||||
| -rw-r--r-- | src/lockdown.c | 463 | ||||
| -rw-r--r-- | src/lockdown.h | 10 | ||||
| -rw-r--r-- | src/userpref.c | 164 | ||||
| -rw-r--r-- | src/userpref.h | 22 | ||||
| -rw-r--r-- | src/utils.c | 8 | ||||
| -rw-r--r-- | src/utils.h | 5 |
14 files changed, 811 insertions, 835 deletions
| @@ -21,15 +21,12 @@ | |||
| 21 | 21 | ||
| 22 | #include <stdio.h> | 22 | #include <stdio.h> |
| 23 | #include <stdlib.h> | 23 | #include <stdlib.h> |
| 24 | #include <errno.h> | ||
| 25 | #include <unistd.h> | 24 | #include <unistd.h> |
| 25 | |||
| 26 | #include "AFC.h" | 26 | #include "AFC.h" |
| 27 | #include "iphone.h" | 27 | #include "iphone.h" |
| 28 | #include "utils.h" | 28 | #include "utils.h" |
| 29 | 29 | ||
| 30 | #include <libiphone/afc.h> | ||
| 31 | |||
| 32 | |||
| 33 | // This is the maximum size an AFC data packet can be | 30 | // This is the maximum size an AFC data packet can be |
| 34 | const int MAXIMUM_PACKET_SIZE = (2 << 15); | 31 | const int MAXIMUM_PACKET_SIZE = (2 << 15); |
| 35 | 32 | ||
| @@ -39,11 +36,7 @@ const int MAXIMUM_PACKET_SIZE = (2 << 15); | |||
| 39 | */ | 36 | */ |
| 40 | static void afc_lock(afc_client_t client) | 37 | static void afc_lock(afc_client_t client) |
| 41 | { | 38 | { |
| 42 | log_debug_msg("Locked\n"); | 39 | log_debug_msg("%s: Locked\n", __func__); |
| 43 | /*while (client->lock) { | ||
| 44 | usleep(500); // they say it's obsolete, but whatever | ||
| 45 | } | ||
| 46 | client->lock = 1; */ | ||
| 47 | g_mutex_lock(client->mutex); | 40 | g_mutex_lock(client->mutex); |
| 48 | } | 41 | } |
| 49 | 42 | ||
| @@ -52,9 +45,8 @@ static void afc_lock(afc_client_t client) | |||
| 52 | * @param client The AFC | 45 | * @param client The AFC |
| 53 | */ | 46 | */ |
| 54 | static void afc_unlock(afc_client_t client) | 47 | static void afc_unlock(afc_client_t client) |
| 55 | { // just to be pretty | 48 | { |
| 56 | log_debug_msg("Unlocked\n"); | 49 | log_debug_msg("%s: Unlocked\n", __func__); |
| 57 | //client->lock = 0; | ||
| 58 | g_mutex_unlock(client->mutex); | 50 | g_mutex_unlock(client->mutex); |
| 59 | } | 51 | } |
| 60 | 52 | ||
| @@ -66,30 +58,30 @@ static void afc_unlock(afc_client_t client) | |||
| 66 | * | 58 | * |
| 67 | * @return A handle to the newly-connected client or NULL upon error. | 59 | * @return A handle to the newly-connected client or NULL upon error. |
| 68 | */ | 60 | */ |
| 69 | iphone_error_t afc_new_client(iphone_device_t device, int dst_port, afc_client_t * client) | 61 | afc_error_t afc_client_new(iphone_device_t device, int dst_port, afc_client_t * client) |
| 70 | { | 62 | { |
| 71 | //makes sure thread environment is available | 63 | /* makes sure thread environment is available */ |
| 72 | if (!g_thread_supported()) | 64 | if (!g_thread_supported()) |
| 73 | g_thread_init(NULL); | 65 | g_thread_init(NULL); |
| 74 | 66 | ||
| 75 | if (!device) | 67 | if (!device) |
| 76 | return IPHONE_E_INVALID_ARG; | 68 | return AFC_E_INVALID_ARGUMENT; |
| 77 | 69 | ||
| 78 | // Attempt connection | 70 | /* attempt connection */ |
| 79 | int sfd = usbmuxd_connect(device->handle, dst_port); | 71 | int sfd = usbmuxd_connect(device->handle, dst_port); |
| 80 | if (sfd < 0) { | 72 | if (sfd < 0) { |
| 81 | return IPHONE_E_UNKNOWN_ERROR; // ret; | 73 | return AFC_E_MUX_ERROR; |
| 82 | } | 74 | } |
| 83 | 75 | ||
| 84 | afc_client_t client_loc = (afc_client_t) malloc(sizeof(struct afc_client_int)); | 76 | afc_client_t client_loc = (afc_client_t) malloc(sizeof(struct afc_client_int)); |
| 85 | client_loc->sfd = sfd; | 77 | client_loc->sfd = sfd; |
| 86 | 78 | ||
| 87 | // Allocate a packet | 79 | /* allocate a packet */ |
| 88 | client_loc->afc_packet = (AFCPacket *) malloc(sizeof(AFCPacket)); | 80 | client_loc->afc_packet = (AFCPacket *) malloc(sizeof(AFCPacket)); |
| 89 | if (!client_loc->afc_packet) { | 81 | if (!client_loc->afc_packet) { |
| 90 | usbmuxd_disconnect(client_loc->sfd); | 82 | usbmuxd_disconnect(client_loc->sfd); |
| 91 | free(client_loc); | 83 | free(client_loc); |
| 92 | return IPHONE_E_UNKNOWN_ERROR; | 84 | return AFC_E_NO_MEM; |
| 93 | } | 85 | } |
| 94 | 86 | ||
| 95 | client_loc->afc_packet->packet_num = 0; | 87 | client_loc->afc_packet->packet_num = 0; |
| @@ -101,17 +93,17 @@ iphone_error_t afc_new_client(iphone_device_t device, int dst_port, afc_client_t | |||
| 101 | client_loc->mutex = g_mutex_new(); | 93 | client_loc->mutex = g_mutex_new(); |
| 102 | 94 | ||
| 103 | *client = client_loc; | 95 | *client = client_loc; |
| 104 | return IPHONE_E_SUCCESS; | 96 | return AFC_E_SUCCESS; |
| 105 | } | 97 | } |
| 106 | 98 | ||
| 107 | /** Disconnects an AFC client from the phone. | 99 | /** Disconnects an AFC client from the phone. |
| 108 | * | 100 | * |
| 109 | * @param client The client to disconnect. | 101 | * @param client The client to disconnect. |
| 110 | */ | 102 | */ |
| 111 | iphone_error_t afc_free_client(afc_client_t client) | 103 | afc_error_t afc_client_free(afc_client_t client) |
| 112 | { | 104 | { |
| 113 | if (!client || client->sfd < 0 || !client->afc_packet) | 105 | if (!client || client->sfd < 0 || !client->afc_packet) |
| 114 | return IPHONE_E_INVALID_ARG; | 106 | return AFC_E_INVALID_ARGUMENT; |
| 115 | 107 | ||
| 116 | usbmuxd_disconnect(client->sfd); | 108 | usbmuxd_disconnect(client->sfd); |
| 117 | free(client->afc_packet); | 109 | free(client->afc_packet); |
| @@ -119,88 +111,7 @@ iphone_error_t afc_free_client(afc_client_t client) | |||
| 119 | g_mutex_free(client->mutex); | 111 | g_mutex_free(client->mutex); |
| 120 | } | 112 | } |
| 121 | free(client); | 113 | free(client); |
| 122 | return IPHONE_E_SUCCESS; | 114 | return AFC_E_SUCCESS; |
| 123 | } | ||
| 124 | |||
| 125 | /** | ||
| 126 | * Returns the AFC error code that has been sent by the device if | ||
| 127 | * an error occured (set inside receive_AFC_data) | ||
| 128 | * | ||
| 129 | * @param client AFC client for that the error value is to be retrieved. | ||
| 130 | * | ||
| 131 | * @return AFC error code or -1 on error. | ||
| 132 | */ | ||
| 133 | int afc_get_afcerror(afc_client_t client) | ||
| 134 | { | ||
| 135 | int res = -1; | ||
| 136 | if (client) { | ||
| 137 | afc_lock(client); | ||
| 138 | res = client->afcerror; | ||
| 139 | afc_unlock(client); | ||
| 140 | } | ||
| 141 | return res; | ||
| 142 | } | ||
| 143 | |||
| 144 | /** | ||
| 145 | * Tries to convert the AFC error value into a meaningful errno value. | ||
| 146 | * Internally used by afc_get_errno. | ||
| 147 | * | ||
| 148 | * @param afcerror AFC error value to convert | ||
| 149 | * | ||
| 150 | * @return errno value or -1 if the errno could not be determined. | ||
| 151 | * | ||
| 152 | * @see afc_get_errno | ||
| 153 | */ | ||
| 154 | static int afcerror_to_errno(int afcerror) | ||
| 155 | { | ||
| 156 | int res = -1; | ||
| 157 | switch (afcerror) { | ||
| 158 | case 0: // ERROR_SUCCESS, this means no error. | ||
| 159 | res = 0; | ||
| 160 | break; | ||
| 161 | case 4: // occurs if you try to open a file as directory | ||
| 162 | res = ENOTDIR; | ||
| 163 | break; | ||
| 164 | case 7: // occurs e.g. if you try to close a file handle that | ||
| 165 | // does not belong to an open file | ||
| 166 | res = EINVAL; | ||
| 167 | break; | ||
| 168 | case 8: // occurs if you try to open a non-existent file | ||
| 169 | res = ENOENT; | ||
| 170 | break; | ||
| 171 | case 9: // occurs if you try to open a directory as file | ||
| 172 | res = EISDIR; | ||
| 173 | break; | ||
| 174 | case 10: // occurs if you try to open a file without permission | ||
| 175 | res = EPERM; | ||
| 176 | break; | ||
| 177 | default: // we'll assume it's an errno value, but report it | ||
| 178 | log_debug_msg("WARNING: unknown AFC error %d, perhaps it's '%s'?\n", afcerror, strerror(afcerror)); | ||
| 179 | res = afcerror; | ||
| 180 | break; | ||
| 181 | } | ||
| 182 | |||
| 183 | log_debug_msg("Mapped AFC error %d to errno %d: %s\n", afcerror, res, strerror(res)); | ||
| 184 | |||
| 185 | return res; | ||
| 186 | } | ||
| 187 | |||
| 188 | /** | ||
| 189 | * Returns the client's AFC error code converted to an errno value. | ||
| 190 | * | ||
| 191 | * @param client AFC client for that the errno value is to be retrieved. | ||
| 192 | * | ||
| 193 | * @return errno value or -1 on error. | ||
| 194 | */ | ||
| 195 | int afc_get_errno(afc_client_t client) | ||
| 196 | { | ||
| 197 | int res = -1; | ||
| 198 | if (client) { | ||
| 199 | afc_lock(client); | ||
| 200 | res = afcerror_to_errno(client->afcerror); | ||
| 201 | afc_unlock(client); | ||
| 202 | } | ||
| 203 | return res; | ||
| 204 | } | 115 | } |
| 205 | 116 | ||
| 206 | /** Dispatches an AFC packet over a client. | 117 | /** Dispatches an AFC packet over a client. |
| @@ -216,13 +127,14 @@ int afc_get_errno(afc_client_t client) | |||
| 216 | * reason is that if you set them to different values, it indicates | 127 | * reason is that if you set them to different values, it indicates |
| 217 | * you want to send the data as two packets. | 128 | * you want to send the data as two packets. |
| 218 | */ | 129 | */ |
| 219 | static int dispatch_AFC_packet(afc_client_t client, const char *data, uint64_t length) | 130 | static int afc_dispatch_packet(afc_client_t client, const char *data, uint64_t length) |
| 220 | { | 131 | { |
| 221 | int bytes = 0, offset = 0; | 132 | int bytes = 0, offset = 0; |
| 222 | char *buffer; | 133 | char *buffer; |
| 223 | 134 | ||
| 224 | if (!client || client->sfd < 0 || !client->afc_packet) | 135 | if (!client || client->sfd < 0 || !client->afc_packet) |
| 225 | return 0; | 136 | return 0; |
| 137 | |||
| 226 | if (!data || !length) | 138 | if (!data || !length) |
| 227 | length = 0; | 139 | length = 0; |
| 228 | 140 | ||
| @@ -242,12 +154,12 @@ static int dispatch_AFC_packet(afc_client_t client, const char *data, uint64_t l | |||
| 242 | memcpy(buffer, (char *) client->afc_packet, sizeof(AFCPacket)); | 154 | memcpy(buffer, (char *) client->afc_packet, sizeof(AFCPacket)); |
| 243 | offset = client->afc_packet->this_length - sizeof(AFCPacket); | 155 | offset = client->afc_packet->this_length - sizeof(AFCPacket); |
| 244 | 156 | ||
| 245 | log_debug_msg("dispatch_AFC_packet: Offset: %i\n", offset); | 157 | log_debug_msg("%s: Offset: %i\n", __func__, offset); |
| 246 | if ((length) < (client->afc_packet->entire_length - client->afc_packet->this_length)) { | 158 | if ((length) < (client->afc_packet->entire_length - client->afc_packet->this_length)) { |
| 247 | log_debug_msg("dispatch_AFC_packet: Length did not resemble what it was supposed"); | 159 | log_debug_msg("%s: Length did not resemble what it was supposed", __func__); |
| 248 | log_debug_msg("to based on the packet.\n"); | 160 | log_debug_msg("to based on the packet.\n"); |
| 249 | log_debug_msg("length minus offset: %i\n", length - offset); | 161 | log_debug_msg("%s: length minus offset: %i\n", __func__, length - offset); |
| 250 | log_debug_msg("rest of packet: %i\n", client->afc_packet->entire_length - client->afc_packet->this_length); | 162 | log_debug_msg("%s: rest of packet: %i\n", __func__, client->afc_packet->entire_length - client->afc_packet->this_length); |
| 251 | free(buffer); | 163 | free(buffer); |
| 252 | return -1; | 164 | return -1; |
| 253 | } | 165 | } |
| @@ -258,19 +170,19 @@ static int dispatch_AFC_packet(afc_client_t client, const char *data, uint64_t l | |||
| 258 | return bytes; | 170 | return bytes; |
| 259 | } | 171 | } |
| 260 | 172 | ||
| 261 | log_debug_msg("dispatch_AFC_packet: sent the first now go with the second\n"); | 173 | log_debug_msg("%s: sent the first now go with the second\n", __func__); |
| 262 | log_debug_msg("Length: %i\n", length - offset); | 174 | log_debug_msg("%s: Length: %i\n", __func__, length - offset); |
| 263 | log_debug_msg("Buffer: \n"); | 175 | log_debug_msg("%s: Buffer: \n", __func__); |
| 264 | log_debug_buffer(data + offset, length - offset); | 176 | log_debug_buffer(data + offset, length - offset); |
| 265 | 177 | ||
| 266 | usbmuxd_send(client->sfd, data + offset, length - offset, (uint32_t*)&bytes); | 178 | usbmuxd_send(client->sfd, data + offset, length - offset, (uint32_t*)&bytes); |
| 267 | return bytes; | 179 | return bytes; |
| 268 | } else { | 180 | } else { |
| 269 | log_debug_msg("dispatch_AFC_packet doin things the old way\n"); | 181 | log_debug_msg("%s: doin things the old way\n", __func__); |
| 270 | buffer = (char *) malloc(sizeof(char) * client->afc_packet->this_length); | 182 | buffer = (char *) malloc(sizeof(char) * client->afc_packet->this_length); |
| 271 | log_debug_msg("dispatch_AFC_packet packet length = %i\n", client->afc_packet->this_length); | 183 | log_debug_msg("%s: packet length = %i\n", __func__, client->afc_packet->this_length); |
| 272 | memcpy(buffer, (char *) client->afc_packet, sizeof(AFCPacket)); | 184 | memcpy(buffer, (char *) client->afc_packet, sizeof(AFCPacket)); |
| 273 | log_debug_msg("dispatch_AFC_packet packet data follows\n"); | 185 | log_debug_msg("%s: packet data follows\n", __func__); |
| 274 | if (length > 0) { | 186 | if (length > 0) { |
| 275 | memcpy(buffer + sizeof(AFCPacket), data, length); | 187 | memcpy(buffer + sizeof(AFCPacket), data, length); |
| 276 | } | 188 | } |
| @@ -297,83 +209,81 @@ static int dispatch_AFC_packet(afc_client_t client, const char *data, uint64_t l | |||
| 297 | * received raised a non-trivial error condition (i.e. non-zero with | 209 | * received raised a non-trivial error condition (i.e. non-zero with |
| 298 | * AFC_ERROR operation) | 210 | * AFC_ERROR operation) |
| 299 | */ | 211 | */ |
| 300 | static int receive_AFC_data(afc_client_t client, char **dump_here) | 212 | static afc_error_t afc_receive_data(afc_client_t client, char **dump_here, int *bytes) |
| 301 | { | 213 | { |
| 302 | AFCPacket header; | 214 | AFCPacket header; |
| 303 | int bytes = 0; | ||
| 304 | uint32_t entire_len = 0; | 215 | uint32_t entire_len = 0; |
| 305 | uint32_t this_len = 0; | 216 | uint32_t this_len = 0; |
| 306 | uint32_t current_count = 0; | 217 | uint32_t current_count = 0; |
| 307 | uint64_t param1 = -1; | 218 | uint64_t param1 = -1; |
| 308 | 219 | ||
| 309 | // reset internal afc error value | 220 | *bytes = 0; |
| 310 | client->afcerror = 0; | ||
| 311 | 221 | ||
| 312 | // first, read the AFC header | 222 | /* first, read the AFC header */ |
| 313 | usbmuxd_recv(client->sfd, (char*)&header, sizeof(AFCPacket), (uint32_t*)&bytes); | 223 | usbmuxd_recv(client->sfd, (char*)&header, sizeof(AFCPacket), (uint32_t*)bytes); |
| 314 | if (bytes <= 0) { | 224 | if (*bytes <= 0) { |
| 315 | log_debug_msg("%s: Just didn't get enough.\n", __func__); | 225 | log_debug_msg("%s: Just didn't get enough.\n", __func__); |
| 316 | *dump_here = NULL; | 226 | *dump_here = NULL; |
| 317 | return -1; | 227 | return AFC_E_MUX_ERROR; |
| 318 | } else if ((uint32_t)bytes < sizeof(AFCPacket)) { | 228 | } else if ((uint32_t)*bytes < sizeof(AFCPacket)) { |
| 319 | log_debug_msg("%s: Did not even get the AFCPacket header\n", __func__); | 229 | log_debug_msg("%s: Did not even get the AFCPacket header\n", __func__); |
| 320 | *dump_here = NULL; | 230 | *dump_here = NULL; |
| 321 | return -1; | 231 | return AFC_E_MUX_ERROR; |
| 322 | } | 232 | } |
| 323 | 233 | ||
| 324 | // check if it's a valid AFC header | 234 | /* check if it's a valid AFC header */ |
| 325 | if (strncmp(header.magic, AFC_MAGIC, AFC_MAGIC_LEN)) { | 235 | if (strncmp(header.magic, AFC_MAGIC, AFC_MAGIC_LEN)) { |
| 326 | log_debug_msg("%s: Invalid AFC packet received (magic != " AFC_MAGIC ")!\n", __func__); | 236 | log_debug_msg("%s: Invalid AFC packet received (magic != " AFC_MAGIC ")!\n", __func__); |
| 327 | } | 237 | } |
| 328 | 238 | ||
| 329 | // check if it has the correct packet number | 239 | /* check if it has the correct packet number */ |
| 330 | if (header.packet_num != client->afc_packet->packet_num) { | 240 | if (header.packet_num != client->afc_packet->packet_num) { |
| 331 | // otherwise print a warning but do not abort | 241 | /* otherwise print a warning but do not abort */ |
| 332 | log_debug_msg("%s: ERROR: Unexpected packet number (%lld != %lld) aborting.\n", __func__, header.packet_num, client->afc_packet->packet_num); | 242 | log_debug_msg("%s: ERROR: Unexpected packet number (%lld != %lld) aborting.\n", __func__, header.packet_num, client->afc_packet->packet_num); |
| 333 | *dump_here = NULL; | 243 | *dump_here = NULL; |
| 334 | return -1; | 244 | return AFC_E_OP_HEADER_INVALID; |
| 335 | } | 245 | } |
| 336 | 246 | ||
| 337 | // then, read the attached packet | 247 | /* then, read the attached packet */ |
| 338 | if (header.this_length < sizeof(AFCPacket)) { | 248 | if (header.this_length < sizeof(AFCPacket)) { |
| 339 | log_debug_msg("%s: Invalid AFCPacket header received!\n", __func__); | 249 | log_debug_msg("%s: Invalid AFCPacket header received!\n", __func__); |
| 340 | *dump_here = NULL; | 250 | *dump_here = NULL; |
| 341 | return -1; | 251 | return AFC_E_OP_HEADER_INVALID; |
| 342 | } else if ((header.this_length == header.entire_length) | 252 | } else if ((header.this_length == header.entire_length) |
| 343 | && header.entire_length == sizeof(AFCPacket)) { | 253 | && header.entire_length == sizeof(AFCPacket)) { |
| 344 | log_debug_msg("%s: Empty AFCPacket received!\n", __func__); | 254 | log_debug_msg("%s: Empty AFCPacket received!\n", __func__); |
| 345 | *dump_here = NULL; | 255 | *dump_here = NULL; |
| 346 | if (header.operation == AFC_SUCCESS_RESPONSE) { | 256 | *bytes = 0; |
| 347 | return 0; | 257 | if (header.operation == AFC_OP_DATA) { |
| 258 | return AFC_E_SUCCESS; | ||
| 348 | } else { | 259 | } else { |
| 349 | client->afcerror = EIO; | 260 | return AFC_E_IO_ERROR; |
| 350 | return -1; | ||
| 351 | } | 261 | } |
| 352 | } | 262 | } |
| 353 | 263 | ||
| 354 | log_debug_msg("%s: received AFC packet, full len=%lld, this len=%lld, operation=%lld\n", __func__, header.entire_length, header.this_length, header.operation); | 264 | log_debug_msg("%s: received AFC packet, full len=%lld, this len=%lld, operation=0x%llx\n", __func__, header.entire_length, header.this_length, header.operation); |
| 355 | 265 | ||
| 356 | entire_len = (uint32_t)header.entire_length - sizeof(AFCPacket); | 266 | entire_len = (uint32_t)header.entire_length - sizeof(AFCPacket); |
| 357 | this_len = (uint32_t)header.this_length - sizeof(AFCPacket); | 267 | this_len = (uint32_t)header.this_length - sizeof(AFCPacket); |
| 358 | 268 | ||
| 359 | // this is here as a check (perhaps a different upper limit is good?) | 269 | /* this is here as a check (perhaps a different upper limit is good?) */ |
| 360 | if (entire_len > (uint32_t)MAXIMUM_PACKET_SIZE) { | 270 | if (entire_len > (uint32_t)MAXIMUM_PACKET_SIZE) { |
| 361 | fprintf(stderr, "%s: entire_len is larger than MAXIMUM_PACKET_SIZE, (%d > %d)!\n", __func__, entire_len, MAXIMUM_PACKET_SIZE); | 271 | fprintf(stderr, "%s: entire_len is larger than MAXIMUM_PACKET_SIZE, (%d > %d)!\n", __func__, entire_len, MAXIMUM_PACKET_SIZE); |
| 362 | } | 272 | } |
| 363 | 273 | ||
| 364 | *dump_here = (char*)malloc(entire_len); | 274 | *dump_here = (char*)malloc(entire_len); |
| 365 | if (this_len > 0) { | 275 | if (this_len > 0) { |
| 366 | usbmuxd_recv(client->sfd, *dump_here, this_len, (uint32_t*)&bytes); | 276 | usbmuxd_recv(client->sfd, *dump_here, this_len, (uint32_t*)bytes); |
| 367 | if (bytes <= 0) { | 277 | if (*bytes <= 0) { |
| 368 | free(*dump_here); | 278 | free(*dump_here); |
| 369 | *dump_here = NULL; | 279 | *dump_here = NULL; |
| 370 | log_debug_msg("%s: Did not get packet contents!\n", __func__); | 280 | log_debug_msg("%s: Did not get packet contents!\n", __func__); |
| 371 | return -1; | 281 | return AFC_E_NOT_ENOUGH_DATA; |
| 372 | } else if ((uint32_t)bytes < this_len) { | 282 | } else if ((uint32_t)*bytes < this_len) { |
| 373 | free(*dump_here); | 283 | free(*dump_here); |
| 374 | *dump_here = NULL; | 284 | *dump_here = NULL; |
| 375 | log_debug_msg("%s: Could not receive this_len=%d bytes\n", __func__, this_len); | 285 | log_debug_msg("%s: Could not receive this_len=%d bytes\n", __func__, this_len); |
| 376 | return -1; | 286 | return AFC_E_NOT_ENOUGH_DATA; |
| 377 | } | 287 | } |
| 378 | } | 288 | } |
| 379 | 289 | ||
| @@ -381,12 +291,12 @@ static int receive_AFC_data(afc_client_t client, char **dump_here) | |||
| 381 | 291 | ||
| 382 | if (entire_len > this_len) { | 292 | if (entire_len > this_len) { |
| 383 | while (current_count < entire_len) { | 293 | while (current_count < entire_len) { |
| 384 | usbmuxd_recv(client->sfd, (*dump_here)+current_count, entire_len - current_count, (uint32_t*)&bytes); | 294 | usbmuxd_recv(client->sfd, (*dump_here)+current_count, entire_len - current_count, (uint32_t*)bytes); |
| 385 | if (bytes <= 0) { | 295 | if (*bytes <= 0) { |
| 386 | log_debug_msg("%s: Error receiving data (recv returned %d)\n", __func__, bytes); | 296 | log_debug_msg("%s: Error receiving data (recv returned %d)\n", __func__, *bytes); |
| 387 | break; | 297 | break; |
| 388 | } | 298 | } |
| 389 | current_count += bytes; | 299 | current_count += *bytes; |
| 390 | } | 300 | } |
| 391 | if (current_count < entire_len) { | 301 | if (current_count < entire_len) { |
| 392 | log_debug_msg("%s: WARNING: could not receive full packet (read %s, size %d)\n", __func__, current_count, entire_len); | 302 | log_debug_msg("%s: WARNING: could not receive full packet (read %s, size %d)\n", __func__, current_count, entire_len); |
| @@ -397,39 +307,45 @@ static int receive_AFC_data(afc_client_t client, char **dump_here) | |||
| 397 | param1 = *(uint64_t*)(*dump_here); | 307 | param1 = *(uint64_t*)(*dump_here); |
| 398 | } | 308 | } |
| 399 | 309 | ||
| 400 | // check for errors | 310 | log_debug_msg("%s: packet data size = %i\n", __func__, current_count); |
| 401 | if (header.operation == AFC_SUCCESS_RESPONSE) { | 311 | log_debug_msg("%s: packet data follows\n", __func__); |
| 402 | // we got a positive response! | 312 | log_debug_buffer(*dump_here, current_count); |
| 403 | log_debug_msg("%s: got a success response\n", __func__); | 313 | |
| 404 | } else if (header.operation == AFC_FILE_HANDLE) { | 314 | /* check operation types */ |
| 405 | // we got a file handle response | 315 | if (header.operation == AFC_OP_STATUS) { |
| 406 | log_debug_msg("%s: got a file handle response, handle=%lld\n", __func__, param1); | 316 | /* status response */ |
| 407 | } else if (header.operation == AFC_ERROR) { | 317 | log_debug_msg("%s: got a status response, code=%lld\n", __func__, param1); |
| 408 | // error message received | 318 | |
| 409 | if (param1 == 0) { | 319 | if (param1 != AFC_E_SUCCESS) { |
| 410 | // ERROR_SUCCESS, this is not an error! | 320 | /* error status */ |
| 411 | log_debug_msg("%s: ERROR_SUCCESS\n", __func__); | 321 | /* free buffer */ |
| 412 | } else { | ||
| 413 | // but this is an error! | ||
| 414 | log_debug_msg("%s: ERROR %lld\n", __func__, param1); | ||
| 415 | free(*dump_here); | 322 | free(*dump_here); |
| 416 | *dump_here = NULL; | 323 | *dump_here = NULL; |
| 417 | // store error value | 324 | return (afc_error_t)param1; |
| 418 | client->afcerror = (int)param1; | ||
| 419 | afcerror_to_errno(client->afcerror); | ||
| 420 | return -1; | ||
| 421 | } | 325 | } |
| 326 | } else if (header.operation == AFC_OP_DATA) { | ||
| 327 | /* data response */ | ||
| 328 | log_debug_msg("%s: got a data response\n", __func__); | ||
| 329 | } else if (header.operation == AFC_OP_FILE_OPEN_RES) { | ||
| 330 | /* file handle response */ | ||
| 331 | log_debug_msg("%s: got a file handle response, handle=%lld\n", __func__, param1); | ||
| 332 | } else if (header.operation == AFC_OP_FILE_TELL_RES) { | ||
| 333 | /* tell response */ | ||
| 334 | log_debug_msg("%s: got a tell response, position=%lld\n", __func__, param1); | ||
| 422 | } else { | 335 | } else { |
| 423 | // unknown operation code received! | 336 | /* unknown operation code received */ |
| 424 | free(*dump_here); | 337 | free(*dump_here); |
| 425 | *dump_here = NULL; | 338 | *dump_here = NULL; |
| 339 | *bytes = 0; | ||
| 426 | 340 | ||
| 427 | log_debug_msg("%s: WARNING: Unknown operation code received 0x%llx param1=%lld\n", __func__, header.operation, param1); | 341 | log_debug_msg("%s: WARNING: Unknown operation code received 0x%llx param1=%lld\n", __func__, header.operation, param1); |
| 428 | fprintf(stderr, "%s: WARNING: Unknown operation code received 0x%llx param1=%lld\n", __func__, (long long)header.operation, (long long)param1); | 342 | fprintf(stderr, "%s: WARNING: Unknown operation code received 0x%llx param1=%lld\n", __func__, (long long)header.operation, (long long)param1); |
| 429 | 343 | ||
| 430 | return -1; | 344 | return AFC_E_OP_NOT_SUPPORTED; |
| 431 | } | 345 | } |
| 432 | return current_count; | 346 | |
| 347 | *bytes = current_count; | ||
| 348 | return AFC_E_SUCCESS; | ||
| 433 | } | 349 | } |
| 434 | 350 | ||
| 435 | static int count_nullspaces(char *string, int number) | 351 | static int count_nullspaces(char *string, int number) |
| @@ -471,36 +387,34 @@ static char **make_strings_list(char *tokens, int true_length) | |||
| 471 | * @return A char ** list of files in that directory, terminated by an empty | 387 | * @return A char ** list of files in that directory, terminated by an empty |
| 472 | * string for now or NULL if there was an error. | 388 | * string for now or NULL if there was an error. |
| 473 | */ | 389 | */ |
| 474 | iphone_error_t afc_get_dir_list(afc_client_t client, const char *dir, char ***list) | 390 | afc_error_t afc_read_directory(afc_client_t client, const char *dir, char ***list) |
| 475 | { | 391 | { |
| 476 | int bytes = 0; | 392 | int bytes = 0; |
| 477 | char *data = NULL, **list_loc = NULL; | 393 | char *data = NULL, **list_loc = NULL; |
| 478 | iphone_error_t ret = IPHONE_E_UNKNOWN_ERROR; | 394 | afc_error_t ret = AFC_E_UNKNOWN_ERROR; |
| 479 | 395 | ||
| 480 | if (!client || !dir || !list || (list && *list)) | 396 | if (!client || !dir || !list || (list && *list)) |
| 481 | return IPHONE_E_INVALID_ARG; | 397 | return AFC_E_INVALID_ARGUMENT; |
| 482 | 398 | ||
| 483 | afc_lock(client); | 399 | afc_lock(client); |
| 484 | 400 | ||
| 485 | // Send the command | 401 | // Send the command |
| 486 | client->afc_packet->operation = AFC_LIST_DIR; | 402 | client->afc_packet->operation = AFC_OP_READ_DIR; |
| 487 | client->afc_packet->entire_length = 0; | 403 | client->afc_packet->entire_length = 0; |
| 488 | client->afc_packet->this_length = 0; | 404 | client->afc_packet->this_length = 0; |
| 489 | bytes = dispatch_AFC_packet(client, dir, strlen(dir)+1); | 405 | bytes = afc_dispatch_packet(client, dir, strlen(dir)+1); |
| 490 | if (bytes <= 0) { | 406 | if (bytes <= 0) { |
| 491 | afc_unlock(client); | 407 | afc_unlock(client); |
| 492 | return IPHONE_E_NOT_ENOUGH_DATA; | 408 | return AFC_E_NOT_ENOUGH_DATA; |
| 493 | } | 409 | } |
| 494 | // Receive the data | 410 | // Receive the data |
| 495 | bytes = receive_AFC_data(client, &data); | 411 | ret = afc_receive_data(client, &data, &bytes); |
| 496 | if (bytes < 0) { | 412 | if (ret != AFC_E_SUCCESS) { |
| 497 | afc_unlock(client); | 413 | afc_unlock(client); |
| 498 | return IPHONE_E_AFC_ERROR; | 414 | return ret; |
| 499 | } | 415 | } |
| 500 | // Parse the data | 416 | // Parse the data |
| 501 | list_loc = make_strings_list(data, bytes); | 417 | list_loc = make_strings_list(data, bytes); |
| 502 | if (list_loc) | ||
| 503 | ret = IPHONE_E_SUCCESS; | ||
| 504 | if (data) | 418 | if (data) |
| 505 | free(data); | 419 | free(data); |
| 506 | 420 | ||
| @@ -517,29 +431,30 @@ iphone_error_t afc_get_dir_list(afc_client_t client, const char *dir, char ***li | |||
| 517 | * @return A char ** list of parameters as given by AFC or NULL if there was an | 431 | * @return A char ** list of parameters as given by AFC or NULL if there was an |
| 518 | * error. | 432 | * error. |
| 519 | */ | 433 | */ |
| 520 | iphone_error_t afc_get_devinfo(afc_client_t client, char ***infos) | 434 | afc_error_t afc_get_device_info(afc_client_t client, char ***infos) |
| 521 | { | 435 | { |
| 522 | int bytes = 0; | 436 | int bytes = 0; |
| 523 | char *data = NULL, **list = NULL; | 437 | char *data = NULL, **list = NULL; |
| 438 | afc_error_t ret = AFC_E_UNKNOWN_ERROR; | ||
| 524 | 439 | ||
| 525 | if (!client || !infos) | 440 | if (!client || !infos) |
| 526 | return IPHONE_E_INVALID_ARG; | 441 | return AFC_E_INVALID_ARGUMENT; |
| 527 | 442 | ||
| 528 | afc_lock(client); | 443 | afc_lock(client); |
| 529 | 444 | ||
| 530 | // Send the command | 445 | // Send the command |
| 531 | client->afc_packet->operation = AFC_GET_DEVINFO; | 446 | client->afc_packet->operation = AFC_OP_GET_DEVINFO; |
| 532 | client->afc_packet->entire_length = client->afc_packet->this_length = 0; | 447 | client->afc_packet->entire_length = client->afc_packet->this_length = 0; |
| 533 | bytes = dispatch_AFC_packet(client, NULL, 0); | 448 | bytes = afc_dispatch_packet(client, NULL, 0); |
| 534 | if (bytes < 0) { | 449 | if (bytes < 0) { |
| 535 | afc_unlock(client); | 450 | afc_unlock(client); |
| 536 | return IPHONE_E_NOT_ENOUGH_DATA; | 451 | return AFC_E_NOT_ENOUGH_DATA; |
| 537 | } | 452 | } |
| 538 | // Receive the data | 453 | // Receive the data |
| 539 | bytes = receive_AFC_data(client, &data); | 454 | ret = afc_receive_data(client, &data, &bytes); |
| 540 | if (bytes < 0) { | 455 | if (ret != AFC_E_SUCCESS) { |
| 541 | afc_unlock(client); | 456 | afc_unlock(client); |
| 542 | return IPHONE_E_AFC_ERROR; | 457 | return ret; |
| 543 | } | 458 | } |
| 544 | // Parse the data | 459 | // Parse the data |
| 545 | list = make_strings_list(data, bytes); | 460 | list = make_strings_list(data, bytes); |
| @@ -547,66 +462,67 @@ iphone_error_t afc_get_devinfo(afc_client_t client, char ***infos) | |||
| 547 | free(data); | 462 | free(data); |
| 548 | 463 | ||
| 549 | afc_unlock(client); | 464 | afc_unlock(client); |
| 465 | |||
| 550 | *infos = list; | 466 | *infos = list; |
| 551 | return IPHONE_E_SUCCESS; | 467 | |
| 468 | return ret; | ||
| 552 | } | 469 | } |
| 553 | 470 | ||
| 554 | /** Deletes a file. | 471 | /** Deletes a file or directory. |
| 555 | * | 472 | * |
| 556 | * @param client The client to have delete the file. | 473 | * @param client The client to use. |
| 557 | * @param path The file to delete. (must be a fully-qualified path) | 474 | * @param path The path to delete. (must be a fully-qualified path) |
| 558 | * | 475 | * |
| 559 | * @return IPHONE_E_SUCCESS if everythong went well, IPHONE_E_INVALID_ARG | 476 | * @return AFC_E_SUCCESS if everythong went well, AFC_E_INVALID_ARGUMENT |
| 560 | * if arguments are NULL or invalid, IPHONE_E_NOT_ENOUGH_DATA otherwise. | 477 | * if arguments are NULL or invalid, AFC_E_NOT_ENOUGH_DATA otherwise. |
| 561 | */ | 478 | */ |
| 562 | iphone_error_t afc_delete_file(afc_client_t client, const char *path) | 479 | afc_error_t afc_remove_path(afc_client_t client, const char *path) |
| 563 | { | 480 | { |
| 564 | char *response = NULL; | 481 | char *response = NULL; |
| 565 | int bytes; | 482 | int bytes; |
| 483 | afc_error_t ret = AFC_E_UNKNOWN_ERROR; | ||
| 566 | 484 | ||
| 567 | if (!client || !path || !client->afc_packet || client->sfd < 0) | 485 | if (!client || !path || !client->afc_packet || client->sfd < 0) |
| 568 | return IPHONE_E_INVALID_ARG; | 486 | return AFC_E_INVALID_ARGUMENT; |
| 569 | 487 | ||
| 570 | afc_lock(client); | 488 | afc_lock(client); |
| 571 | 489 | ||
| 572 | // Send command | 490 | // Send command |
| 573 | client->afc_packet->this_length = client->afc_packet->entire_length = 0; | 491 | client->afc_packet->this_length = client->afc_packet->entire_length = 0; |
| 574 | client->afc_packet->operation = AFC_DELETE; | 492 | client->afc_packet->operation = AFC_OP_REMOVE_PATH; |
| 575 | bytes = dispatch_AFC_packet(client, path, strlen(path)+1); | 493 | bytes = afc_dispatch_packet(client, path, strlen(path)+1); |
| 576 | if (bytes <= 0) { | 494 | if (bytes <= 0) { |
| 577 | afc_unlock(client); | 495 | afc_unlock(client); |
| 578 | return IPHONE_E_NOT_ENOUGH_DATA; | 496 | return AFC_E_NOT_ENOUGH_DATA; |
| 579 | } | 497 | } |
| 580 | // Receive response | 498 | // Receive response |
| 581 | bytes = receive_AFC_data(client, &response); | 499 | ret = afc_receive_data(client, &response, &bytes); |
| 582 | if (response) | 500 | if (response) |
| 583 | free(response); | 501 | free(response); |
| 584 | 502 | ||
| 585 | afc_unlock(client); | 503 | afc_unlock(client); |
| 586 | 504 | ||
| 587 | if (bytes < 0) { | 505 | return ret; |
| 588 | return IPHONE_E_AFC_ERROR; | ||
| 589 | } | ||
| 590 | return IPHONE_E_SUCCESS; | ||
| 591 | } | 506 | } |
| 592 | 507 | ||
| 593 | /** Renames a file on the phone. | 508 | /** Renames a file or directory on the phone. |
| 594 | * | 509 | * |
| 595 | * @param client The client to have rename the file. | 510 | * @param client The client to have rename. |
| 596 | * @param from The file to rename. (must be a fully-qualified path) | 511 | * @param from The name to rename from. (must be a fully-qualified path) |
| 597 | * @param to The new name of the file. (must also be a fully-qualified path) | 512 | * @param to The new name. (must also be a fully-qualified path) |
| 598 | * | 513 | * |
| 599 | * @return IPHONE_E_SUCCESS if everythong went well, IPHONE_E_INVALID_ARG | 514 | * @return AFC_E_SUCCESS if everythong went well, AFC_E_INVALID_ARGUMENT |
| 600 | * if arguments are NULL or invalid, IPHONE_E_NOT_ENOUGH_DATA otherwise. | 515 | * if arguments are NULL or invalid, AFC_E_NOT_ENOUGH_DATA otherwise. |
| 601 | */ | 516 | */ |
| 602 | iphone_error_t afc_rename_file(afc_client_t client, const char *from, const char *to) | 517 | afc_error_t afc_rename_path(afc_client_t client, const char *from, const char *to) |
| 603 | { | 518 | { |
| 604 | char *response = NULL; | 519 | char *response = NULL; |
| 605 | char *send = (char *) malloc(sizeof(char) * (strlen(from) + strlen(to) + 1 + sizeof(uint32_t))); | 520 | char *send = (char *) malloc(sizeof(char) * (strlen(from) + strlen(to) + 1 + sizeof(uint32_t))); |
| 606 | int bytes = 0; | 521 | int bytes = 0; |
| 522 | afc_error_t ret = AFC_E_UNKNOWN_ERROR; | ||
| 607 | 523 | ||
| 608 | if (!client || !from || !to || !client->afc_packet || client->sfd < 0) | 524 | if (!client || !from || !to || !client->afc_packet || client->sfd < 0) |
| 609 | return IPHONE_E_INVALID_ARG; | 525 | return AFC_E_INVALID_ARGUMENT; |
| 610 | 526 | ||
| 611 | afc_lock(client); | 527 | afc_lock(client); |
| 612 | 528 | ||
| @@ -614,24 +530,21 @@ iphone_error_t afc_rename_file(afc_client_t client, const char *from, const char | |||
| 614 | memcpy(send, from, strlen(from) + 1); | 530 | memcpy(send, from, strlen(from) + 1); |
| 615 | memcpy(send + strlen(from) + 1, to, strlen(to) + 1); | 531 | memcpy(send + strlen(from) + 1, to, strlen(to) + 1); |
| 616 | client->afc_packet->entire_length = client->afc_packet->this_length = 0; | 532 | client->afc_packet->entire_length = client->afc_packet->this_length = 0; |
| 617 | client->afc_packet->operation = AFC_RENAME; | 533 | client->afc_packet->operation = AFC_OP_RENAME_PATH; |
| 618 | bytes = dispatch_AFC_packet(client, send, strlen(to)+1 + strlen(from)+1); | 534 | bytes = afc_dispatch_packet(client, send, strlen(to)+1 + strlen(from)+1); |
| 619 | free(send); | 535 | free(send); |
| 620 | if (bytes <= 0) { | 536 | if (bytes <= 0) { |
| 621 | afc_unlock(client); | 537 | afc_unlock(client); |
| 622 | return IPHONE_E_NOT_ENOUGH_DATA; | 538 | return AFC_E_NOT_ENOUGH_DATA; |
| 623 | } | 539 | } |
| 624 | // Receive response | 540 | // Receive response |
| 625 | bytes = receive_AFC_data(client, &response); | 541 | ret = afc_receive_data(client, &response, &bytes); |
| 626 | if (response) | 542 | if (response) |
| 627 | free(response); | 543 | free(response); |
| 628 | 544 | ||
| 629 | afc_unlock(client); | 545 | afc_unlock(client); |
| 630 | 546 | ||
| 631 | if (bytes < 0) { | 547 | return ret; |
| 632 | return IPHONE_E_AFC_ERROR; | ||
| 633 | } | ||
| 634 | return IPHONE_E_SUCCESS; | ||
| 635 | } | 548 | } |
| 636 | 549 | ||
| 637 | /** Creates a directory on the phone. | 550 | /** Creates a directory on the phone. |
| @@ -640,38 +553,36 @@ iphone_error_t afc_rename_file(afc_client_t client, const char *from, const char | |||
| 640 | * @param dir The directory's path. (must be a fully-qualified path, I assume | 553 | * @param dir The directory's path. (must be a fully-qualified path, I assume |
| 641 | * all other mkdir restrictions apply as well) | 554 | * all other mkdir restrictions apply as well) |
| 642 | * | 555 | * |
| 643 | * @return IPHONE_E_SUCCESS if everythong went well, IPHONE_E_INVALID_ARG | 556 | * @return AFC_E_SUCCESS if everythong went well, AFC_E_INVALID_ARGUMENT |
| 644 | * if arguments are NULL or invalid, IPHONE_E_NOT_ENOUGH_DATA otherwise. | 557 | * if arguments are NULL or invalid, AFC_E_NOT_ENOUGH_DATA otherwise. |
| 645 | */ | 558 | */ |
| 646 | iphone_error_t afc_mkdir(afc_client_t client, const char *dir) | 559 | afc_error_t afc_make_directory(afc_client_t client, const char *dir) |
| 647 | { | 560 | { |
| 648 | int bytes = 0; | 561 | int bytes = 0; |
| 649 | char *response = NULL; | 562 | char *response = NULL; |
| 563 | afc_error_t ret = AFC_E_UNKNOWN_ERROR; | ||
| 650 | 564 | ||
| 651 | if (!client) | 565 | if (!client) |
| 652 | return IPHONE_E_INVALID_ARG; | 566 | return AFC_E_INVALID_ARGUMENT; |
| 653 | 567 | ||
| 654 | afc_lock(client); | 568 | afc_lock(client); |
| 655 | 569 | ||
| 656 | // Send command | 570 | // Send command |
| 657 | client->afc_packet->operation = AFC_MAKE_DIR; | 571 | client->afc_packet->operation = AFC_OP_MAKE_DIR; |
| 658 | client->afc_packet->this_length = client->afc_packet->entire_length = 0; | 572 | client->afc_packet->this_length = client->afc_packet->entire_length = 0; |
| 659 | bytes = dispatch_AFC_packet(client, dir, strlen(dir)+1); | 573 | bytes = afc_dispatch_packet(client, dir, strlen(dir)+1); |
| 660 | if (bytes <= 0) { | 574 | if (bytes <= 0) { |
| 661 | afc_unlock(client); | 575 | afc_unlock(client); |
| 662 | return IPHONE_E_NOT_ENOUGH_DATA; | 576 | return AFC_E_NOT_ENOUGH_DATA; |
| 663 | } | 577 | } |
| 664 | // Receive response | 578 | // Receive response |
| 665 | bytes = receive_AFC_data(client, &response); | 579 | ret = afc_receive_data(client, &response, &bytes); |
| 666 | if (response) | 580 | if (response) |
| 667 | free(response); | 581 | free(response); |
| 668 | 582 | ||
| 669 | afc_unlock(client); | 583 | afc_unlock(client); |
| 670 | 584 | ||
| 671 | if (bytes < 0) { | 585 | return ret; |
| 672 | return IPHONE_E_AFC_ERROR; | ||
| 673 | } | ||
| 674 | return IPHONE_E_SUCCESS; | ||
| 675 | } | 586 | } |
| 676 | 587 | ||
| 677 | /** Gets information about a specific file. | 588 | /** Gets information about a specific file. |
| @@ -682,38 +593,35 @@ iphone_error_t afc_mkdir(afc_client_t client, const char *dir) | |||
| 682 | * list of strings with the file information. | 593 | * list of strings with the file information. |
| 683 | * Set to NULL before calling this function. | 594 | * Set to NULL before calling this function. |
| 684 | * | 595 | * |
| 685 | * @return IPHONE_E_SUCCESS on success or an IPHONE_E_* error value | 596 | * @return AFC_E_SUCCESS on success or an AFC_E_* error value |
| 686 | * when something went wrong. | 597 | * when something went wrong. |
| 687 | */ | 598 | */ |
| 688 | iphone_error_t afc_get_file_info(afc_client_t client, const char *path, char ***infolist) | 599 | afc_error_t afc_get_file_info(afc_client_t client, const char *path, char ***infolist) |
| 689 | { | 600 | { |
| 690 | char *received = NULL; | 601 | char *received = NULL; |
| 691 | int length; | 602 | int bytes; |
| 603 | afc_error_t ret = AFC_E_UNKNOWN_ERROR; | ||
| 692 | 604 | ||
| 693 | if (!client || !path || !infolist) { | 605 | if (!client || !path || !infolist) |
| 694 | return IPHONE_E_INVALID_ARG; | 606 | return AFC_E_INVALID_ARGUMENT; |
| 695 | } | ||
| 696 | 607 | ||
| 697 | afc_lock(client); | 608 | afc_lock(client); |
| 698 | 609 | ||
| 699 | // Send command | 610 | // Send command |
| 700 | client->afc_packet->operation = AFC_GET_INFO; | 611 | client->afc_packet->operation = AFC_OP_GET_FILE_INFO; |
| 701 | client->afc_packet->entire_length = client->afc_packet->this_length = 0; | 612 | client->afc_packet->entire_length = client->afc_packet->this_length = 0; |
| 702 | dispatch_AFC_packet(client, path, strlen(path)+1); | 613 | afc_dispatch_packet(client, path, strlen(path)+1); |
| 703 | 614 | ||
| 704 | // Receive data | 615 | // Receive data |
| 705 | length = receive_AFC_data(client, &received); | 616 | ret = afc_receive_data(client, &received, &bytes); |
| 706 | if (received) { | 617 | if (received) { |
| 707 | *infolist = make_strings_list(received, length); | 618 | *infolist = make_strings_list(received, bytes); |
| 708 | free(received); | 619 | free(received); |
| 709 | } else { | ||
| 710 | afc_unlock(client); | ||
| 711 | return IPHONE_E_AFC_ERROR; | ||
| 712 | } | 620 | } |
| 713 | 621 | ||
| 714 | afc_unlock(client); | 622 | afc_unlock(client); |
| 715 | 623 | ||
| 716 | return IPHONE_E_SUCCESS; | 624 | return ret; |
| 717 | } | 625 | } |
| 718 | 626 | ||
| 719 | /** Opens a file on the phone. | 627 | /** Opens a file on the phone. |
| @@ -726,21 +634,22 @@ iphone_error_t afc_get_file_info(afc_client_t client, const char *path, char *** | |||
| 726 | * destroying anything previously there. | 634 | * destroying anything previously there. |
| 727 | * @param handle Pointer to a uint64_t that will hold the handle of the file | 635 | * @param handle Pointer to a uint64_t that will hold the handle of the file |
| 728 | * | 636 | * |
| 729 | * @return IPHONE_E_SUCCESS on success or an IPHONE_E_* error on failure. | 637 | * @return AFC_E_SUCCESS on success or an AFC_E_* error on failure. |
| 730 | */ | 638 | */ |
| 731 | iphone_error_t | 639 | iphone_error_t |
| 732 | afc_open_file(afc_client_t client, const char *filename, | 640 | afc_file_open(afc_client_t client, const char *filename, |
| 733 | afc_file_mode_t file_mode, uint64_t *handle) | 641 | afc_file_mode_t file_mode, uint64_t *handle) |
| 734 | { | 642 | { |
| 735 | uint32_t ag = 0; | 643 | uint32_t ag = 0; |
| 736 | int bytes = 0, length = 0; | 644 | int bytes = 0; |
| 737 | char *data = (char *) malloc(sizeof(char) * (8 + strlen(filename) + 1)); | 645 | char *data = (char *) malloc(sizeof(char) * (8 + strlen(filename) + 1)); |
| 646 | afc_error_t ret = AFC_E_UNKNOWN_ERROR; | ||
| 738 | 647 | ||
| 739 | // set handle to 0 so in case an error occurs, the handle is invalid | 648 | // set handle to 0 so in case an error occurs, the handle is invalid |
| 740 | *handle = 0; | 649 | *handle = 0; |
| 741 | 650 | ||
| 742 | if (!client || client->sfd < 0|| !client->afc_packet) | 651 | if (!client || client->sfd < 0|| !client->afc_packet) |
| 743 | return IPHONE_E_INVALID_ARG; | 652 | return AFC_E_INVALID_ARGUMENT; |
| 744 | 653 | ||
| 745 | afc_lock(client); | 654 | afc_lock(client); |
| 746 | 655 | ||
| @@ -749,34 +658,32 @@ afc_open_file(afc_client_t client, const char *filename, | |||
| 749 | memcpy(data + 4, &ag, 4); | 658 | memcpy(data + 4, &ag, 4); |
| 750 | memcpy(data + 8, filename, strlen(filename)); | 659 | memcpy(data + 8, filename, strlen(filename)); |
| 751 | data[8 + strlen(filename)] = '\0'; | 660 | data[8 + strlen(filename)] = '\0'; |
| 752 | client->afc_packet->operation = AFC_FILE_OPEN; | 661 | client->afc_packet->operation = AFC_OP_FILE_OPEN; |
| 753 | client->afc_packet->entire_length = client->afc_packet->this_length = 0; | 662 | client->afc_packet->entire_length = client->afc_packet->this_length = 0; |
| 754 | bytes = dispatch_AFC_packet(client, data, 8 + strlen(filename) + 1); | 663 | bytes = afc_dispatch_packet(client, data, 8 + strlen(filename) + 1); |
| 755 | free(data); | 664 | free(data); |
| 756 | 665 | ||
| 757 | if (bytes <= 0) { | 666 | if (bytes <= 0) { |
| 758 | log_debug_msg("afc_open_file: Didn't receive a response to the command\n"); | 667 | log_debug_msg("%s: Didn't receive a response to the command\n", __func__); |
| 759 | afc_unlock(client); | 668 | afc_unlock(client); |
| 760 | return IPHONE_E_NOT_ENOUGH_DATA; | 669 | return AFC_E_NOT_ENOUGH_DATA; |
| 761 | } | 670 | } |
| 762 | // Receive the data | 671 | // Receive the data |
| 763 | length = receive_AFC_data(client, &data); | 672 | ret = afc_receive_data(client, &data, &bytes); |
| 764 | if (length > 0 && data) { | 673 | if ((ret == AFC_E_SUCCESS) && (bytes > 0) && data) { |
| 765 | afc_unlock(client); | 674 | afc_unlock(client); |
| 766 | 675 | ||
| 767 | // Get the file handle | 676 | // Get the file handle |
| 768 | memcpy(handle, data, sizeof(uint64_t)); | 677 | memcpy(handle, data, sizeof(uint64_t)); |
| 769 | free(data); | 678 | free(data); |
| 770 | return IPHONE_E_SUCCESS; | 679 | return ret; |
| 771 | } else { | ||
| 772 | log_debug_msg("afc_open_file: Didn't get any further data\n"); | ||
| 773 | afc_unlock(client); | ||
| 774 | return IPHONE_E_AFC_ERROR; | ||
| 775 | } | 680 | } |
| 776 | 681 | ||
| 682 | log_debug_msg("%s: Didn't get any further data\n", __func__); | ||
| 683 | |||
| 777 | afc_unlock(client); | 684 | afc_unlock(client); |
| 778 | 685 | ||
| 779 | return IPHONE_E_UNKNOWN_ERROR; | 686 | return ret; |
| 780 | } | 687 | } |
| 781 | 688 | ||
| 782 | /** Attempts to the read the given number of bytes from the given file. | 689 | /** Attempts to the read the given number of bytes from the given file. |
| @@ -789,52 +696,54 @@ afc_open_file(afc_client_t client, const char *filename, | |||
| 789 | * @return The number of bytes read if successful. If there was an error -1. | 696 | * @return The number of bytes read if successful. If there was an error -1. |
| 790 | */ | 697 | */ |
| 791 | iphone_error_t | 698 | iphone_error_t |
| 792 | afc_read_file(afc_client_t client, uint64_t handle, char *data, int length, uint32_t * bytes) | 699 | afc_file_read(afc_client_t client, uint64_t handle, char *data, int length, uint32_t * bytes) |
| 793 | { | 700 | { |
| 794 | char *input = NULL; | 701 | char *input = NULL; |
| 795 | int current_count = 0, bytes_loc = 0; | 702 | int current_count = 0, bytes_loc = 0; |
| 796 | const int MAXIMUM_READ_SIZE = 1 << 16; | 703 | const int MAXIMUM_READ_SIZE = 1 << 16; |
| 704 | afc_error_t ret = AFC_E_SUCCESS; | ||
| 797 | 705 | ||
| 798 | if (!client || !client->afc_packet || client->sfd < 0 || handle == 0) | 706 | if (!client || !client->afc_packet || client->sfd < 0 || handle == 0) |
| 799 | return IPHONE_E_INVALID_ARG; | 707 | return AFC_E_INVALID_ARGUMENT; |
| 800 | log_debug_msg("afc_read_file called for length %i\n", length); | 708 | log_debug_msg("%s: called for length %i\n", __func__, length); |
| 801 | 709 | ||
| 802 | afc_lock(client); | 710 | afc_lock(client); |
| 803 | 711 | ||
| 804 | // Looping here to get around the maximum amount of data that | 712 | // Looping here to get around the maximum amount of data that |
| 805 | // recieve_AFC_data can handle | 713 | // afc_receive_data can handle |
| 806 | while (current_count < length) { | 714 | while (current_count < length) { |
| 807 | log_debug_msg("afc_read_file: current count is %i but length is %i\n", current_count, length); | 715 | log_debug_msg("%s: current count is %i but length is %i\n", __func__, current_count, length); |
| 808 | 716 | ||
| 809 | // Send the read command | 717 | // Send the read command |
| 810 | AFCFilePacket *packet = (AFCFilePacket *) malloc(sizeof(AFCFilePacket)); | 718 | AFCFilePacket *packet = (AFCFilePacket *) malloc(sizeof(AFCFilePacket)); |
| 811 | packet->filehandle = handle; | 719 | packet->filehandle = handle; |
| 812 | packet->size = ((length - current_count) < MAXIMUM_READ_SIZE) ? (length - current_count) : MAXIMUM_READ_SIZE; | 720 | packet->size = ((length - current_count) < MAXIMUM_READ_SIZE) ? (length - current_count) : MAXIMUM_READ_SIZE; |
| 813 | client->afc_packet->operation = AFC_READ; | 721 | client->afc_packet->operation = AFC_OP_READ; |
| 814 | client->afc_packet->entire_length = client->afc_packet->this_length = 0; | 722 | client->afc_packet->entire_length = client->afc_packet->this_length = 0; |
| 815 | bytes_loc = dispatch_AFC_packet(client, (char *) packet, sizeof(AFCFilePacket)); | 723 | bytes_loc = afc_dispatch_packet(client, (char *) packet, sizeof(AFCFilePacket)); |
| 816 | free(packet); | 724 | free(packet); |
| 817 | 725 | ||
| 818 | if (bytes_loc <= 0) { | 726 | if (bytes_loc <= 0) { |
| 819 | afc_unlock(client); | 727 | afc_unlock(client); |
| 820 | return IPHONE_E_NOT_ENOUGH_DATA; | 728 | return AFC_E_NOT_ENOUGH_DATA; |
| 821 | } | 729 | } |
| 822 | // Receive the data | 730 | // Receive the data |
| 823 | bytes_loc = receive_AFC_data(client, &input); | 731 | ret = afc_receive_data(client, &input, &bytes_loc); |
| 824 | log_debug_msg("afc_read_file: bytes returned: %i\n", bytes_loc); | 732 | log_debug_msg("%s: afc_receive_data returned error: %d\n", __func__, ret); |
| 825 | if (bytes_loc < 0) { | 733 | log_debug_msg("%s: bytes returned: %i\n", __func__, bytes_loc); |
| 734 | if (ret != AFC_E_SUCCESS) { | ||
| 826 | afc_unlock(client); | 735 | afc_unlock(client); |
| 827 | return IPHONE_E_AFC_ERROR; | 736 | return ret; |
| 828 | } else if (bytes_loc == 0) { | 737 | } else if (bytes_loc == 0) { |
| 829 | if (input) | 738 | if (input) |
| 830 | free(input); | 739 | free(input); |
| 831 | afc_unlock(client); | 740 | afc_unlock(client); |
| 832 | *bytes = current_count; | 741 | *bytes = current_count; |
| 833 | return IPHONE_E_SUCCESS; // FIXME check that's actually a | 742 | /* FIXME: check that's actually a success */ |
| 834 | // success | 743 | return ret; |
| 835 | } else { | 744 | } else { |
| 836 | if (input) { | 745 | if (input) { |
| 837 | log_debug_msg("afc_read_file: %d\n", bytes_loc); | 746 | log_debug_msg("%s: %d\n", __func__, bytes_loc); |
| 838 | memcpy(data + current_count, input, (bytes_loc > length) ? length : bytes_loc); | 747 | memcpy(data + current_count, input, (bytes_loc > length) ? length : bytes_loc); |
| 839 | free(input); | 748 | free(input); |
| 840 | input = NULL; | 749 | input = NULL; |
| @@ -842,11 +751,11 @@ afc_read_file(afc_client_t client, uint64_t handle, char *data, int length, uint | |||
| 842 | } | 751 | } |
| 843 | } | 752 | } |
| 844 | } | 753 | } |
| 845 | log_debug_msg("afc_read_file: returning current_count as %i\n", current_count); | 754 | log_debug_msg("%s: returning current_count as %i\n", __func__, current_count); |
| 846 | 755 | ||
| 847 | afc_unlock(client); | 756 | afc_unlock(client); |
| 848 | *bytes = current_count; | 757 | *bytes = current_count; |
| 849 | return IPHONE_E_SUCCESS; | 758 | return ret; |
| 850 | } | 759 | } |
| 851 | 760 | ||
| 852 | /** Writes a given number of bytes to a file. | 761 | /** Writes a given number of bytes to a file. |
| @@ -860,7 +769,7 @@ afc_read_file(afc_client_t client, uint64_t handle, char *data, int length, uint | |||
| 860 | * none were written... | 769 | * none were written... |
| 861 | */ | 770 | */ |
| 862 | iphone_error_t | 771 | iphone_error_t |
| 863 | afc_write_file(afc_client_t client, uint64_t handle, | 772 | afc_file_write(afc_client_t client, uint64_t handle, |
| 864 | const char *data, int length, uint32_t * bytes) | 773 | const char *data, int length, uint32_t * bytes) |
| 865 | { | 774 | { |
| 866 | char *acknowledgement = NULL; | 775 | char *acknowledgement = NULL; |
| @@ -869,36 +778,37 @@ afc_write_file(afc_client_t client, uint64_t handle, | |||
| 869 | uint32_t segments = (length / MAXIMUM_WRITE_SIZE); | 778 | uint32_t segments = (length / MAXIMUM_WRITE_SIZE); |
| 870 | int bytes_loc = 0; | 779 | int bytes_loc = 0; |
| 871 | char *out_buffer = NULL; | 780 | char *out_buffer = NULL; |
| 781 | afc_error_t ret = AFC_E_SUCCESS; | ||
| 872 | 782 | ||
| 873 | if (!client || !client->afc_packet || client->sfd < 0 || !bytes || (handle == 0)) | 783 | if (!client || !client->afc_packet || client->sfd < 0 || !bytes || (handle == 0)) |
| 874 | return IPHONE_E_INVALID_ARG; | 784 | return AFC_E_INVALID_ARGUMENT; |
| 875 | 785 | ||
| 876 | afc_lock(client); | 786 | afc_lock(client); |
| 877 | 787 | ||
| 878 | log_debug_msg("afc_write_file: Write length: %i\n", length); | 788 | log_debug_msg("%s: Write length: %i\n", __func__, length); |
| 879 | 789 | ||
| 880 | // Divide the file into segments. | 790 | // Divide the file into segments. |
| 881 | for (i = 0; i < segments; i++) { | 791 | for (i = 0; i < segments; i++) { |
| 882 | // Send the segment | 792 | // Send the segment |
| 883 | client->afc_packet->this_length = sizeof(AFCPacket) + 8; | 793 | client->afc_packet->this_length = sizeof(AFCPacket) + 8; |
| 884 | client->afc_packet->entire_length = client->afc_packet->this_length + MAXIMUM_WRITE_SIZE; | 794 | client->afc_packet->entire_length = client->afc_packet->this_length + MAXIMUM_WRITE_SIZE; |
| 885 | client->afc_packet->operation = AFC_WRITE; | 795 | client->afc_packet->operation = AFC_OP_WRITE; |
| 886 | out_buffer = (char *) malloc(sizeof(char) * client->afc_packet->entire_length - sizeof(AFCPacket)); | 796 | out_buffer = (char *) malloc(sizeof(char) * client->afc_packet->entire_length - sizeof(AFCPacket)); |
| 887 | memcpy(out_buffer, (char *)&handle, sizeof(uint64_t)); | 797 | memcpy(out_buffer, (char *)&handle, sizeof(uint64_t)); |
| 888 | memcpy(out_buffer + 8, data + current_count, MAXIMUM_WRITE_SIZE); | 798 | memcpy(out_buffer + 8, data + current_count, MAXIMUM_WRITE_SIZE); |
| 889 | bytes_loc = dispatch_AFC_packet(client, out_buffer, MAXIMUM_WRITE_SIZE + 8); | 799 | bytes_loc = afc_dispatch_packet(client, out_buffer, MAXIMUM_WRITE_SIZE + 8); |
| 890 | if (bytes_loc < 0) { | 800 | if (bytes_loc < 0) { |
| 891 | afc_unlock(client); | 801 | afc_unlock(client); |
| 892 | return IPHONE_E_NOT_ENOUGH_DATA; | 802 | return AFC_E_NOT_ENOUGH_DATA; |
| 893 | } | 803 | } |
| 894 | free(out_buffer); | 804 | free(out_buffer); |
| 895 | out_buffer = NULL; | 805 | out_buffer = NULL; |
| 896 | 806 | ||
| 897 | current_count += bytes_loc; | 807 | current_count += bytes_loc; |
| 898 | bytes_loc = receive_AFC_data(client, &acknowledgement); | 808 | ret = afc_receive_data(client, &acknowledgement, &bytes_loc); |
| 899 | if (bytes_loc < 0) { | 809 | if (ret != AFC_E_SUCCESS) { |
| 900 | afc_unlock(client); | 810 | afc_unlock(client); |
| 901 | return IPHONE_E_AFC_ERROR; | 811 | return ret; |
| 902 | } else { | 812 | } else { |
| 903 | free(acknowledgement); | 813 | free(acknowledgement); |
| 904 | } | 814 | } |
| @@ -911,16 +821,16 @@ afc_write_file(afc_client_t client, uint64_t handle, | |||
| 911 | if (current_count == (uint32_t)length) { | 821 | if (current_count == (uint32_t)length) { |
| 912 | afc_unlock(client); | 822 | afc_unlock(client); |
| 913 | *bytes = current_count; | 823 | *bytes = current_count; |
| 914 | return IPHONE_E_SUCCESS; | 824 | return ret; |
| 915 | } | 825 | } |
| 916 | 826 | ||
| 917 | client->afc_packet->this_length = sizeof(AFCPacket) + 8; | 827 | client->afc_packet->this_length = sizeof(AFCPacket) + 8; |
| 918 | client->afc_packet->entire_length = client->afc_packet->this_length + (length - current_count); | 828 | client->afc_packet->entire_length = client->afc_packet->this_length + (length - current_count); |
| 919 | client->afc_packet->operation = AFC_WRITE; | 829 | client->afc_packet->operation = AFC_OP_WRITE; |
| 920 | out_buffer = (char *) malloc(sizeof(char) * client->afc_packet->entire_length - sizeof(AFCPacket)); | 830 | out_buffer = (char *) malloc(sizeof(char) * client->afc_packet->entire_length - sizeof(AFCPacket)); |
| 921 | memcpy(out_buffer, (char *) &handle, sizeof(uint64_t)); | 831 | memcpy(out_buffer, (char *) &handle, sizeof(uint64_t)); |
| 922 | memcpy(out_buffer + 8, data + current_count, (length - current_count)); | 832 | memcpy(out_buffer + 8, data + current_count, (length - current_count)); |
| 923 | bytes_loc = dispatch_AFC_packet(client, out_buffer, (length - current_count) + 8); | 833 | bytes_loc = afc_dispatch_packet(client, out_buffer, (length - current_count) + 8); |
| 924 | free(out_buffer); | 834 | free(out_buffer); |
| 925 | out_buffer = NULL; | 835 | out_buffer = NULL; |
| 926 | 836 | ||
| @@ -929,19 +839,19 @@ afc_write_file(afc_client_t client, uint64_t handle, | |||
| 929 | if (bytes_loc <= 0) { | 839 | if (bytes_loc <= 0) { |
| 930 | afc_unlock(client); | 840 | afc_unlock(client); |
| 931 | *bytes = current_count; | 841 | *bytes = current_count; |
| 932 | return IPHONE_E_SUCCESS; | 842 | return AFC_E_SUCCESS; |
| 933 | } | 843 | } |
| 934 | 844 | ||
| 935 | zero = bytes_loc; | 845 | zero = bytes_loc; |
| 936 | bytes_loc = receive_AFC_data(client, &acknowledgement); | 846 | ret = afc_receive_data(client, &acknowledgement, &bytes_loc); |
| 937 | afc_unlock(client); | 847 | afc_unlock(client); |
| 938 | if (bytes_loc < 0) { | 848 | if (ret != AFC_E_SUCCESS) { |
| 939 | log_debug_msg("afc_write_file: uh oh?\n"); | 849 | log_debug_msg("%s: uh oh?\n", __func__); |
| 940 | } else { | 850 | } else { |
| 941 | free(acknowledgement); | 851 | free(acknowledgement); |
| 942 | } | 852 | } |
| 943 | *bytes = current_count; | 853 | *bytes = current_count; |
| 944 | return IPHONE_E_SUCCESS; | 854 | return ret; |
| 945 | } | 855 | } |
| 946 | 856 | ||
| 947 | /** Closes a file on the phone. | 857 | /** Closes a file on the phone. |
| @@ -949,95 +859,91 @@ afc_write_file(afc_client_t client, uint64_t handle, | |||
| 949 | * @param client The client to close the file with. | 859 | * @param client The client to close the file with. |
| 950 | * @param handle File handle of a previously opened file. | 860 | * @param handle File handle of a previously opened file. |
| 951 | */ | 861 | */ |
| 952 | iphone_error_t afc_close_file(afc_client_t client, uint64_t handle) | 862 | afc_error_t afc_file_close(afc_client_t client, uint64_t handle) |
| 953 | { | 863 | { |
| 954 | if (!client || (handle == 0)) | ||
| 955 | return IPHONE_E_INVALID_ARG; | ||
| 956 | char *buffer = malloc(sizeof(char) * 8); | 864 | char *buffer = malloc(sizeof(char) * 8); |
| 957 | int bytes = 0; | 865 | int bytes = 0; |
| 866 | afc_error_t ret = AFC_E_UNKNOWN_ERROR; | ||
| 867 | |||
| 868 | if (!client || (handle == 0)) | ||
| 869 | return AFC_E_INVALID_ARGUMENT; | ||
| 958 | 870 | ||
| 959 | afc_lock(client); | 871 | afc_lock(client); |
| 960 | 872 | ||
| 961 | log_debug_msg("afc_close_file: File handle %i\n", handle); | 873 | log_debug_msg("%s: File handle %i\n", __func__, handle); |
| 962 | 874 | ||
| 963 | // Send command | 875 | // Send command |
| 964 | memcpy(buffer, &handle, sizeof(uint64_t)); | 876 | memcpy(buffer, &handle, sizeof(uint64_t)); |
| 965 | client->afc_packet->operation = AFC_FILE_CLOSE; | 877 | client->afc_packet->operation = AFC_OP_FILE_CLOSE; |
| 966 | client->afc_packet->entire_length = client->afc_packet->this_length = 0; | 878 | client->afc_packet->entire_length = client->afc_packet->this_length = 0; |
| 967 | bytes = dispatch_AFC_packet(client, buffer, 8); | 879 | bytes = afc_dispatch_packet(client, buffer, 8); |
| 968 | free(buffer); | 880 | free(buffer); |
| 969 | buffer = NULL; | 881 | buffer = NULL; |
| 970 | 882 | ||
| 971 | // FIXME: Is this necesary? | ||
| 972 | // client->afc_packet->entire_length = client->afc_packet->this_length | ||
| 973 | // = 0; | ||
| 974 | |||
| 975 | if (bytes <= 0) { | 883 | if (bytes <= 0) { |
| 976 | afc_unlock(client); | 884 | afc_unlock(client); |
| 977 | return IPHONE_E_UNKNOWN_ERROR; | 885 | return AFC_E_UNKNOWN_ERROR; |
| 978 | } | 886 | } |
| 887 | |||
| 979 | // Receive the response | 888 | // Receive the response |
| 980 | bytes = receive_AFC_data(client, &buffer); | 889 | ret = afc_receive_data(client, &buffer, &bytes); |
| 981 | if (buffer) | 890 | if (buffer) |
| 982 | free(buffer); | 891 | free(buffer); |
| 892 | |||
| 983 | afc_unlock(client); | 893 | afc_unlock(client); |
| 984 | return IPHONE_E_SUCCESS; | 894 | |
| 895 | return ret; | ||
| 985 | } | 896 | } |
| 986 | 897 | ||
| 987 | /** Locks or unlocks a file on the phone. | 898 | /** Locks or unlocks a file on the phone. |
| 988 | * | 899 | * |
| 989 | * makes use of flock, see | 900 | * makes use of flock on the device, see |
| 990 | * http://developer.apple.com/documentation/Darwin/Reference/ManPages/man2/flock.2.html | 901 | * http://developer.apple.com/documentation/Darwin/Reference/ManPages/man2/flock.2.html |
| 991 | * | 902 | * |
| 992 | * operation (same as in sys/file.h on linux): | 903 | * @param client The client to lock the file with. |
| 993 | * | ||
| 994 | * LOCK_SH 1 // shared lock | ||
| 995 | * LOCK_EX 2 // exclusive lock | ||
| 996 | * LOCK_NB 4 // don't block when locking | ||
| 997 | * LOCK_UN 8 // unlock | ||
| 998 | * | ||
| 999 | * @param client The client to close the file with. | ||
| 1000 | * @param handle File handle of a previously opened file. | 904 | * @param handle File handle of a previously opened file. |
| 1001 | * @operation the lock or unlock operation to perform. | 905 | * @param operation the lock or unlock operation to perform, this is one of |
| 906 | * AFC_LOCK_SH (shared lock), AFC_LOCK_EX (exclusive lock), | ||
| 907 | * or AFC_LOCK_UN (unlock). | ||
| 1002 | */ | 908 | */ |
| 1003 | iphone_error_t afc_lock_file(afc_client_t client, uint64_t handle, int operation) | 909 | afc_error_t afc_file_lock(afc_client_t client, uint64_t handle, afc_lock_op_t operation) |
| 1004 | { | 910 | { |
| 1005 | if (!client || (handle == 0)) | ||
| 1006 | return IPHONE_E_INVALID_ARG; | ||
| 1007 | char *buffer = malloc(16); | 911 | char *buffer = malloc(16); |
| 1008 | int bytes = 0; | 912 | int bytes = 0; |
| 1009 | uint64_t op = operation; | 913 | uint64_t op = operation; |
| 914 | afc_error_t ret = AFC_E_UNKNOWN_ERROR; | ||
| 915 | |||
| 916 | if (!client || (handle == 0)) | ||
| 917 | return AFC_E_INVALID_ARGUMENT; | ||
| 1010 | 918 | ||
| 1011 | afc_lock(client); | 919 | afc_lock(client); |
| 1012 | 920 | ||
| 1013 | log_debug_msg("afc_lock_file: File handle %i\n", handle); | 921 | log_debug_msg("%s: file handle %i\n", __func__, handle); |
| 1014 | 922 | ||
| 1015 | // Send command | 923 | // Send command |
| 1016 | memcpy(buffer, &handle, sizeof(uint64_t)); | 924 | memcpy(buffer, &handle, sizeof(uint64_t)); |
| 1017 | memcpy(buffer + 8, &op, 8); | 925 | memcpy(buffer + 8, &op, 8); |
| 1018 | 926 | ||
| 1019 | client->afc_packet->operation = AFC_FILE_LOCK; | 927 | client->afc_packet->operation = AFC_OP_FILE_LOCK; |
| 1020 | client->afc_packet->entire_length = client->afc_packet->this_length = 0; | 928 | client->afc_packet->entire_length = client->afc_packet->this_length = 0; |
| 1021 | bytes = dispatch_AFC_packet(client, buffer, 16); | 929 | bytes = afc_dispatch_packet(client, buffer, 16); |
| 1022 | free(buffer); | 930 | free(buffer); |
| 1023 | buffer = NULL; | 931 | buffer = NULL; |
| 1024 | 932 | ||
| 1025 | if (bytes <= 0) { | 933 | if (bytes <= 0) { |
| 1026 | afc_unlock(client); | 934 | afc_unlock(client); |
| 1027 | log_debug_msg("fuck\n"); | 935 | log_debug_msg("%s: could not send lock command\n", __func__); |
| 1028 | return IPHONE_E_UNKNOWN_ERROR; | 936 | return AFC_E_UNKNOWN_ERROR; |
| 1029 | } | 937 | } |
| 1030 | // Receive the response | 938 | // Receive the response |
| 1031 | bytes = receive_AFC_data(client, &buffer); | 939 | ret = afc_receive_data(client, &buffer, &bytes); |
| 1032 | if (buffer) { | 940 | if (buffer) { |
| 1033 | log_debug_buffer(buffer, bytes); | 941 | log_debug_buffer(buffer, bytes); |
| 1034 | free(buffer); | 942 | free(buffer); |
| 1035 | } | 943 | } |
| 1036 | afc_unlock(client); | 944 | afc_unlock(client); |
| 1037 | if (bytes < 0) { | 945 | |
| 1038 | return IPHONE_E_AFC_ERROR; | 946 | return ret; |
| 1039 | } | ||
| 1040 | return IPHONE_E_SUCCESS; | ||
| 1041 | } | 947 | } |
| 1042 | 948 | ||
| 1043 | /** Seeks to a given position of a pre-opened file on the phone. | 949 | /** Seeks to a given position of a pre-opened file on the phone. |
| @@ -1047,13 +953,17 @@ iphone_error_t afc_lock_file(afc_client_t client, uint64_t handle, int operation | |||
| 1047 | * @param offset Seek offset. | 953 | * @param offset Seek offset. |
| 1048 | * @param whence Seeking direction, one of SEEK_SET, SEEK_CUR, or SEEK_END. | 954 | * @param whence Seeking direction, one of SEEK_SET, SEEK_CUR, or SEEK_END. |
| 1049 | * | 955 | * |
| 1050 | * @return IPHONE_E_SUCCESS on success, IPHONE_E_NOT_ENOUGH_DATA on failure. | 956 | * @return AFC_E_SUCCESS on success, AFC_E_NOT_ENOUGH_DATA on failure. |
| 1051 | */ | 957 | */ |
| 1052 | iphone_error_t afc_seek_file(afc_client_t client, uint64_t handle, int64_t offset, int whence) | 958 | afc_error_t afc_file_seek(afc_client_t client, uint64_t handle, int64_t offset, int whence) |
| 1053 | { | 959 | { |
| 1054 | char *buffer = (char *) malloc(sizeof(char) * 24); | 960 | char *buffer = (char *) malloc(sizeof(char) * 24); |
| 1055 | uint32_t zero = 0; | 961 | uint32_t zero = 0; |
| 1056 | int bytes = 0; | 962 | int bytes = 0; |
| 963 | afc_error_t ret = AFC_E_UNKNOWN_ERROR; | ||
| 964 | |||
| 965 | if (!client || (handle == 0)) | ||
| 966 | return AFC_E_INVALID_ARGUMENT; | ||
| 1057 | 967 | ||
| 1058 | afc_lock(client); | 968 | afc_lock(client); |
| 1059 | 969 | ||
| @@ -1062,27 +972,70 @@ iphone_error_t afc_seek_file(afc_client_t client, uint64_t handle, int64_t offse | |||
| 1062 | memcpy(buffer + 8, &whence, sizeof(int32_t)); // fromwhere | 972 | memcpy(buffer + 8, &whence, sizeof(int32_t)); // fromwhere |
| 1063 | memcpy(buffer + 12, &zero, sizeof(uint32_t)); // pad | 973 | memcpy(buffer + 12, &zero, sizeof(uint32_t)); // pad |
| 1064 | memcpy(buffer + 16, &offset, sizeof(uint64_t)); // offset | 974 | memcpy(buffer + 16, &offset, sizeof(uint64_t)); // offset |
| 1065 | client->afc_packet->operation = AFC_FILE_SEEK; | 975 | client->afc_packet->operation = AFC_OP_FILE_SEEK; |
| 1066 | client->afc_packet->this_length = client->afc_packet->entire_length = 0; | 976 | client->afc_packet->this_length = client->afc_packet->entire_length = 0; |
| 1067 | bytes = dispatch_AFC_packet(client, buffer, 24); | 977 | bytes = afc_dispatch_packet(client, buffer, 24); |
| 1068 | free(buffer); | 978 | free(buffer); |
| 1069 | buffer = NULL; | 979 | buffer = NULL; |
| 1070 | 980 | ||
| 1071 | if (bytes <= 0) { | 981 | if (bytes <= 0) { |
| 1072 | afc_unlock(client); | 982 | afc_unlock(client); |
| 1073 | return IPHONE_E_NOT_ENOUGH_DATA; | 983 | return AFC_E_NOT_ENOUGH_DATA; |
| 1074 | } | 984 | } |
| 1075 | // Receive response | 985 | // Receive response |
| 1076 | bytes = receive_AFC_data(client, &buffer); | 986 | ret = afc_receive_data(client, &buffer, &bytes); |
| 1077 | if (buffer) | 987 | if (buffer) |
| 1078 | free(buffer); | 988 | free(buffer); |
| 1079 | 989 | ||
| 1080 | afc_unlock(client); | 990 | afc_unlock(client); |
| 1081 | 991 | ||
| 1082 | if (bytes < 0) { | 992 | return ret; |
| 1083 | return IPHONE_E_AFC_ERROR; | 993 | } |
| 994 | |||
| 995 | /** Returns current position in a pre-opened file on the phone. | ||
| 996 | * | ||
| 997 | * @param client The client to use. | ||
| 998 | * @param handle File handle of a previously opened file. | ||
| 999 | * @param position Position in bytes of indicator | ||
| 1000 | * | ||
| 1001 | * @return AFC_E_SUCCESS on success, AFC_E_NOT_ENOUGH_DATA on failure. | ||
| 1002 | */ | ||
| 1003 | afc_error_t afc_file_tell(afc_client_t client, uint64_t handle, uint64_t *position) | ||
| 1004 | { | ||
| 1005 | char *buffer = (char *) malloc(sizeof(char) * 8); | ||
| 1006 | int bytes = 0; | ||
| 1007 | afc_error_t ret = AFC_E_UNKNOWN_ERROR; | ||
| 1008 | |||
| 1009 | if (!client || (handle == 0)) | ||
| 1010 | return AFC_E_INVALID_ARGUMENT; | ||
| 1011 | |||
| 1012 | afc_lock(client); | ||
| 1013 | |||
| 1014 | // Send the command | ||
| 1015 | memcpy(buffer, &handle, sizeof(uint64_t)); // handle | ||
| 1016 | client->afc_packet->operation = AFC_OP_FILE_TELL; | ||
| 1017 | client->afc_packet->this_length = client->afc_packet->entire_length = 0; | ||
| 1018 | bytes = afc_dispatch_packet(client, buffer, 8); | ||
| 1019 | free(buffer); | ||
| 1020 | buffer = NULL; | ||
| 1021 | |||
| 1022 | if (bytes <= 0) { | ||
| 1023 | afc_unlock(client); | ||
| 1024 | return AFC_E_NOT_ENOUGH_DATA; | ||
| 1084 | } | 1025 | } |
| 1085 | return IPHONE_E_SUCCESS; | 1026 | |
| 1027 | // Receive the data | ||
| 1028 | ret = afc_receive_data(client, &buffer, &bytes); | ||
| 1029 | if (bytes > 0 && buffer) { | ||
| 1030 | /* Get the position */ | ||
| 1031 | memcpy(position, buffer, sizeof(uint64_t)); | ||
| 1032 | } | ||
| 1033 | if (buffer) | ||
| 1034 | free(buffer); | ||
| 1035 | |||
| 1036 | afc_unlock(client); | ||
| 1037 | |||
| 1038 | return ret; | ||
| 1086 | } | 1039 | } |
| 1087 | 1040 | ||
| 1088 | /** Sets the size of a file on the phone. | 1041 | /** Sets the size of a file on the phone. |
| @@ -1096,37 +1049,38 @@ iphone_error_t afc_seek_file(afc_client_t client, uint64_t handle, int64_t offse | |||
| 1096 | * @note This function is more akin to ftruncate than truncate, and truncate | 1049 | * @note This function is more akin to ftruncate than truncate, and truncate |
| 1097 | * calls would have to open the file before calling this, sadly. | 1050 | * calls would have to open the file before calling this, sadly. |
| 1098 | */ | 1051 | */ |
| 1099 | iphone_error_t afc_truncate_file(afc_client_t client, uint64_t handle, uint64_t newsize) | 1052 | afc_error_t afc_file_truncate(afc_client_t client, uint64_t handle, uint64_t newsize) |
| 1100 | { | 1053 | { |
| 1101 | char *buffer = (char *) malloc(sizeof(char) * 16); | 1054 | char *buffer = (char *) malloc(sizeof(char) * 16); |
| 1102 | int bytes = 0; | 1055 | int bytes = 0; |
| 1056 | afc_error_t ret = AFC_E_UNKNOWN_ERROR; | ||
| 1057 | |||
| 1058 | if (!client || (handle == 0)) | ||
| 1059 | return AFC_E_INVALID_ARGUMENT; | ||
| 1103 | 1060 | ||
| 1104 | afc_lock(client); | 1061 | afc_lock(client); |
| 1105 | 1062 | ||
| 1106 | // Send command | 1063 | // Send command |
| 1107 | memcpy(buffer, &handle, sizeof(uint64_t)); // handle | 1064 | memcpy(buffer, &handle, sizeof(uint64_t)); // handle |
| 1108 | memcpy(buffer + 8, &newsize, sizeof(uint64_t)); // newsize | 1065 | memcpy(buffer + 8, &newsize, sizeof(uint64_t)); // newsize |
| 1109 | client->afc_packet->operation = AFC_FILE_TRUNCATE; | 1066 | client->afc_packet->operation = AFC_OP_FILE_SET_SIZE; |
| 1110 | client->afc_packet->this_length = client->afc_packet->entire_length = 0; | 1067 | client->afc_packet->this_length = client->afc_packet->entire_length = 0; |
| 1111 | bytes = dispatch_AFC_packet(client, buffer, 16); | 1068 | bytes = afc_dispatch_packet(client, buffer, 16); |
| 1112 | free(buffer); | 1069 | free(buffer); |
| 1113 | buffer = NULL; | 1070 | buffer = NULL; |
| 1114 | 1071 | ||
| 1115 | if (bytes <= 0) { | 1072 | if (bytes <= 0) { |
| 1116 | afc_unlock(client); | 1073 | afc_unlock(client); |
| 1117 | return IPHONE_E_NOT_ENOUGH_DATA; | 1074 | return AFC_E_NOT_ENOUGH_DATA; |
| 1118 | } | 1075 | } |
| 1119 | // Receive response | 1076 | // Receive response |
| 1120 | bytes = receive_AFC_data(client, &buffer); | 1077 | ret = afc_receive_data(client, &buffer, &bytes); |
| 1121 | if (buffer) | 1078 | if (buffer) |
| 1122 | free(buffer); | 1079 | free(buffer); |
| 1123 | 1080 | ||
| 1124 | afc_unlock(client); | 1081 | afc_unlock(client); |
| 1125 | 1082 | ||
| 1126 | if (bytes < 0) { | 1083 | return ret; |
| 1127 | return IPHONE_E_AFC_ERROR; | ||
| 1128 | } | ||
| 1129 | return IPHONE_E_SUCCESS; | ||
| 1130 | } | 1084 | } |
| 1131 | 1085 | ||
| 1132 | /** Sets the size of a file on the phone without prior opening it. | 1086 | /** Sets the size of a file on the phone without prior opening it. |
| @@ -1135,18 +1089,19 @@ iphone_error_t afc_truncate_file(afc_client_t client, uint64_t handle, uint64_t | |||
| 1135 | * @param path The path of the file to be truncated. | 1089 | * @param path The path of the file to be truncated. |
| 1136 | * @param newsize The size to set the file to. | 1090 | * @param newsize The size to set the file to. |
| 1137 | * | 1091 | * |
| 1138 | * @return IPHONE_E_SUCCESS if everything went well, IPHONE_E_INVALID_ARG | 1092 | * @return AFC_E_SUCCESS if everything went well, AFC_E_INVALID_ARGUMENT |
| 1139 | * if arguments are NULL or invalid, IPHONE_E_NOT_ENOUGH_DATA otherwise. | 1093 | * if arguments are NULL or invalid, AFC_E_NOT_ENOUGH_DATA otherwise. |
| 1140 | */ | 1094 | */ |
| 1141 | iphone_error_t afc_truncate(afc_client_t client, const char *path, off_t newsize) | 1095 | afc_error_t afc_truncate(afc_client_t client, const char *path, off_t newsize) |
| 1142 | { | 1096 | { |
| 1143 | char *response = NULL; | 1097 | char *response = NULL; |
| 1144 | char *send = (char *) malloc(sizeof(char) * (strlen(path) + 1 + 8)); | 1098 | char *send = (char *) malloc(sizeof(char) * (strlen(path) + 1 + 8)); |
| 1145 | int bytes = 0; | 1099 | int bytes = 0; |
| 1146 | uint64_t size_requested = newsize; | 1100 | uint64_t size_requested = newsize; |
| 1101 | afc_error_t ret = AFC_E_UNKNOWN_ERROR; | ||
| 1147 | 1102 | ||
| 1148 | if (!client || !path || !client->afc_packet || client->sfd < 0) | 1103 | if (!client || !path || !client->afc_packet || client->sfd < 0) |
| 1149 | return IPHONE_E_INVALID_ARG; | 1104 | return AFC_E_INVALID_ARGUMENT; |
| 1150 | 1105 | ||
| 1151 | afc_lock(client); | 1106 | afc_lock(client); |
| 1152 | 1107 | ||
| @@ -1154,24 +1109,21 @@ iphone_error_t afc_truncate(afc_client_t client, const char *path, off_t newsize | |||
| 1154 | memcpy(send, &size_requested, 8); | 1109 | memcpy(send, &size_requested, 8); |
| 1155 | memcpy(send + 8, path, strlen(path) + 1); | 1110 | memcpy(send + 8, path, strlen(path) + 1); |
| 1156 | client->afc_packet->entire_length = client->afc_packet->this_length = 0; | 1111 | client->afc_packet->entire_length = client->afc_packet->this_length = 0; |
| 1157 | client->afc_packet->operation = AFC_TRUNCATE; | 1112 | client->afc_packet->operation = AFC_OP_TRUNCATE; |
| 1158 | bytes = dispatch_AFC_packet(client, send, 8 + strlen(path) + 1); | 1113 | bytes = afc_dispatch_packet(client, send, 8 + strlen(path) + 1); |
| 1159 | free(send); | 1114 | free(send); |
| 1160 | if (bytes <= 0) { | 1115 | if (bytes <= 0) { |
| 1161 | afc_unlock(client); | 1116 | afc_unlock(client); |
| 1162 | return IPHONE_E_NOT_ENOUGH_DATA; | 1117 | return AFC_E_NOT_ENOUGH_DATA; |
| 1163 | } | 1118 | } |
| 1164 | // Receive response | 1119 | // Receive response |
| 1165 | bytes = receive_AFC_data(client, &response); | 1120 | ret = afc_receive_data(client, &response, &bytes); |
| 1166 | if (response) | 1121 | if (response) |
| 1167 | free(response); | 1122 | free(response); |
| 1168 | 1123 | ||
| 1169 | afc_unlock(client); | 1124 | afc_unlock(client); |
| 1170 | 1125 | ||
| 1171 | if (bytes < 0) { | 1126 | return ret; |
| 1172 | return IPHONE_E_AFC_ERROR; | ||
| 1173 | } | ||
| 1174 | return IPHONE_E_SUCCESS; | ||
| 1175 | } | 1127 | } |
| 1176 | 1128 | ||
| 1177 | /** Creates a hard link or symbolic link on the device. | 1129 | /** Creates a hard link or symbolic link on the device. |
| @@ -1181,47 +1133,44 @@ iphone_error_t afc_truncate(afc_client_t client, const char *path, off_t newsize | |||
| 1181 | * @param target The file to be linked. | 1133 | * @param target The file to be linked. |
| 1182 | * @param linkname The name of link. | 1134 | * @param linkname The name of link. |
| 1183 | * | 1135 | * |
| 1184 | * @return IPHONE_E_SUCCESS if everything went well, IPHONE_E_INVALID_ARG | 1136 | * @return AFC_E_SUCCESS if everything went well, AFC_E_INVALID_ARGUMENT |
| 1185 | * if arguments are NULL or invalid, IPHONE_E_NOT_ENOUGH_DATA otherwise. | 1137 | * if arguments are NULL or invalid, AFC_E_NOT_ENOUGH_DATA otherwise. |
| 1186 | */ | 1138 | */ |
| 1187 | iphone_error_t afc_make_link(afc_client_t client, afc_link_type_t linktype, const char *target, const char *linkname) | 1139 | afc_error_t afc_make_link(afc_client_t client, afc_link_type_t linktype, const char *target, const char *linkname) |
| 1188 | { | 1140 | { |
| 1189 | char *response = NULL; | 1141 | char *response = NULL; |
| 1190 | char *send = (char *) malloc(sizeof(char) * (strlen(target)+1 + strlen(linkname)+1 + 8)); | 1142 | char *send = (char *) malloc(sizeof(char) * (strlen(target)+1 + strlen(linkname)+1 + 8)); |
| 1191 | int bytes = 0; | 1143 | int bytes = 0; |
| 1192 | uint64_t type = linktype; | 1144 | uint64_t type = linktype; |
| 1145 | afc_error_t ret = AFC_E_UNKNOWN_ERROR; | ||
| 1193 | 1146 | ||
| 1194 | if (!client || !target || !linkname || !client->afc_packet || client->sfd < 0) | 1147 | if (!client || !target || !linkname || !client->afc_packet || client->sfd < 0) |
| 1195 | return IPHONE_E_INVALID_ARG; | 1148 | return AFC_E_INVALID_ARGUMENT; |
| 1196 | 1149 | ||
| 1197 | afc_lock(client); | 1150 | afc_lock(client); |
| 1198 | 1151 | ||
| 1199 | log_debug_msg("link type: %lld\n", type); | 1152 | log_debug_msg("%s: link type: %lld\n", __func__, type); |
| 1200 | log_debug_msg("target: %s, length:%d\n", target, strlen(target)); | 1153 | log_debug_msg("%s: target: %s, length:%d\n", __func__, target, strlen(target)); |
| 1201 | log_debug_msg("linkname: %s, length:%d\n", linkname, strlen(linkname)); | 1154 | log_debug_msg("%s: linkname: %s, length:%d\n", __func__, linkname, strlen(linkname)); |
| 1202 | 1155 | ||
| 1203 | // Send command | 1156 | // Send command |
| 1204 | memcpy(send, &type, 8); | 1157 | memcpy(send, &type, 8); |
| 1205 | memcpy(send + 8, target, strlen(target) + 1); | 1158 | memcpy(send + 8, target, strlen(target) + 1); |
| 1206 | memcpy(send + 8 + strlen(target) + 1, linkname, strlen(linkname) + 1); | 1159 | memcpy(send + 8 + strlen(target) + 1, linkname, strlen(linkname) + 1); |
| 1207 | client->afc_packet->entire_length = client->afc_packet->this_length = 0; | 1160 | client->afc_packet->entire_length = client->afc_packet->this_length = 0; |
| 1208 | client->afc_packet->operation = AFC_MAKE_LINK; | 1161 | client->afc_packet->operation = AFC_OP_MAKE_LINK; |
| 1209 | bytes = dispatch_AFC_packet(client, send, 8 + strlen(linkname) + 1 + strlen(target) + 1); | 1162 | bytes = afc_dispatch_packet(client, send, 8 + strlen(linkname) + 1 + strlen(target) + 1); |
| 1210 | free(send); | 1163 | free(send); |
| 1211 | if (bytes <= 0) { | 1164 | if (bytes <= 0) { |
| 1212 | afc_unlock(client); | 1165 | afc_unlock(client); |
| 1213 | return IPHONE_E_NOT_ENOUGH_DATA; | 1166 | return AFC_E_NOT_ENOUGH_DATA; |
| 1214 | } | 1167 | } |
| 1215 | // Receive response | 1168 | // Receive response |
| 1216 | bytes = receive_AFC_data(client, &response); | 1169 | ret = afc_receive_data(client, &response, &bytes); |
| 1217 | if (response) | 1170 | if (response) |
| 1218 | free(response); | 1171 | free(response); |
| 1219 | 1172 | ||
| 1220 | afc_unlock(client); | 1173 | afc_unlock(client); |
| 1221 | 1174 | ||
| 1222 | if (bytes < 0) { | 1175 | return ret; |
| 1223 | return IPHONE_E_NOT_ENOUGH_DATA; | ||
| 1224 | } else { | ||
| 1225 | return IPHONE_E_SUCCESS; | ||
| 1226 | } | ||
| 1227 | } | 1176 | } |
| @@ -26,6 +26,8 @@ | |||
| 26 | #include <glib.h> | 26 | #include <glib.h> |
| 27 | #include <stdint.h> | 27 | #include <stdint.h> |
| 28 | 28 | ||
| 29 | #include "libiphone/afc.h" | ||
| 30 | |||
| 29 | #define AFC_MAGIC "CFA6LPAA" | 31 | #define AFC_MAGIC "CFA6LPAA" |
| 30 | #define AFC_MAGIC_LEN (8) | 32 | #define AFC_MAGIC_LEN (8) |
| 31 | 33 | ||
| @@ -48,39 +50,38 @@ struct afc_client_int { | |||
| 48 | AFCPacket *afc_packet; | 50 | AFCPacket *afc_packet; |
| 49 | int file_handle; | 51 | int file_handle; |
| 50 | int lock; | 52 | int lock; |
| 51 | int afcerror; | ||
| 52 | GMutex *mutex; | 53 | GMutex *mutex; |
| 53 | }; | 54 | }; |
| 54 | 55 | ||
| 56 | /* AFC Operations */ | ||
| 55 | enum { | 57 | enum { |
| 56 | AFC_ERROR = 0x00000001, | 58 | AFC_OP_STATUS = 0x00000001, // Status |
| 57 | AFC_SUCCESS_RESPONSE = 0x00000002, | 59 | AFC_OP_DATA = 0x00000002, // Data |
| 58 | AFC_LIST_DIR = 0x00000003, // ReadDir | 60 | AFC_OP_READ_DIR = 0x00000003, // ReadDir |
| 59 | // 0x00000004 // ReadFile | 61 | AFC_OP_READ_FILE = 0x00000004, // ReadFile |
| 60 | // 0x00000005 // WriteFile | 62 | AFC_OP_WRITE_FILE = 0x00000005, // WriteFile |
| 61 | // 0x00000006 // WritePart | 63 | AFC_OP_WRITE_PART = 0x00000006, // WritePart |
| 62 | AFC_TRUNCATE = 0x00000007, // Truncate | 64 | AFC_OP_TRUNCATE = 0x00000007, // TruncateFile |
| 63 | AFC_DELETE = 0x00000008, // RemovePath | 65 | AFC_OP_REMOVE_PATH = 0x00000008, // RemovePath |
| 64 | AFC_MAKE_DIR = 0x00000009, // MakeDir | 66 | AFC_OP_MAKE_DIR = 0x00000009, // MakeDir |
| 65 | AFC_GET_INFO = 0x0000000a, // GetFileInfo | 67 | AFC_OP_GET_FILE_INFO = 0x0000000a, // GetFileInfo |
| 66 | AFC_GET_DEVINFO = 0x0000000b, // GetDeviceInfo | 68 | AFC_OP_GET_DEVINFO = 0x0000000b, // GetDeviceInfo |
| 67 | // 0x0000000c // same as 5, but writes to temp file, then renames it. | 69 | AFC_OP_WRITE_FILE_ATOM = 0x0000000c, // WriteFileAtomic (tmp file+rename) |
| 68 | AFC_FILE_OPEN = 0x0000000d, // FileRefOpen | 70 | AFC_OP_FILE_OPEN = 0x0000000d, // FileRefOpen |
| 69 | AFC_FILE_HANDLE = 0x0000000e, // _unknownPacket | 71 | AFC_OP_FILE_OPEN_RES = 0x0000000e, // FileRefOpenResult |
| 70 | AFC_READ = 0x0000000f, // FileRefRead | 72 | AFC_OP_READ = 0x0000000f, // FileRefRead |
| 71 | AFC_WRITE = 0x00000010, // FileRefWrite | 73 | AFC_OP_WRITE = 0x00000010, // FileRefWrite |
| 72 | AFC_FILE_SEEK = 0x00000011, // FileRefSeek | 74 | AFC_OP_FILE_SEEK = 0x00000011, // FileRefSeek |
| 73 | AFC_FILE_TELL = 0x00000012, // FileRefTell | 75 | AFC_OP_FILE_TELL = 0x00000012, // FileRefTell |
| 74 | // 0x00000013 // _unknownPacket | 76 | AFC_OP_FILE_TELL_RES = 0x00000013, // FileRefTellResult |
| 75 | AFC_FILE_CLOSE = 0x00000014, // FileRefClose | 77 | AFC_OP_FILE_CLOSE = 0x00000014, // FileRefClose |
| 76 | AFC_FILE_TRUNCATE = 0x00000015, // FileRefSetFileSize (ftruncate) | 78 | AFC_OP_FILE_SET_SIZE = 0x00000015, // FileRefSetFileSize (ftruncate) |
| 77 | // 0x00000016 // SetFatalError | 79 | AFC_OP_GET_CON_INFO = 0x00000016, // GetConnectionInfo |
| 78 | // 0x00000017 // SetConnectionOptions | 80 | AFC_OP_SET_CON_OPTIONS = 0x00000017, // SetConnectionOptions |
| 79 | AFC_RENAME = 0x00000018, // RenamePath | 81 | AFC_OP_RENAME_PATH = 0x00000018, // RenamePath |
| 80 | // 0x00000019 // SetFSBlockSize (0x800000) | 82 | AFC_OP_SET_FS_BS = 0x00000019, // SetFSBlockSize (0x800000) |
| 81 | // 0x0000001A // SetBlockSize (0x800000) | 83 | AFC_OP_SET_SOCKET_BS = 0x0000001A, // SetSocketBlockSize (0x800000) |
| 82 | AFC_FILE_LOCK = 0x0000001B, // FileRefLock | 84 | AFC_OP_FILE_LOCK = 0x0000001B, // FileRefLock |
| 83 | AFC_MAKE_LINK = 0x0000001C // MakeLink | 85 | AFC_OP_MAKE_LINK = 0x0000001C // MakeLink |
| 84 | }; | 86 | }; |
| 85 | 87 | ||
| 86 | static int afcerror_to_errno(int afcerror); | ||
diff --git a/src/MobileSync.c b/src/MobileSync.c index b9a1cb0..4463251 100644 --- a/src/MobileSync.c +++ b/src/MobileSync.c | |||
| @@ -19,25 +19,27 @@ | |||
| 19 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA | 19 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA |
| 20 | */ | 20 | */ |
| 21 | 21 | ||
| 22 | #include "MobileSync.h" | ||
| 23 | #include <plist/plist.h> | 22 | #include <plist/plist.h> |
| 24 | #include <string.h> | 23 | #include <string.h> |
| 25 | #include <stdlib.h> | 24 | #include <stdlib.h> |
| 26 | #include <arpa/inet.h> | 25 | #include <arpa/inet.h> |
| 27 | 26 | ||
| 27 | #include "MobileSync.h" | ||
| 28 | #include "iphone.h" | ||
| 29 | #include "utils.h" | ||
| 28 | 30 | ||
| 29 | #define MSYNC_VERSION_INT1 100 | 31 | #define MSYNC_VERSION_INT1 100 |
| 30 | #define MSYNC_VERSION_INT2 100 | 32 | #define MSYNC_VERSION_INT2 100 |
| 31 | 33 | ||
| 32 | iphone_error_t mobilesync_new_client(iphone_device_t device, int dst_port, | 34 | mobilesync_error_t mobilesync_client_new(iphone_device_t device, int dst_port, |
| 33 | mobilesync_client_t * client) | 35 | mobilesync_client_t * client) |
| 34 | { | 36 | { |
| 35 | if (!device || dst_port == 0 || !client || *client) | 37 | if (!device || dst_port == 0 || !client || *client) |
| 36 | return IPHONE_E_INVALID_ARG; | 38 | return MOBILESYNC_E_INVALID_ARG; |
| 37 | 39 | ||
| 38 | iphone_error_t ret = IPHONE_E_UNKNOWN_ERROR; | 40 | mobilesync_error_t ret = MOBILESYNC_E_UNKNOWN_ERROR; |
| 39 | 41 | ||
| 40 | // Attempt connection | 42 | /* Attempt connection */ |
| 41 | int sfd = usbmuxd_connect(device->handle, dst_port); | 43 | int sfd = usbmuxd_connect(device->handle, dst_port); |
| 42 | if (sfd < 0) { | 44 | if (sfd < 0) { |
| 43 | return ret; | 45 | return ret; |
| @@ -46,10 +48,10 @@ iphone_error_t mobilesync_new_client(iphone_device_t device, int dst_port, | |||
| 46 | mobilesync_client_t client_loc = (mobilesync_client_t) malloc(sizeof(struct mobilesync_client_int)); | 48 | mobilesync_client_t client_loc = (mobilesync_client_t) malloc(sizeof(struct mobilesync_client_int)); |
| 47 | client_loc->sfd = sfd; | 49 | client_loc->sfd = sfd; |
| 48 | 50 | ||
| 49 | //perform handshake | 51 | /* perform handshake */ |
| 50 | plist_t array = NULL; | 52 | plist_t array = NULL; |
| 51 | 53 | ||
| 52 | //first receive version | 54 | /* first receive version */ |
| 53 | ret = mobilesync_recv(client_loc, &array); | 55 | ret = mobilesync_recv(client_loc, &array); |
| 54 | 56 | ||
| 55 | plist_t msg_node = plist_find_node_by_string(array, "DLMessageVersionExchange"); | 57 | plist_t msg_node = plist_find_node_by_string(array, "DLMessageVersionExchange"); |
| @@ -86,17 +88,20 @@ iphone_error_t mobilesync_new_client(iphone_device_t device, int dst_port, | |||
| 86 | plist_t rep_node = plist_find_node_by_string(array, "DLMessageDeviceReady"); | 88 | plist_t rep_node = plist_find_node_by_string(array, "DLMessageDeviceReady"); |
| 87 | 89 | ||
| 88 | if (rep_node) { | 90 | if (rep_node) { |
| 89 | ret = IPHONE_E_SUCCESS; | 91 | ret = MOBILESYNC_E_SUCCESS; |
| 90 | *client = client_loc; | 92 | *client = client_loc; |
| 91 | } | 93 | } |
| 94 | else | ||
| 95 | { | ||
| 96 | ret = MOBILESYNC_E_BAD_VERSION; | ||
| 97 | } | ||
| 92 | plist_free(array); | 98 | plist_free(array); |
| 93 | array = NULL; | 99 | array = NULL; |
| 94 | |||
| 95 | } | 100 | } |
| 96 | } | 101 | } |
| 97 | 102 | ||
| 98 | if (IPHONE_E_SUCCESS != ret) | 103 | if (MOBILESYNC_E_SUCCESS != ret) |
| 99 | mobilesync_free_client(client_loc); | 104 | mobilesync_client_free(client_loc); |
| 100 | 105 | ||
| 101 | return ret; | 106 | return ret; |
| 102 | } | 107 | } |
| @@ -115,13 +120,13 @@ static void mobilesync_disconnect(mobilesync_client_t client) | |||
| 115 | array = NULL; | 120 | array = NULL; |
| 116 | } | 121 | } |
| 117 | 122 | ||
| 118 | iphone_error_t mobilesync_free_client(mobilesync_client_t client) | 123 | mobilesync_error_t mobilesync_client_free(mobilesync_client_t client) |
| 119 | { | 124 | { |
| 120 | if (!client) | 125 | if (!client) |
| 121 | return IPHONE_E_INVALID_ARG; | 126 | return IPHONE_E_INVALID_ARG; |
| 122 | 127 | ||
| 123 | mobilesync_disconnect(client); | 128 | mobilesync_disconnect(client); |
| 124 | return usbmuxd_disconnect(client->sfd); | 129 | return (usbmuxd_disconnect(client->sfd) == 0 ? MOBILESYNC_E_SUCCESS: MOBILESYNC_E_MUX_ERROR); |
| 125 | } | 130 | } |
| 126 | 131 | ||
| 127 | /** Polls the iPhone for MobileSync data. | 132 | /** Polls the iPhone for MobileSync data. |
| @@ -131,11 +136,11 @@ iphone_error_t mobilesync_free_client(mobilesync_client_t client) | |||
| 131 | * | 136 | * |
| 132 | * @return an error code | 137 | * @return an error code |
| 133 | */ | 138 | */ |
| 134 | iphone_error_t mobilesync_recv(mobilesync_client_t client, plist_t * plist) | 139 | mobilesync_error_t mobilesync_recv(mobilesync_client_t client, plist_t * plist) |
| 135 | { | 140 | { |
| 136 | if (!client || !plist || (plist && *plist)) | 141 | if (!client || !plist || (plist && *plist)) |
| 137 | return IPHONE_E_INVALID_ARG; | 142 | return MOBILESYNC_E_INVALID_ARG; |
| 138 | iphone_error_t ret = IPHONE_E_UNKNOWN_ERROR; | 143 | mobilesync_error_t ret = MOBILESYNC_E_UNKNOWN_ERROR; |
| 139 | char *receive = NULL; | 144 | char *receive = NULL; |
| 140 | uint32_t datalen = 0, bytes = 0, received_bytes = 0; | 145 | uint32_t datalen = 0, bytes = 0, received_bytes = 0; |
| 141 | 146 | ||
| @@ -145,14 +150,14 @@ iphone_error_t mobilesync_recv(mobilesync_client_t client, plist_t * plist) | |||
| 145 | receive = (char *) malloc(sizeof(char) * datalen); | 150 | receive = (char *) malloc(sizeof(char) * datalen); |
| 146 | 151 | ||
| 147 | /* fill buffer and request more packets if needed */ | 152 | /* fill buffer and request more packets if needed */ |
| 148 | while ((received_bytes < datalen) && (ret == IPHONE_E_SUCCESS)) { | 153 | while ((received_bytes < datalen) && (ret == MOBILESYNC_E_SUCCESS)) { |
| 149 | ret = usbmuxd_recv(client->sfd, receive + received_bytes, datalen - received_bytes, &bytes); | 154 | ret = usbmuxd_recv(client->sfd, receive + received_bytes, datalen - received_bytes, &bytes); |
| 150 | received_bytes += bytes; | 155 | received_bytes += bytes; |
| 151 | } | 156 | } |
| 152 | 157 | ||
| 153 | if (ret != IPHONE_E_SUCCESS) { | 158 | if (ret != MOBILESYNC_E_SUCCESS) { |
| 154 | free(receive); | 159 | free(receive); |
| 155 | return ret; | 160 | return MOBILESYNC_E_MUX_ERROR; |
| 156 | } | 161 | } |
| 157 | 162 | ||
| 158 | plist_from_bin(receive, received_bytes, plist); | 163 | plist_from_bin(receive, received_bytes, plist); |
| @@ -161,7 +166,7 @@ iphone_error_t mobilesync_recv(mobilesync_client_t client, plist_t * plist) | |||
| 161 | char *XMLContent = NULL; | 166 | char *XMLContent = NULL; |
| 162 | uint32_t length = 0; | 167 | uint32_t length = 0; |
| 163 | plist_to_xml(*plist, &XMLContent, &length); | 168 | plist_to_xml(*plist, &XMLContent, &length); |
| 164 | log_dbg_msg(DBGMASK_MOBILESYNC, "Recv msg :\nsize : %i\nbuffer :\n%s\n", length, XMLContent); | 169 | log_dbg_msg(DBGMASK_MOBILESYNC, "%s: plist size: %i\nbuffer :\n%s\n", __func__, length, XMLContent); |
| 165 | free(XMLContent); | 170 | free(XMLContent); |
| 166 | 171 | ||
| 167 | return ret; | 172 | return ret; |
| @@ -177,15 +182,15 @@ iphone_error_t mobilesync_recv(mobilesync_client_t client, plist_t * plist) | |||
| 177 | * | 182 | * |
| 178 | * @return an error code | 183 | * @return an error code |
| 179 | */ | 184 | */ |
| 180 | iphone_error_t mobilesync_send(mobilesync_client_t client, plist_t plist) | 185 | mobilesync_error_t mobilesync_send(mobilesync_client_t client, plist_t plist) |
| 181 | { | 186 | { |
| 182 | if (!client || !plist) | 187 | if (!client || !plist) |
| 183 | return IPHONE_E_INVALID_ARG; | 188 | return MOBILESYNC_E_INVALID_ARG; |
| 184 | 189 | ||
| 185 | char *XMLContent = NULL; | 190 | char *XMLContent = NULL; |
| 186 | uint32_t length = 0; | 191 | uint32_t length = 0; |
| 187 | plist_to_xml(plist, &XMLContent, &length); | 192 | plist_to_xml(plist, &XMLContent, &length); |
| 188 | log_dbg_msg(DBGMASK_MOBILESYNC, "Send msg :\nsize : %i\nbuffer :\n%s\n", length, XMLContent); | 193 | log_dbg_msg(DBGMASK_MOBILESYNC, "%s: plist size: %i\nbuffer :\n%s\n", __func__, length, XMLContent); |
| 189 | free(XMLContent); | 194 | free(XMLContent); |
| 190 | 195 | ||
| 191 | char *content = NULL; | 196 | char *content = NULL; |
| @@ -195,7 +200,7 @@ iphone_error_t mobilesync_send(mobilesync_client_t client, plist_t plist) | |||
| 195 | 200 | ||
| 196 | char *real_query; | 201 | char *real_query; |
| 197 | int bytes; | 202 | int bytes; |
| 198 | iphone_error_t ret = IPHONE_E_UNKNOWN_ERROR; | 203 | mobilesync_error_t ret = MOBILESYNC_E_UNKNOWN_ERROR; |
| 199 | 204 | ||
| 200 | real_query = (char *) malloc(sizeof(char) * (length + 4)); | 205 | real_query = (char *) malloc(sizeof(char) * (length + 4)); |
| 201 | length = htonl(length); | 206 | length = htonl(length); |
| @@ -204,6 +209,6 @@ iphone_error_t mobilesync_send(mobilesync_client_t client, plist_t plist) | |||
| 204 | 209 | ||
| 205 | ret = usbmuxd_send(client->sfd, real_query, ntohl(length) + sizeof(length), (uint32_t*)&bytes); | 210 | ret = usbmuxd_send(client->sfd, real_query, ntohl(length) + sizeof(length), (uint32_t*)&bytes); |
| 206 | free(real_query); | 211 | free(real_query); |
| 207 | return ret; | 212 | return (ret == 0 ? MOBILESYNC_E_SUCCESS: MOBILESYNC_E_MUX_ERROR); |
| 208 | } | 213 | } |
| 209 | 214 | ||
diff --git a/src/MobileSync.h b/src/MobileSync.h index 5279ce0..6347399 100644 --- a/src/MobileSync.h +++ b/src/MobileSync.h | |||
| @@ -21,12 +21,8 @@ | |||
| 21 | #ifndef MOBILESYNC_H | 21 | #ifndef MOBILESYNC_H |
| 22 | #define MOBILESYNC_H | 22 | #define MOBILESYNC_H |
| 23 | 23 | ||
| 24 | #include "iphone.h" | ||
| 25 | #include "utils.h" | ||
| 26 | #include "libiphone/mobilesync.h" | 24 | #include "libiphone/mobilesync.h" |
| 27 | 25 | ||
| 28 | #include <plist/plist.h> | ||
| 29 | |||
| 30 | struct mobilesync_client_int { | 26 | struct mobilesync_client_int { |
| 31 | int sfd; | 27 | int sfd; |
| 32 | }; | 28 | }; |
diff --git a/src/NotificationProxy.c b/src/NotificationProxy.c index 511b07f..e4735cc 100644 --- a/src/NotificationProxy.c +++ b/src/NotificationProxy.c | |||
| @@ -25,6 +25,7 @@ | |||
| 25 | #include <unistd.h> | 25 | #include <unistd.h> |
| 26 | #include <arpa/inet.h> | 26 | #include <arpa/inet.h> |
| 27 | #include <plist/plist.h> | 27 | #include <plist/plist.h> |
| 28 | |||
| 28 | #include "NotificationProxy.h" | 29 | #include "NotificationProxy.h" |
| 29 | #include "iphone.h" | 30 | #include "iphone.h" |
| 30 | #include "utils.h" | 31 | #include "utils.h" |
| @@ -61,24 +62,24 @@ static void np_unlock(np_client_t client) | |||
| 61 | * @param client NP to send data to | 62 | * @param client NP to send data to |
| 62 | * @param dict plist to send | 63 | * @param dict plist to send |
| 63 | * | 64 | * |
| 64 | * @return IPHONE_E_SUCCESS or an error code. | 65 | * @return NP_E_SUCCESS or an error code. |
| 65 | */ | 66 | */ |
| 66 | static iphone_error_t np_plist_send(np_client_t client, plist_t dict) | 67 | static np_error_t np_plist_send(np_client_t client, plist_t dict) |
| 67 | { | 68 | { |
| 68 | char *XML_content = NULL; | 69 | char *XML_content = NULL; |
| 69 | uint32_t length = 0; | 70 | uint32_t length = 0; |
| 70 | uint32_t nlen = 0; | 71 | uint32_t nlen = 0; |
| 71 | int bytes = 0; | 72 | int bytes = 0; |
| 72 | iphone_error_t res = IPHONE_E_UNKNOWN_ERROR; | 73 | np_error_t res = NP_E_UNKNOWN_ERROR; |
| 73 | 74 | ||
| 74 | if (!client || !dict) { | 75 | if (!client || !dict) { |
| 75 | return IPHONE_E_INVALID_ARG; | 76 | return NP_E_INVALID_ARG; |
| 76 | } | 77 | } |
| 77 | 78 | ||
| 78 | plist_to_xml(dict, &XML_content, &length); | 79 | plist_to_xml(dict, &XML_content, &length); |
| 79 | 80 | ||
| 80 | if (!XML_content || length == 0) { | 81 | if (!XML_content || length == 0) { |
| 81 | return IPHONE_E_PLIST_ERROR; | 82 | return NP_E_PLIST_ERROR; |
| 82 | } | 83 | } |
| 83 | 84 | ||
| 84 | nlen = htonl(length); | 85 | nlen = htonl(length); |
| @@ -87,7 +88,7 @@ static iphone_error_t np_plist_send(np_client_t client, plist_t dict) | |||
| 87 | usbmuxd_send(client->sfd, XML_content, length, (uint32_t*)&bytes); | 88 | usbmuxd_send(client->sfd, XML_content, length, (uint32_t*)&bytes); |
| 88 | if (bytes > 0) { | 89 | if (bytes > 0) { |
| 89 | if ((uint32_t)bytes == length) { | 90 | if ((uint32_t)bytes == length) { |
| 90 | res = IPHONE_E_SUCCESS; | 91 | res = NP_E_SUCCESS; |
| 91 | } else { | 92 | } else { |
| 92 | log_debug_msg("%s: ERROR: Could not send all data (%d of %d)!\n", __func__, bytes, length); | 93 | log_debug_msg("%s: ERROR: Could not send all data (%d of %d)!\n", __func__, bytes, length); |
| 93 | } | 94 | } |
| @@ -110,19 +111,19 @@ static iphone_error_t np_plist_send(np_client_t client, plist_t dict) | |||
| 110 | * | 111 | * |
| 111 | * @return A handle to the newly-connected client or NULL upon error. | 112 | * @return A handle to the newly-connected client or NULL upon error. |
| 112 | */ | 113 | */ |
| 113 | iphone_error_t np_new_client ( iphone_device_t device, int dst_port, np_client_t *client ) | 114 | np_error_t np_client_new(iphone_device_t device, int dst_port, np_client_t *client) |
| 114 | { | 115 | { |
| 115 | //makes sure thread environment is available | 116 | /* makes sure thread environment is available */ |
| 116 | if (!g_thread_supported()) | 117 | if (!g_thread_supported()) |
| 117 | g_thread_init(NULL); | 118 | g_thread_init(NULL); |
| 118 | 119 | ||
| 119 | if (!device) | 120 | if (!device) |
| 120 | return IPHONE_E_INVALID_ARG; | 121 | return NP_E_INVALID_ARG; |
| 121 | 122 | ||
| 122 | // Attempt connection | 123 | /* Attempt connection */ |
| 123 | int sfd = usbmuxd_connect(device->handle, dst_port); | 124 | int sfd = usbmuxd_connect(device->handle, dst_port); |
| 124 | if (sfd < 0) { | 125 | if (sfd < 0) { |
| 125 | return IPHONE_E_UNKNOWN_ERROR; //ret; | 126 | return NP_E_UNKNOWN_ERROR; |
| 126 | } | 127 | } |
| 127 | 128 | ||
| 128 | np_client_t client_loc = (np_client_t) malloc(sizeof(struct np_client_int)); | 129 | np_client_t client_loc = (np_client_t) malloc(sizeof(struct np_client_int)); |
| @@ -133,17 +134,17 @@ iphone_error_t np_new_client ( iphone_device_t device, int dst_port, np_client_t | |||
| 133 | client_loc->notifier = NULL; | 134 | client_loc->notifier = NULL; |
| 134 | 135 | ||
| 135 | *client = client_loc; | 136 | *client = client_loc; |
| 136 | return IPHONE_E_SUCCESS; | 137 | return NP_E_SUCCESS; |
| 137 | } | 138 | } |
| 138 | 139 | ||
| 139 | /** Disconnects an NP client from the phone. | 140 | /** Disconnects an NP client from the phone. |
| 140 | * | 141 | * |
| 141 | * @param client The client to disconnect. | 142 | * @param client The client to disconnect. |
| 142 | */ | 143 | */ |
| 143 | iphone_error_t np_free_client ( np_client_t client ) | 144 | np_error_t np_client_free(np_client_t client) |
| 144 | { | 145 | { |
| 145 | if (!client) | 146 | if (!client) |
| 146 | return IPHONE_E_INVALID_ARG; | 147 | return NP_E_INVALID_ARG; |
| 147 | 148 | ||
| 148 | usbmuxd_disconnect(client->sfd); | 149 | usbmuxd_disconnect(client->sfd); |
| 149 | client->sfd = -1; | 150 | client->sfd = -1; |
| @@ -156,7 +157,7 @@ iphone_error_t np_free_client ( np_client_t client ) | |||
| 156 | } | 157 | } |
| 157 | free(client); | 158 | free(client); |
| 158 | 159 | ||
| 159 | return IPHONE_E_SUCCESS; | 160 | return NP_E_SUCCESS; |
| 160 | } | 161 | } |
| 161 | 162 | ||
| 162 | /** Sends a notification to the device's Notification Proxy. | 163 | /** Sends a notification to the device's Notification Proxy. |
| @@ -168,10 +169,10 @@ iphone_error_t np_free_client ( np_client_t client ) | |||
| 168 | * @param client The client to send to | 169 | * @param client The client to send to |
| 169 | * @param notification The notification message to send | 170 | * @param notification The notification message to send |
| 170 | */ | 171 | */ |
| 171 | iphone_error_t np_post_notification( np_client_t client, const char *notification ) | 172 | np_error_t np_post_notification(np_client_t client, const char *notification) |
| 172 | { | 173 | { |
| 173 | if (!client || !notification) { | 174 | if (!client || !notification) { |
| 174 | return IPHONE_E_INVALID_ARG; | 175 | return NP_E_INVALID_ARG; |
| 175 | } | 176 | } |
| 176 | np_lock(client); | 177 | np_lock(client); |
| 177 | 178 | ||
| @@ -181,7 +182,7 @@ iphone_error_t np_post_notification( np_client_t client, const char *notificatio | |||
| 181 | plist_add_sub_key_el(dict, "Name"); | 182 | plist_add_sub_key_el(dict, "Name"); |
| 182 | plist_add_sub_string_el(dict, notification); | 183 | plist_add_sub_string_el(dict, notification); |
| 183 | 184 | ||
| 184 | iphone_error_t res = np_plist_send(client, dict); | 185 | np_error_t res = np_plist_send(client, dict); |
| 185 | plist_free(dict); | 186 | plist_free(dict); |
| 186 | 187 | ||
| 187 | dict = plist_new_dict(); | 188 | dict = plist_new_dict(); |
| @@ -191,7 +192,7 @@ iphone_error_t np_post_notification( np_client_t client, const char *notificatio | |||
| 191 | res = np_plist_send(client, dict); | 192 | res = np_plist_send(client, dict); |
| 192 | plist_free(dict); | 193 | plist_free(dict); |
| 193 | 194 | ||
| 194 | if (res != IPHONE_E_SUCCESS) { | 195 | if (res != NP_E_SUCCESS) { |
| 195 | log_debug_msg("%s: Error sending XML plist to device!\n", __func__); | 196 | log_debug_msg("%s: Error sending XML plist to device!\n", __func__); |
| 196 | } | 197 | } |
| 197 | 198 | ||
| @@ -204,10 +205,10 @@ iphone_error_t np_post_notification( np_client_t client, const char *notificatio | |||
| 204 | * @param client The client to send to | 205 | * @param client The client to send to |
| 205 | * @param notification The notifications that should be observed. | 206 | * @param notification The notifications that should be observed. |
| 206 | */ | 207 | */ |
| 207 | iphone_error_t np_observe_notification( np_client_t client, const char *notification ) | 208 | np_error_t np_observe_notification( np_client_t client, const char *notification ) |
| 208 | { | 209 | { |
| 209 | if (!client || !notification) { | 210 | if (!client || !notification) { |
| 210 | return IPHONE_E_INVALID_ARG; | 211 | return NP_E_INVALID_ARG; |
| 211 | } | 212 | } |
| 212 | np_lock(client); | 213 | np_lock(client); |
| 213 | 214 | ||
| @@ -217,8 +218,8 @@ iphone_error_t np_observe_notification( np_client_t client, const char *notifica | |||
| 217 | plist_add_sub_key_el(dict, "Name"); | 218 | plist_add_sub_key_el(dict, "Name"); |
| 218 | plist_add_sub_string_el(dict, notification); | 219 | plist_add_sub_string_el(dict, notification); |
| 219 | 220 | ||
| 220 | iphone_error_t res = np_plist_send(client, dict); | 221 | np_error_t res = np_plist_send(client, dict); |
| 221 | if (res != IPHONE_E_SUCCESS) { | 222 | if (res != NP_E_SUCCESS) { |
| 222 | log_debug_msg("%s: Error sending XML plist to device!\n", __func__); | 223 | log_debug_msg("%s: Error sending XML plist to device!\n", __func__); |
| 223 | } | 224 | } |
| 224 | plist_free(dict); | 225 | plist_free(dict); |
| @@ -227,7 +228,6 @@ iphone_error_t np_observe_notification( np_client_t client, const char *notifica | |||
| 227 | return res; | 228 | return res; |
| 228 | } | 229 | } |
| 229 | 230 | ||
| 230 | |||
| 231 | /** Notifies the iphone to send a notification on specified events. | 231 | /** Notifies the iphone to send a notification on specified events. |
| 232 | * | 232 | * |
| 233 | * observation messages seen so far: | 233 | * observation messages seen so far: |
| @@ -247,14 +247,14 @@ iphone_error_t np_observe_notification( np_client_t client, const char *notifica | |||
| 247 | * terminating NULL entry. However this parameter can be NULL; in this case, | 247 | * terminating NULL entry. However this parameter can be NULL; in this case, |
| 248 | * the default set of notifications will be used. | 248 | * the default set of notifications will be used. |
| 249 | */ | 249 | */ |
| 250 | iphone_error_t np_observe_notifications( np_client_t client, const char **notification_spec ) | 250 | np_error_t np_observe_notifications(np_client_t client, const char **notification_spec) |
| 251 | { | 251 | { |
| 252 | int i = 0; | 252 | int i = 0; |
| 253 | iphone_error_t res = IPHONE_E_UNKNOWN_ERROR; | 253 | np_error_t res = NP_E_UNKNOWN_ERROR; |
| 254 | const char **notifications = notification_spec; | 254 | const char **notifications = notification_spec; |
| 255 | 255 | ||
| 256 | if (!client) { | 256 | if (!client) { |
| 257 | return IPHONE_E_INVALID_ARG; | 257 | return NP_E_INVALID_ARG; |
| 258 | } | 258 | } |
| 259 | 259 | ||
| 260 | if (!notifications) { | 260 | if (!notifications) { |
| @@ -263,7 +263,7 @@ iphone_error_t np_observe_notifications( np_client_t client, const char **notifi | |||
| 263 | 263 | ||
| 264 | while (notifications[i]) { | 264 | while (notifications[i]) { |
| 265 | res = np_observe_notification(client, notifications[i]); | 265 | res = np_observe_notification(client, notifications[i]); |
| 266 | if (res != IPHONE_E_SUCCESS) { | 266 | if (res != NP_E_SUCCESS) { |
| 267 | break; | 267 | break; |
| 268 | } | 268 | } |
| 269 | i++; | 269 | i++; |
| @@ -279,24 +279,22 @@ iphone_error_t np_observe_notifications( np_client_t client, const char **notifi | |||
| 279 | * @param notification Pointer to a buffer that will be allocated and filled | 279 | * @param notification Pointer to a buffer that will be allocated and filled |
| 280 | * with the notification that has been received. | 280 | * with the notification that has been received. |
| 281 | * | 281 | * |
| 282 | * @return IPHONE_E_SUCCESS if a notification has been received, | 282 | * @return 0 if a notification has been received or nothing has been received, |
| 283 | * IPHONE_E_TIMEOUT if nothing has been received, | ||
| 284 | * or an error value if an error occured. | 283 | * or an error value if an error occured. |
| 285 | * | 284 | * |
| 286 | * @note You probably want to check out np_set_notify_callback | 285 | * @note You probably want to check out np_set_notify_callback |
| 287 | * @see np_set_notify_callback | 286 | * @see np_set_notify_callback |
| 288 | */ | 287 | */ |
| 289 | static iphone_error_t np_get_notification( np_client_t client, char **notification ) | 288 | static int np_get_notification(np_client_t client, char **notification) |
| 290 | { | 289 | { |
| 291 | uint32_t bytes = 0; | 290 | uint32_t bytes = 0; |
| 292 | iphone_error_t res; | 291 | int res = 0; |
| 293 | uint32_t pktlen = 0; | 292 | uint32_t pktlen = 0; |
| 294 | char *XML_content = NULL; | 293 | char *XML_content = NULL; |
| 295 | plist_t dict = NULL; | 294 | plist_t dict = NULL; |
| 296 | 295 | ||
| 297 | if (!client || client->sfd < 0 || *notification) { | 296 | if (!client || client->sfd < 0 || *notification) |
| 298 | return IPHONE_E_INVALID_ARG; | 297 | return -1; |
| 299 | } | ||
| 300 | 298 | ||
| 301 | np_lock(client); | 299 | np_lock(client); |
| 302 | 300 | ||
| @@ -304,7 +302,7 @@ static iphone_error_t np_get_notification( np_client_t client, char **notificati | |||
| 304 | log_debug_msg("NotificationProxy: initial read=%i\n", bytes); | 302 | log_debug_msg("NotificationProxy: initial read=%i\n", bytes); |
| 305 | if (bytes < 4) { | 303 | if (bytes < 4) { |
| 306 | log_debug_msg("NotificationProxy: no notification received!\n"); | 304 | log_debug_msg("NotificationProxy: no notification received!\n"); |
| 307 | res = IPHONE_E_TIMEOUT; | 305 | res = 0; |
| 308 | } else { | 306 | } else { |
| 309 | if ((char)pktlen == 0) { | 307 | if ((char)pktlen == 0) { |
| 310 | pktlen = ntohl(pktlen); | 308 | pktlen = ntohl(pktlen); |
| @@ -314,7 +312,7 @@ static iphone_error_t np_get_notification( np_client_t client, char **notificati | |||
| 314 | 312 | ||
| 315 | usbmuxd_recv_timeout(client->sfd, XML_content, pktlen, &bytes, 1000); | 313 | usbmuxd_recv_timeout(client->sfd, XML_content, pktlen, &bytes, 1000); |
| 316 | if (bytes <= 0) { | 314 | if (bytes <= 0) { |
| 317 | res = IPHONE_E_UNKNOWN_ERROR; | 315 | res = -1; |
| 318 | } else { | 316 | } else { |
| 319 | log_debug_msg("NotificationProxy: received data:\n"); | 317 | log_debug_msg("NotificationProxy: received data:\n"); |
| 320 | log_debug_buffer(XML_content, pktlen); | 318 | log_debug_buffer(XML_content, pktlen); |
| @@ -322,7 +320,7 @@ static iphone_error_t np_get_notification( np_client_t client, char **notificati | |||
| 322 | plist_from_xml(XML_content, bytes, &dict); | 320 | plist_from_xml(XML_content, bytes, &dict); |
| 323 | if (!dict) { | 321 | if (!dict) { |
| 324 | np_unlock(client); | 322 | np_unlock(client); |
| 325 | return IPHONE_E_PLIST_ERROR; | 323 | return -2; |
| 326 | } | 324 | } |
| 327 | 325 | ||
| 328 | plist_t cmd_key_node = plist_find_node_by_key(dict, "Command"); | 326 | plist_t cmd_key_node = plist_find_node_by_key(dict, "Command"); |
| @@ -347,21 +345,21 @@ static iphone_error_t np_get_notification( np_client_t client, char **notificati | |||
| 347 | plist_get_string_val(name_value_node, &name_value); | 345 | plist_get_string_val(name_value_node, &name_value); |
| 348 | } | 346 | } |
| 349 | 347 | ||
| 350 | res = IPHONE_E_PLIST_ERROR; | 348 | res = -2; |
| 351 | if (name_key && name_value && !strcmp(name_key, "Name")) { | 349 | if (name_key && name_value && !strcmp(name_key, "Name")) { |
| 352 | *notification = name_value; | 350 | *notification = name_value; |
| 353 | log_debug_msg("%s: got notification %s\n", __func__, name_value); | 351 | log_debug_msg("%s: got notification %s\n", __func__, name_value); |
| 354 | res = IPHONE_E_SUCCESS; | 352 | res = 0; |
| 355 | } | 353 | } |
| 356 | free(name_key); | 354 | free(name_key); |
| 357 | } else if (cmd_value && !strcmp(cmd_value, "ProxyDeath")) { | 355 | } else if (cmd_value && !strcmp(cmd_value, "ProxyDeath")) { |
| 358 | log_debug_msg("%s: ERROR: NotificationProxy died!\n", __func__); | 356 | log_debug_msg("%s: ERROR: NotificationProxy died!\n", __func__); |
| 359 | res = IPHONE_E_UNKNOWN_ERROR; | 357 | res = -1; |
| 360 | } else if (cmd_value) { | 358 | } else if (cmd_value) { |
| 361 | log_debug_msg("%d: unknown NotificationProxy command '%s' received!\n", __func__); | 359 | log_debug_msg("%d: unknown NotificationProxy command '%s' received!\n", __func__); |
| 362 | res = IPHONE_E_UNKNOWN_ERROR; | 360 | res = -1; |
| 363 | } else { | 361 | } else { |
| 364 | res = IPHONE_E_PLIST_ERROR; | 362 | res = -2; |
| 365 | } | 363 | } |
| 366 | if (cmd_value) { | 364 | if (cmd_value) { |
| 367 | free(cmd_value); | 365 | free(cmd_value); |
| @@ -372,7 +370,7 @@ static iphone_error_t np_get_notification( np_client_t client, char **notificati | |||
| 372 | XML_content = NULL; | 370 | XML_content = NULL; |
| 373 | } | 371 | } |
| 374 | } else { | 372 | } else { |
| 375 | res = IPHONE_E_UNKNOWN_ERROR; | 373 | res = -1; |
| 376 | } | 374 | } |
| 377 | } | 375 | } |
| 378 | 376 | ||
| @@ -418,15 +416,15 @@ gpointer np_notifier( gpointer arg ) | |||
| 418 | * @param notify_cb pointer to a callback function or NULL to de-register a | 416 | * @param notify_cb pointer to a callback function or NULL to de-register a |
| 419 | * previously set callback function | 417 | * previously set callback function |
| 420 | * | 418 | * |
| 421 | * @return IPHONE_E_SUCCESS when the callback was successfully registered, | 419 | * @return NP_E_SUCCESS when the callback was successfully registered, |
| 422 | * or an error value when an error occured. | 420 | * or an error value when an error occured. |
| 423 | */ | 421 | */ |
| 424 | iphone_error_t np_set_notify_callback( np_client_t client, np_notify_cb_t notify_cb ) | 422 | np_error_t np_set_notify_callback( np_client_t client, np_notify_cb_t notify_cb ) |
| 425 | { | 423 | { |
| 426 | if (!client) { | 424 | if (!client) |
| 427 | return IPHONE_E_INVALID_ARG; | 425 | return NP_E_INVALID_ARG; |
| 428 | } | 426 | |
| 429 | iphone_error_t res = IPHONE_E_UNKNOWN_ERROR; | 427 | np_error_t res = NP_E_UNKNOWN_ERROR; |
| 430 | 428 | ||
| 431 | np_lock(client); | 429 | np_lock(client); |
| 432 | if (client->notifier) { | 430 | if (client->notifier) { |
| @@ -446,7 +444,7 @@ iphone_error_t np_set_notify_callback( np_client_t client, np_notify_cb_t notify | |||
| 446 | 444 | ||
| 447 | client->notifier = g_thread_create(np_notifier, npt, TRUE, NULL); | 445 | client->notifier = g_thread_create(np_notifier, npt, TRUE, NULL); |
| 448 | if (client->notifier) { | 446 | if (client->notifier) { |
| 449 | res = IPHONE_E_SUCCESS; | 447 | res = NP_E_SUCCESS; |
| 450 | } | 448 | } |
| 451 | } | 449 | } |
| 452 | } else { | 450 | } else { |
diff --git a/src/NotificationProxy.h b/src/NotificationProxy.h index a10cde4..bc5be43 100644 --- a/src/NotificationProxy.h +++ b/src/NotificationProxy.h | |||
| @@ -18,17 +18,20 @@ | |||
| 18 | * License along with this library; if not, write to the Free Software | 18 | * License along with this library; if not, write to the Free Software |
| 19 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA | 19 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA |
| 20 | */ | 20 | */ |
| 21 | #include "libiphone/notification_proxy.h" | 21 | #ifndef INOTIFICATION_PROXY_H |
| 22 | #define INOTIFICATION_PROXY_H | ||
| 22 | 23 | ||
| 23 | #include <glib.h> | 24 | #include <glib.h> |
| 24 | 25 | ||
| 26 | #include "libiphone/notification_proxy.h" | ||
| 27 | |||
| 25 | struct np_client_int { | 28 | struct np_client_int { |
| 26 | int sfd; | 29 | int sfd; |
| 27 | GMutex *mutex; | 30 | GMutex *mutex; |
| 28 | GThread *notifier; | 31 | GThread *notifier; |
| 29 | }; | 32 | }; |
| 30 | 33 | ||
| 31 | static const char *np_default_notifications[10] = { | 34 | static const char *np_default_notifications[11] = { |
| 32 | NP_SYNC_SUSPEND_REQUEST, | 35 | NP_SYNC_SUSPEND_REQUEST, |
| 33 | NP_SYNC_RESUME_REQUEST, | 36 | NP_SYNC_RESUME_REQUEST, |
| 34 | NP_PHONE_NUMBER_CHANGED, | 37 | NP_PHONE_NUMBER_CHANGED, |
| @@ -38,7 +41,10 @@ static const char *np_default_notifications[10] = { | |||
| 38 | NP_DS_DOMAIN_CHANGED, | 41 | NP_DS_DOMAIN_CHANGED, |
| 39 | NP_APP_INSTALLED, | 42 | NP_APP_INSTALLED, |
| 40 | NP_APP_UNINSTALLED, | 43 | NP_APP_UNINSTALLED, |
| 44 | NP_ITDBPREP_DID_END, | ||
| 41 | NULL | 45 | NULL |
| 42 | }; | 46 | }; |
| 43 | 47 | ||
| 44 | gpointer np_notifier( gpointer arg ); | 48 | gpointer np_notifier(gpointer arg); |
| 49 | |||
| 50 | #endif | ||
diff --git a/src/iphone.c b/src/iphone.c index 0e179e7..e694373 100644 --- a/src/iphone.c +++ b/src/iphone.c | |||
| @@ -19,13 +19,12 @@ | |||
| 19 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA | 19 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA |
| 20 | */ | 20 | */ |
| 21 | 21 | ||
| 22 | #include "iphone.h" | ||
| 23 | #include "utils.h" | ||
| 24 | #include <stdio.h> | 22 | #include <stdio.h> |
| 25 | #include <stdlib.h> | 23 | #include <stdlib.h> |
| 26 | #include <string.h> | 24 | #include <string.h> |
| 27 | #include <errno.h> | 25 | |
| 28 | #include <libiphone/libiphone.h> | 26 | #include "iphone.h" |
| 27 | #include "utils.h" | ||
| 29 | 28 | ||
| 30 | /** | 29 | /** |
| 31 | * Retrieves a list of connected devices from usbmuxd and matches their | 30 | * Retrieves a list of connected devices from usbmuxd and matches their |
| @@ -52,11 +51,11 @@ iphone_error_t iphone_get_device_by_uuid(iphone_device_t * device, const char *u | |||
| 52 | } | 51 | } |
| 53 | if (dev_list && dev_list[0].handle > 0) { | 52 | if (dev_list && dev_list[0].handle > 0) { |
| 54 | if (!uuid) { | 53 | if (!uuid) { |
| 55 | // select first device found if no UUID specified | 54 | /* select first device found if no UUID specified */ |
| 56 | handle = dev_list[0].handle; | 55 | handle = dev_list[0].handle; |
| 57 | strcpy(serial_number, dev_list[0].serial_number); | 56 | strcpy(serial_number, dev_list[0].serial_number); |
| 58 | } else { | 57 | } else { |
| 59 | // otherwise walk through the list | 58 | /* otherwise walk through the list */ |
| 60 | for (i = 0; dev_list[i].handle > 0; i++) { | 59 | for (i = 0; dev_list[i].handle > 0; i++) { |
| 61 | log_debug_msg("%s: device handle=%d, uuid=%s\n", __func__, dev_list[i].handle, dev_list[i].serial_number); | 60 | log_debug_msg("%s: device handle=%d, uuid=%s\n", __func__, dev_list[i].handle, dev_list[i].serial_number); |
| 62 | if (strcasecmp(uuid, dev_list[i].serial_number) == 0) { | 61 | if (strcasecmp(uuid, dev_list[i].serial_number) == 0) { |
| @@ -95,22 +94,22 @@ iphone_error_t iphone_get_device(iphone_device_t * device) | |||
| 95 | return iphone_get_device_by_uuid(device, NULL); | 94 | return iphone_get_device_by_uuid(device, NULL); |
| 96 | } | 95 | } |
| 97 | 96 | ||
| 98 | uint32_t iphone_get_device_handle(iphone_device_t device) | 97 | iphone_error_t iphone_device_get_handle(iphone_device_t device, uint32_t *handle) |
| 99 | { | 98 | { |
| 100 | if (device) { | 99 | if (!device) |
| 101 | return device->handle; | 100 | return IPHONE_E_INVALID_ARG; |
| 102 | } else { | 101 | |
| 103 | return 0; | 102 | *handle = device->handle; |
| 104 | } | 103 | return IPHONE_E_SUCCESS; |
| 105 | } | 104 | } |
| 106 | 105 | ||
| 107 | char* iphone_get_uuid(iphone_device_t device) | 106 | iphone_error_t iphone_device_get_uuid(iphone_device_t device, char **uuid) |
| 108 | { | 107 | { |
| 109 | if (device) { | 108 | if (!device) |
| 110 | return device->serial_number; | 109 | return IPHONE_E_INVALID_ARG; |
| 111 | } else { | 110 | |
| 112 | return NULL; | 111 | *uuid = strdup(device->serial_number); |
| 113 | } | 112 | return IPHONE_E_SUCCESS; |
| 114 | } | 113 | } |
| 115 | 114 | ||
| 116 | /** Cleans up an iPhone structure, then frees the structure itself. | 115 | /** Cleans up an iPhone structure, then frees the structure itself. |
| @@ -119,7 +118,7 @@ char* iphone_get_uuid(iphone_device_t device) | |||
| 119 | * | 118 | * |
| 120 | * @param phone A pointer to an iPhone structure. | 119 | * @param phone A pointer to an iPhone structure. |
| 121 | */ | 120 | */ |
| 122 | iphone_error_t iphone_free_device(iphone_device_t device) | 121 | iphone_error_t iphone_device_free(iphone_device_t device) |
| 123 | { | 122 | { |
| 124 | if (!device) | 123 | if (!device) |
| 125 | return IPHONE_E_INVALID_ARG; | 124 | return IPHONE_E_INVALID_ARG; |
diff --git a/src/iphone.h b/src/iphone.h index 2ed0fba..6e14280 100644 --- a/src/iphone.h +++ b/src/iphone.h | |||
| @@ -24,6 +24,8 @@ | |||
| 24 | 24 | ||
| 25 | #include <stdint.h> | 25 | #include <stdint.h> |
| 26 | 26 | ||
| 27 | #include "libiphone/libiphone.h" | ||
| 28 | |||
| 27 | struct iphone_device_int { | 29 | struct iphone_device_int { |
| 28 | char *buffer; | 30 | char *buffer; |
| 29 | uint32_t handle; | 31 | uint32_t handle; |
diff --git a/src/lockdown.c b/src/lockdown.c index 1a434aa..bc430c9 100644 --- a/src/lockdown.c +++ b/src/lockdown.c | |||
| @@ -19,10 +19,6 @@ | |||
| 19 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA | 19 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA |
| 20 | */ | 20 | */ |
| 21 | 21 | ||
| 22 | #include "utils.h" | ||
| 23 | #include "iphone.h" | ||
| 24 | #include "lockdown.h" | ||
| 25 | #include "userpref.h" | ||
| 26 | #include <arpa/inet.h> | 22 | #include <arpa/inet.h> |
| 27 | #include <errno.h> | 23 | #include <errno.h> |
| 28 | #include <string.h> | 24 | #include <string.h> |
| @@ -30,9 +26,13 @@ | |||
| 30 | #include <glib.h> | 26 | #include <glib.h> |
| 31 | #include <libtasn1.h> | 27 | #include <libtasn1.h> |
| 32 | #include <gnutls/x509.h> | 28 | #include <gnutls/x509.h> |
| 33 | |||
| 34 | #include <plist/plist.h> | 29 | #include <plist/plist.h> |
| 35 | 30 | ||
| 31 | #include "lockdown.h" | ||
| 32 | #include "iphone.h" | ||
| 33 | #include "utils.h" | ||
| 34 | #include "userpref.h" | ||
| 35 | |||
| 36 | #define RESULT_SUCCESS 0 | 36 | #define RESULT_SUCCESS 0 |
| 37 | #define RESULT_FAILURE 1 | 37 | #define RESULT_FAILURE 1 |
| 38 | 38 | ||
| @@ -126,21 +126,23 @@ static int lockdown_check_result(plist_t dict, const char *query_match) | |||
| 126 | * the StopSession Request to the device. | 126 | * the StopSession Request to the device. |
| 127 | * | 127 | * |
| 128 | * @param control The lockdown client | 128 | * @param control The lockdown client |
| 129 | * | ||
| 130 | * @return an error code (LOCKDOWN_E_SUCCESS on success) | ||
| 129 | */ | 131 | */ |
| 130 | iphone_error_t lockdownd_stop_session(lockdownd_client_t client) | 132 | lockdownd_error_t lockdownd_stop_session(lockdownd_client_t client, const char *session_id) |
| 131 | { | 133 | { |
| 132 | if (!client) | 134 | if (!client) |
| 133 | return IPHONE_E_INVALID_ARG; | 135 | return LOCKDOWN_E_INVALID_ARG; |
| 134 | 136 | ||
| 135 | iphone_error_t ret = IPHONE_E_UNKNOWN_ERROR; | 137 | lockdownd_error_t ret = LOCKDOWN_E_UNKNOWN_ERROR; |
| 136 | 138 | ||
| 137 | plist_t dict = plist_new_dict(); | 139 | plist_t dict = plist_new_dict(); |
| 138 | plist_add_sub_key_el(dict, "Request"); | 140 | plist_add_sub_key_el(dict, "Request"); |
| 139 | plist_add_sub_string_el(dict, "StopSession"); | 141 | plist_add_sub_string_el(dict, "StopSession"); |
| 140 | plist_add_sub_key_el(dict, "SessionID"); | 142 | plist_add_sub_key_el(dict, "SessionID"); |
| 141 | plist_add_sub_string_el(dict, client->session_id); | 143 | plist_add_sub_string_el(dict, session_id); |
| 142 | 144 | ||
| 143 | log_dbg_msg(DBGMASK_LOCKDOWND, "iphone_lckd_stop_session() called\n"); | 145 | log_dbg_msg(DBGMASK_LOCKDOWND, "%s: called\n", __func__); |
| 144 | 146 | ||
| 145 | ret = lockdownd_send(client, dict); | 147 | ret = lockdownd_send(client, dict); |
| 146 | 148 | ||
| @@ -150,14 +152,14 @@ iphone_error_t lockdownd_stop_session(lockdownd_client_t client) | |||
| 150 | ret = lockdownd_recv(client, &dict); | 152 | ret = lockdownd_recv(client, &dict); |
| 151 | 153 | ||
| 152 | if (!dict) { | 154 | if (!dict) { |
| 153 | log_dbg_msg(DBGMASK_LOCKDOWND, "lockdownd_stop_session(): IPHONE_E_PLIST_ERROR\n"); | 155 | log_dbg_msg(DBGMASK_LOCKDOWND, "%s: LOCKDOWN_E_PLIST_ERROR\n", __func__); |
| 154 | return IPHONE_E_PLIST_ERROR; | 156 | return LOCKDOWN_E_PLIST_ERROR; |
| 155 | } | 157 | } |
| 156 | 158 | ||
| 157 | ret = IPHONE_E_UNKNOWN_ERROR; | 159 | ret = LOCKDOWN_E_UNKNOWN_ERROR; |
| 158 | if (lockdown_check_result(dict, "StopSession") == RESULT_SUCCESS) { | 160 | if (lockdown_check_result(dict, "StopSession") == RESULT_SUCCESS) { |
| 159 | log_dbg_msg(DBGMASK_LOCKDOWND, "lockdownd_stop_session(): success\n"); | 161 | log_dbg_msg(DBGMASK_LOCKDOWND, "%s: success\n", __func__); |
| 160 | ret = IPHONE_E_SUCCESS; | 162 | ret = LOCKDOWN_E_SUCCESS; |
| 161 | } | 163 | } |
| 162 | plist_free(dict); | 164 | plist_free(dict); |
| 163 | dict = NULL; | 165 | dict = NULL; |
| @@ -171,19 +173,21 @@ iphone_error_t lockdownd_stop_session(lockdownd_client_t client) | |||
| 171 | * performing a close notify, which is done by "gnutls_bye". | 173 | * performing a close notify, which is done by "gnutls_bye". |
| 172 | * | 174 | * |
| 173 | * @param client The lockdown client | 175 | * @param client The lockdown client |
| 176 | * | ||
| 177 | * @return an error code (LOCKDOWN_E_SUCCESS on success) | ||
| 174 | */ | 178 | */ |
| 175 | static iphone_error_t lockdownd_stop_ssl_session(lockdownd_client_t client) | 179 | static lockdownd_error_t lockdownd_stop_ssl_session(lockdownd_client_t client) |
| 176 | { | 180 | { |
| 177 | if (!client) { | 181 | if (!client) { |
| 178 | log_dbg_msg(DBGMASK_LOCKDOWND, "lockdownd_stop_ssl_session(): invalid argument!\n"); | 182 | log_dbg_msg(DBGMASK_LOCKDOWND, "%s: invalid argument!\n", __func__); |
| 179 | return IPHONE_E_INVALID_ARG; | 183 | return LOCKDOWN_E_INVALID_ARG; |
| 180 | } | 184 | } |
| 181 | iphone_error_t ret = IPHONE_E_SUCCESS; | 185 | lockdownd_error_t ret = LOCKDOWN_E_SUCCESS; |
| 182 | 186 | ||
| 183 | if (client->in_SSL) { | 187 | if (client->in_SSL) { |
| 184 | log_dbg_msg(DBGMASK_LOCKDOWND, "Stopping SSL Session\n"); | 188 | log_dbg_msg(DBGMASK_LOCKDOWND, "%s: stopping SSL session\n", __func__); |
| 185 | ret = lockdownd_stop_session(client); | 189 | ret = lockdownd_stop_session(client, client->session_id); |
| 186 | log_dbg_msg(DBGMASK_LOCKDOWND, "Sending SSL close notify\n"); | 190 | log_dbg_msg(DBGMASK_LOCKDOWND, "%s: sending SSL close notify\n", __func__); |
| 187 | gnutls_bye(*client->ssl_session, GNUTLS_SHUT_RDWR); | 191 | gnutls_bye(*client->ssl_session, GNUTLS_SHUT_RDWR); |
| 188 | } | 192 | } |
| 189 | if (client->ssl_session) { | 193 | if (client->ssl_session) { |
| @@ -198,12 +202,14 @@ static iphone_error_t lockdownd_stop_ssl_session(lockdownd_client_t client) | |||
| 198 | /** Closes the lockdownd client and does the necessary housekeeping. | 202 | /** Closes the lockdownd client and does the necessary housekeeping. |
| 199 | * | 203 | * |
| 200 | * @param client The lockdown client | 204 | * @param client The lockdown client |
| 205 | * | ||
| 206 | * @return an error code (LOCKDOWN_E_SUCCESS on success) | ||
| 201 | */ | 207 | */ |
| 202 | iphone_error_t lockdownd_free_client(lockdownd_client_t client) | 208 | lockdownd_error_t lockdownd_client_free(lockdownd_client_t client) |
| 203 | { | 209 | { |
| 204 | if (!client) | 210 | if (!client) |
| 205 | return IPHONE_E_INVALID_ARG; | 211 | return LOCKDOWN_E_INVALID_ARG; |
| 206 | iphone_error_t ret = IPHONE_E_UNKNOWN_ERROR; | 212 | lockdownd_error_t ret = LOCKDOWN_E_UNKNOWN_ERROR; |
| 207 | 213 | ||
| 208 | lockdownd_stop_ssl_session(client); | 214 | lockdownd_stop_ssl_session(client); |
| 209 | 215 | ||
| @@ -224,13 +230,13 @@ iphone_error_t lockdownd_free_client(lockdownd_client_t client) | |||
| 224 | * @param control The lockdownd client | 230 | * @param control The lockdownd client |
| 225 | * @param plist The plist to store the received data | 231 | * @param plist The plist to store the received data |
| 226 | * | 232 | * |
| 227 | * @return an error code (IPHONE_E_SUCCESS on success) | 233 | * @return an error code (LOCKDOWN_E_SUCCESS on success) |
| 228 | */ | 234 | */ |
| 229 | iphone_error_t lockdownd_recv(lockdownd_client_t client, plist_t *plist) | 235 | lockdownd_error_t lockdownd_recv(lockdownd_client_t client, plist_t *plist) |
| 230 | { | 236 | { |
| 231 | if (!client || !plist || (plist && *plist)) | 237 | if (!client || !plist || (plist && *plist)) |
| 232 | return IPHONE_E_INVALID_ARG; | 238 | return LOCKDOWN_E_INVALID_ARG; |
| 233 | iphone_error_t ret = IPHONE_E_UNKNOWN_ERROR; | 239 | lockdownd_error_t ret = LOCKDOWN_E_UNKNOWN_ERROR; |
| 234 | char *receive = NULL; | 240 | char *receive = NULL; |
| 235 | uint32_t datalen = 0, bytes = 0, received_bytes = 0; | 241 | uint32_t datalen = 0, bytes = 0, received_bytes = 0; |
| 236 | 242 | ||
| @@ -240,10 +246,10 @@ iphone_error_t lockdownd_recv(lockdownd_client_t client, plist_t *plist) | |||
| 240 | ssize_t res = gnutls_record_recv(*client->ssl_session, &datalen, sizeof(datalen)); | 246 | ssize_t res = gnutls_record_recv(*client->ssl_session, &datalen, sizeof(datalen)); |
| 241 | if (res < 0) { | 247 | if (res < 0) { |
| 242 | log_dbg_msg(DBGMASK_LOCKDOWND, "gnutls_record_recv: Error occured: %s\n", gnutls_strerror(res)); | 248 | log_dbg_msg(DBGMASK_LOCKDOWND, "gnutls_record_recv: Error occured: %s\n", gnutls_strerror(res)); |
| 243 | return IPHONE_E_SSL_ERROR; | 249 | return LOCKDOWN_E_SSL_ERROR; |
| 244 | } else { | 250 | } else { |
| 245 | bytes = res; | 251 | bytes = res; |
| 246 | ret = IPHONE_E_SUCCESS; | 252 | ret = LOCKDOWN_E_SUCCESS; |
| 247 | } | 253 | } |
| 248 | } | 254 | } |
| 249 | datalen = ntohl(datalen); | 255 | datalen = ntohl(datalen); |
| @@ -253,40 +259,40 @@ iphone_error_t lockdownd_recv(lockdownd_client_t client, plist_t *plist) | |||
| 253 | 259 | ||
| 254 | /* fill buffer and request more packets if needed */ | 260 | /* fill buffer and request more packets if needed */ |
| 255 | if (!client->in_SSL) { | 261 | if (!client->in_SSL) { |
| 256 | while ((received_bytes < datalen) && (ret == IPHONE_E_SUCCESS)) { | 262 | while ((received_bytes < datalen) && (ret == LOCKDOWN_E_SUCCESS)) { |
| 257 | ret = usbmuxd_recv(client->sfd, receive + received_bytes, datalen - received_bytes, &bytes); | 263 | ret = usbmuxd_recv(client->sfd, receive + received_bytes, datalen - received_bytes, &bytes); |
| 258 | received_bytes += bytes; | 264 | received_bytes += bytes; |
| 259 | } | 265 | } |
| 260 | } else { | 266 | } else { |
| 261 | ssize_t res = 0; | 267 | ssize_t res = 0; |
| 262 | while ((received_bytes < datalen) && (ret == IPHONE_E_SUCCESS)) { | 268 | while ((received_bytes < datalen) && (ret == LOCKDOWN_E_SUCCESS)) { |
| 263 | res = gnutls_record_recv(*client->ssl_session, receive + received_bytes, datalen - received_bytes); | 269 | res = gnutls_record_recv(*client->ssl_session, receive + received_bytes, datalen - received_bytes); |
| 264 | if (res < 0) { | 270 | if (res < 0) { |
| 265 | log_dbg_msg(DBGMASK_LOCKDOWND, "gnutls_record_recv: Error occured: %s\n", gnutls_strerror(res)); | 271 | log_dbg_msg(DBGMASK_LOCKDOWND, "gnutls_record_recv: Error occured: %s\n", gnutls_strerror(res)); |
| 266 | ret = IPHONE_E_SSL_ERROR; | 272 | ret = LOCKDOWN_E_SSL_ERROR; |
| 267 | } else { | 273 | } else { |
| 268 | received_bytes += res; | 274 | received_bytes += res; |
| 269 | ret = IPHONE_E_SUCCESS; | 275 | ret = LOCKDOWN_E_SUCCESS; |
| 270 | } | 276 | } |
| 271 | } | 277 | } |
| 272 | } | 278 | } |
| 273 | 279 | ||
| 274 | if (ret != IPHONE_E_SUCCESS) { | 280 | if (ret != LOCKDOWN_E_SUCCESS) { |
| 275 | free(receive); | 281 | free(receive); |
| 276 | return ret; | 282 | return ret; |
| 277 | } | 283 | } |
| 278 | 284 | ||
| 279 | if ((ssize_t)received_bytes <= 0) { | 285 | if ((ssize_t)received_bytes <= 0) { |
| 280 | free(receive); | 286 | free(receive); |
| 281 | return IPHONE_E_NOT_ENOUGH_DATA; | 287 | return LOCKDOWN_E_NOT_ENOUGH_DATA; |
| 282 | } | 288 | } |
| 283 | 289 | ||
| 284 | log_dbg_msg(DBGMASK_LOCKDOWND, "Recv msg :\nsize : %i\nbuffer :\n%s\n", received_bytes, receive); | 290 | log_dbg_msg(DBGMASK_LOCKDOWND, "%s: received msg size: %i, buffer follows:\n%s", __func__, received_bytes, receive); |
| 285 | plist_from_xml(receive, received_bytes, plist); | 291 | plist_from_xml(receive, received_bytes, plist); |
| 286 | free(receive); | 292 | free(receive); |
| 287 | 293 | ||
| 288 | if (!*plist) | 294 | if (!*plist) |
| 289 | ret = IPHONE_E_PLIST_ERROR; | 295 | ret = LOCKDOWN_E_PLIST_ERROR; |
| 290 | 296 | ||
| 291 | return ret; | 297 | return ret; |
| 292 | } | 298 | } |
| @@ -299,27 +305,27 @@ iphone_error_t lockdownd_recv(lockdownd_client_t client, plist_t *plist) | |||
| 299 | * @param client The lockdownd client | 305 | * @param client The lockdownd client |
| 300 | * @param plist The plist to send | 306 | * @param plist The plist to send |
| 301 | * | 307 | * |
| 302 | * @return an error code (IPHONE_E_SUCCESS on success) | 308 | * @return an error code (LOCKDOWN_E_SUCCESS on success) |
| 303 | */ | 309 | */ |
| 304 | iphone_error_t lockdownd_send(lockdownd_client_t client, plist_t plist) | 310 | lockdownd_error_t lockdownd_send(lockdownd_client_t client, plist_t plist) |
| 305 | { | 311 | { |
| 306 | if (!client || !plist) | 312 | if (!client || !plist) |
| 307 | return IPHONE_E_INVALID_ARG; | 313 | return LOCKDOWN_E_INVALID_ARG; |
| 308 | char *real_query; | 314 | char *real_query; |
| 309 | int bytes; | 315 | int bytes; |
| 310 | char *XMLContent = NULL; | 316 | char *XMLContent = NULL; |
| 311 | uint32_t length = 0; | 317 | uint32_t length = 0; |
| 312 | iphone_error_t ret = IPHONE_E_UNKNOWN_ERROR; | 318 | lockdownd_error_t ret = LOCKDOWN_E_UNKNOWN_ERROR; |
| 313 | 319 | ||
| 314 | plist_to_xml(plist, &XMLContent, &length); | 320 | plist_to_xml(plist, &XMLContent, &length); |
| 315 | log_dbg_msg(DBGMASK_LOCKDOWND, "Send msg :\nsize : %i\nbuffer :\n%s\n", length, XMLContent); | 321 | log_dbg_msg(DBGMASK_LOCKDOWND, "%s: sending msg size %i, buffer follows:\n%s", __func__, length, XMLContent); |
| 316 | 322 | ||
| 317 | real_query = (char *) malloc(sizeof(char) * (length + 4)); | 323 | real_query = (char *) malloc(sizeof(char) * (length + 4)); |
| 318 | length = htonl(length); | 324 | length = htonl(length); |
| 319 | memcpy(real_query, &length, sizeof(length)); | 325 | memcpy(real_query, &length, sizeof(length)); |
| 320 | memcpy(real_query + 4, XMLContent, ntohl(length)); | 326 | memcpy(real_query + 4, XMLContent, ntohl(length)); |
| 321 | free(XMLContent); | 327 | free(XMLContent); |
| 322 | log_dbg_msg(DBGMASK_LOCKDOWND, "lockdownd_send(): made the query, sending it along\n"); | 328 | log_dbg_msg(DBGMASK_LOCKDOWND, "%s: made the query, sending it along\n", __func__); |
| 323 | 329 | ||
| 324 | if (!client->in_SSL) | 330 | if (!client->in_SSL) |
| 325 | ret = usbmuxd_send(client->sfd, real_query, ntohl(length) + sizeof(length), (uint32_t*)&bytes); | 331 | ret = usbmuxd_send(client->sfd, real_query, ntohl(length) + sizeof(length), (uint32_t*)&bytes); |
| @@ -327,16 +333,16 @@ iphone_error_t lockdownd_send(lockdownd_client_t client, plist_t plist) | |||
| 327 | ssize_t res = gnutls_record_send(*client->ssl_session, real_query, ntohl(length) + sizeof(length)); | 333 | ssize_t res = gnutls_record_send(*client->ssl_session, real_query, ntohl(length) + sizeof(length)); |
| 328 | if (res < 0) { | 334 | if (res < 0) { |
| 329 | log_dbg_msg(DBGMASK_LOCKDOWND, "gnutls_record_send: Error occured: %s\n", gnutls_strerror(res)); | 335 | log_dbg_msg(DBGMASK_LOCKDOWND, "gnutls_record_send: Error occured: %s\n", gnutls_strerror(res)); |
| 330 | ret = IPHONE_E_SSL_ERROR; | 336 | ret = LOCKDOWN_E_SSL_ERROR; |
| 331 | } else { | 337 | } else { |
| 332 | bytes = res; | 338 | bytes = res; |
| 333 | ret = IPHONE_E_SUCCESS; | 339 | ret = LOCKDOWN_E_SUCCESS; |
| 334 | } | 340 | } |
| 335 | } | 341 | } |
| 336 | if (ret == IPHONE_E_SUCCESS) { | 342 | if (ret == LOCKDOWN_E_SUCCESS) { |
| 337 | log_dbg_msg(DBGMASK_LOCKDOWND, "lockdownd_send(): sent it!\n"); | 343 | log_dbg_msg(DBGMASK_LOCKDOWND, "%s: sent it!\n", __func__); |
| 338 | } else { | 344 | } else { |
| 339 | log_dbg_msg(DBGMASK_LOCKDOWND, "lockdownd_send(): sending failed!\n"); | 345 | log_dbg_msg(DBGMASK_LOCKDOWND, "%s: sending failed!\n", __func__); |
| 340 | } | 346 | } |
| 341 | free(real_query); | 347 | free(real_query); |
| 342 | 348 | ||
| @@ -347,20 +353,20 @@ iphone_error_t lockdownd_send(lockdownd_client_t client, plist_t plist) | |||
| 347 | * | 353 | * |
| 348 | * @param client The lockdownd client | 354 | * @param client The lockdownd client |
| 349 | * | 355 | * |
| 350 | * @return an error code (IPHONE_E_SUCCESS on success) | 356 | * @return an error code (LOCKDOWN_E_SUCCESS on success) |
| 351 | */ | 357 | */ |
| 352 | iphone_error_t lockdownd_query_type(lockdownd_client_t client) | 358 | lockdownd_error_t lockdownd_query_type(lockdownd_client_t client) |
| 353 | { | 359 | { |
| 354 | if (!client) | 360 | if (!client) |
| 355 | return IPHONE_E_INVALID_ARG; | 361 | return LOCKDOWN_E_INVALID_ARG; |
| 356 | 362 | ||
| 357 | iphone_error_t ret = IPHONE_E_UNKNOWN_ERROR; | 363 | lockdownd_error_t ret = LOCKDOWN_E_UNKNOWN_ERROR; |
| 358 | 364 | ||
| 359 | plist_t dict = plist_new_dict(); | 365 | plist_t dict = plist_new_dict(); |
| 360 | plist_add_sub_key_el(dict, "Request"); | 366 | plist_add_sub_key_el(dict, "Request"); |
| 361 | plist_add_sub_string_el(dict, "QueryType"); | 367 | plist_add_sub_string_el(dict, "QueryType"); |
| 362 | 368 | ||
| 363 | log_dbg_msg(DBGMASK_LOCKDOWND, "lockdownd_query_type() called\n"); | 369 | log_dbg_msg(DBGMASK_LOCKDOWND, "%s: called\n", __func__); |
| 364 | ret = lockdownd_send(client, dict); | 370 | ret = lockdownd_send(client, dict); |
| 365 | 371 | ||
| 366 | plist_free(dict); | 372 | plist_free(dict); |
| @@ -368,13 +374,13 @@ iphone_error_t lockdownd_query_type(lockdownd_client_t client) | |||
| 368 | 374 | ||
| 369 | ret = lockdownd_recv(client, &dict); | 375 | ret = lockdownd_recv(client, &dict); |
| 370 | 376 | ||
| 371 | if (IPHONE_E_SUCCESS != ret) | 377 | if (LOCKDOWN_E_SUCCESS != ret) |
| 372 | return ret; | 378 | return ret; |
| 373 | 379 | ||
| 374 | ret = IPHONE_E_UNKNOWN_ERROR; | 380 | ret = LOCKDOWN_E_UNKNOWN_ERROR; |
| 375 | if (lockdown_check_result(dict, "QueryType") == RESULT_SUCCESS) { | 381 | if (lockdown_check_result(dict, "QueryType") == RESULT_SUCCESS) { |
| 376 | log_dbg_msg(DBGMASK_LOCKDOWND, "lockdownd_query_type(): success\n"); | 382 | log_dbg_msg(DBGMASK_LOCKDOWND, "%s: success\n", __func__); |
| 377 | ret = IPHONE_E_SUCCESS; | 383 | ret = LOCKDOWN_E_SUCCESS; |
| 378 | } | 384 | } |
| 379 | plist_free(dict); | 385 | plist_free(dict); |
| 380 | dict = NULL; | 386 | dict = NULL; |
| @@ -389,15 +395,15 @@ iphone_error_t lockdownd_query_type(lockdownd_client_t client) | |||
| 389 | * @param key the key name to request or NULL to query for all keys | 395 | * @param key the key name to request or NULL to query for all keys |
| 390 | * @param value a plist node representing the result value node | 396 | * @param value a plist node representing the result value node |
| 391 | * | 397 | * |
| 392 | * @return an error code (IPHONE_E_SUCCESS on success) | 398 | * @return an error code (LOCKDOWN_E_SUCCESS on success) |
| 393 | */ | 399 | */ |
| 394 | iphone_error_t lockdownd_get_value(lockdownd_client_t client, const char *domain, const char *key, plist_t *value) | 400 | lockdownd_error_t lockdownd_get_value(lockdownd_client_t client, const char *domain, const char *key, plist_t *value) |
| 395 | { | 401 | { |
| 396 | if (!client) | 402 | if (!client) |
| 397 | return IPHONE_E_INVALID_ARG; | 403 | return LOCKDOWN_E_INVALID_ARG; |
| 398 | 404 | ||
| 399 | plist_t dict = NULL; | 405 | plist_t dict = NULL; |
| 400 | iphone_error_t ret = IPHONE_E_UNKNOWN_ERROR; | 406 | lockdownd_error_t ret = LOCKDOWN_E_UNKNOWN_ERROR; |
| 401 | 407 | ||
| 402 | /* setup request plist */ | 408 | /* setup request plist */ |
| 403 | dict = plist_new_dict(); | 409 | dict = plist_new_dict(); |
| @@ -418,19 +424,19 @@ iphone_error_t lockdownd_get_value(lockdownd_client_t client, const char *domain | |||
| 418 | plist_free(dict); | 424 | plist_free(dict); |
| 419 | dict = NULL; | 425 | dict = NULL; |
| 420 | 426 | ||
| 421 | if (ret != IPHONE_E_SUCCESS) | 427 | if (ret != LOCKDOWN_E_SUCCESS) |
| 422 | return ret; | 428 | return ret; |
| 423 | 429 | ||
| 424 | /* Now get device's answer */ | 430 | /* Now get device's answer */ |
| 425 | ret = lockdownd_recv(client, &dict); | 431 | ret = lockdownd_recv(client, &dict); |
| 426 | if (ret != IPHONE_E_SUCCESS) | 432 | if (ret != LOCKDOWN_E_SUCCESS) |
| 427 | return ret; | 433 | return ret; |
| 428 | 434 | ||
| 429 | if (lockdown_check_result(dict, "GetValue") == RESULT_SUCCESS) { | 435 | if (lockdown_check_result(dict, "GetValue") == RESULT_SUCCESS) { |
| 430 | log_dbg_msg(DBGMASK_LOCKDOWND, "%s: success\n", __func__); | 436 | log_dbg_msg(DBGMASK_LOCKDOWND, "%s: success\n", __func__); |
| 431 | ret = IPHONE_E_SUCCESS; | 437 | ret = LOCKDOWN_E_SUCCESS; |
| 432 | } | 438 | } |
| 433 | if (ret != IPHONE_E_SUCCESS) { | 439 | if (ret != LOCKDOWN_E_SUCCESS) { |
| 434 | plist_free(dict); | 440 | plist_free(dict); |
| 435 | return ret; | 441 | return ret; |
| 436 | } | 442 | } |
| @@ -445,7 +451,7 @@ iphone_error_t lockdownd_get_value(lockdownd_client_t client, const char *domain | |||
| 445 | plist_get_key_val(value_key_node, &result_key); | 451 | plist_get_key_val(value_key_node, &result_key); |
| 446 | 452 | ||
| 447 | if (!strcmp(result_key, "Value")) { | 453 | if (!strcmp(result_key, "Value")) { |
| 448 | log_dbg_msg(DBGMASK_LOCKDOWND, "lockdownd_get_value(): has a value\n"); | 454 | log_dbg_msg(DBGMASK_LOCKDOWND, "%s: has a value\n", __func__); |
| 449 | *value = plist_copy(value_value_node); | 455 | *value = plist_copy(value_value_node); |
| 450 | } | 456 | } |
| 451 | free(result_key); | 457 | free(result_key); |
| @@ -462,15 +468,15 @@ iphone_error_t lockdownd_get_value(lockdownd_client_t client, const char *domain | |||
| 462 | * @param key the key name to set the value or NULL to set a value dict plist | 468 | * @param key the key name to set the value or NULL to set a value dict plist |
| 463 | * @param value a plist node of any node type representing the value to set | 469 | * @param value a plist node of any node type representing the value to set |
| 464 | * | 470 | * |
| 465 | * @return an error code (IPHONE_E_SUCCESS on success) | 471 | * @return an error code (LOCKDOWN_E_SUCCESS on success) |
| 466 | */ | 472 | */ |
| 467 | iphone_error_t lockdownd_set_value(lockdownd_client_t client, const char *domain, const char *key, plist_t value) | 473 | lockdownd_error_t lockdownd_set_value(lockdownd_client_t client, const char *domain, const char *key, plist_t value) |
| 468 | { | 474 | { |
| 469 | if (!client || !value) | 475 | if (!client || !value) |
| 470 | return IPHONE_E_INVALID_ARG; | 476 | return LOCKDOWN_E_INVALID_ARG; |
| 471 | 477 | ||
| 472 | plist_t dict = NULL; | 478 | plist_t dict = NULL; |
| 473 | iphone_error_t ret = IPHONE_E_UNKNOWN_ERROR; | 479 | lockdownd_error_t ret = LOCKDOWN_E_UNKNOWN_ERROR; |
| 474 | 480 | ||
| 475 | /* setup request plist */ | 481 | /* setup request plist */ |
| 476 | dict = plist_new_dict(); | 482 | dict = plist_new_dict(); |
| @@ -494,20 +500,20 @@ iphone_error_t lockdownd_set_value(lockdownd_client_t client, const char *domain | |||
| 494 | plist_free(dict); | 500 | plist_free(dict); |
| 495 | dict = NULL; | 501 | dict = NULL; |
| 496 | 502 | ||
| 497 | if (ret != IPHONE_E_SUCCESS) | 503 | if (ret != LOCKDOWN_E_SUCCESS) |
| 498 | return ret; | 504 | return ret; |
| 499 | 505 | ||
| 500 | /* Now get device's answer */ | 506 | /* Now get device's answer */ |
| 501 | ret = lockdownd_recv(client, &dict); | 507 | ret = lockdownd_recv(client, &dict); |
| 502 | if (ret != IPHONE_E_SUCCESS) | 508 | if (ret != LOCKDOWN_E_SUCCESS) |
| 503 | return ret; | 509 | return ret; |
| 504 | 510 | ||
| 505 | if (lockdown_check_result(dict, "SetValue") == RESULT_SUCCESS) { | 511 | if (lockdown_check_result(dict, "SetValue") == RESULT_SUCCESS) { |
| 506 | log_dbg_msg(DBGMASK_LOCKDOWND, "%s: success\n", __func__); | 512 | log_dbg_msg(DBGMASK_LOCKDOWND, "%s: success\n", __func__); |
| 507 | ret = IPHONE_E_SUCCESS; | 513 | ret = LOCKDOWN_E_SUCCESS; |
| 508 | } | 514 | } |
| 509 | 515 | ||
| 510 | if (ret != IPHONE_E_SUCCESS) { | 516 | if (ret != LOCKDOWN_E_SUCCESS) { |
| 511 | plist_free(dict); | 517 | plist_free(dict); |
| 512 | return ret; | 518 | return ret; |
| 513 | } | 519 | } |
| @@ -524,15 +530,15 @@ iphone_error_t lockdownd_set_value(lockdownd_client_t client, const char *domain | |||
| 524 | * @param domain the domain to query on or NULL for global domain | 530 | * @param domain the domain to query on or NULL for global domain |
| 525 | * @param key the key name to remove or NULL remove all keys for the current domain | 531 | * @param key the key name to remove or NULL remove all keys for the current domain |
| 526 | * | 532 | * |
| 527 | * @return an error code (IPHONE_E_SUCCESS on success) | 533 | * @return an error code (LOCKDOWN_E_SUCCESS on success) |
| 528 | */ | 534 | */ |
| 529 | iphone_error_t lockdownd_remove_value(lockdownd_client_t client, const char *domain, const char *key) | 535 | lockdownd_error_t lockdownd_remove_value(lockdownd_client_t client, const char *domain, const char *key) |
| 530 | { | 536 | { |
| 531 | if (!client) | 537 | if (!client) |
| 532 | return IPHONE_E_INVALID_ARG; | 538 | return LOCKDOWN_E_INVALID_ARG; |
| 533 | 539 | ||
| 534 | plist_t dict = NULL; | 540 | plist_t dict = NULL; |
| 535 | iphone_error_t ret = IPHONE_E_UNKNOWN_ERROR; | 541 | lockdownd_error_t ret = LOCKDOWN_E_UNKNOWN_ERROR; |
| 536 | 542 | ||
| 537 | /* setup request plist */ | 543 | /* setup request plist */ |
| 538 | dict = plist_new_dict(); | 544 | dict = plist_new_dict(); |
| @@ -553,20 +559,20 @@ iphone_error_t lockdownd_remove_value(lockdownd_client_t client, const char *dom | |||
| 553 | plist_free(dict); | 559 | plist_free(dict); |
| 554 | dict = NULL; | 560 | dict = NULL; |
| 555 | 561 | ||
| 556 | if (ret != IPHONE_E_SUCCESS) | 562 | if (ret != LOCKDOWN_E_SUCCESS) |
| 557 | return ret; | 563 | return ret; |
| 558 | 564 | ||
| 559 | /* Now get device's answer */ | 565 | /* Now get device's answer */ |
| 560 | ret = lockdownd_recv(client, &dict); | 566 | ret = lockdownd_recv(client, &dict); |
| 561 | if (ret != IPHONE_E_SUCCESS) | 567 | if (ret != LOCKDOWN_E_SUCCESS) |
| 562 | return ret; | 568 | return ret; |
| 563 | 569 | ||
| 564 | if (lockdown_check_result(dict, "RemoveValue") == RESULT_SUCCESS) { | 570 | if (lockdown_check_result(dict, "RemoveValue") == RESULT_SUCCESS) { |
| 565 | log_dbg_msg(DBGMASK_LOCKDOWND, "%s: success\n", __func__); | 571 | log_dbg_msg(DBGMASK_LOCKDOWND, "%s: success\n", __func__); |
| 566 | ret = IPHONE_E_SUCCESS; | 572 | ret = LOCKDOWN_E_SUCCESS; |
| 567 | } | 573 | } |
| 568 | 574 | ||
| 569 | if (ret != IPHONE_E_SUCCESS) { | 575 | if (ret != LOCKDOWN_E_SUCCESS) { |
| 570 | plist_free(dict); | 576 | plist_free(dict); |
| 571 | return ret; | 577 | return ret; |
| 572 | } | 578 | } |
| @@ -577,18 +583,18 @@ iphone_error_t lockdownd_remove_value(lockdownd_client_t client, const char *dom | |||
| 577 | 583 | ||
| 578 | /** Asks for the device's unique id. Part of the lockdownd handshake. | 584 | /** Asks for the device's unique id. Part of the lockdownd handshake. |
| 579 | * | 585 | * |
| 580 | * @return an error code (IPHONE_E_SUCCESS on success) | 586 | * @return an error code (LOCKDOWN_E_SUCCESS on success) |
| 581 | */ | 587 | */ |
| 582 | iphone_error_t lockdownd_get_device_uid(lockdownd_client_t client, char **uid) | 588 | lockdownd_error_t lockdownd_get_device_uuid(lockdownd_client_t client, char **uuid) |
| 583 | { | 589 | { |
| 584 | iphone_error_t ret = IPHONE_E_UNKNOWN_ERROR; | 590 | lockdownd_error_t ret = LOCKDOWN_E_UNKNOWN_ERROR; |
| 585 | plist_t value = NULL; | 591 | plist_t value = NULL; |
| 586 | 592 | ||
| 587 | ret = lockdownd_get_value(client, NULL, "UniqueDeviceID", &value); | 593 | ret = lockdownd_get_value(client, NULL, "UniqueDeviceID", &value); |
| 588 | if (ret != IPHONE_E_SUCCESS) { | 594 | if (ret != LOCKDOWN_E_SUCCESS) { |
| 589 | return ret; | 595 | return ret; |
| 590 | } | 596 | } |
| 591 | plist_get_string_val(value, uid); | 597 | plist_get_string_val(value, uuid); |
| 592 | 598 | ||
| 593 | plist_free(value); | 599 | plist_free(value); |
| 594 | value = NULL; | 600 | value = NULL; |
| @@ -597,17 +603,17 @@ iphone_error_t lockdownd_get_device_uid(lockdownd_client_t client, char **uid) | |||
| 597 | 603 | ||
| 598 | /** Askes for the device's public key. Part of the lockdownd handshake. | 604 | /** Askes for the device's public key. Part of the lockdownd handshake. |
| 599 | * | 605 | * |
| 600 | * @return an error code (IPHONE_E_SUCCESS on success) | 606 | * @return an error code (LOCKDOWN_E_SUCCESS on success) |
| 601 | */ | 607 | */ |
| 602 | iphone_error_t lockdownd_get_device_public_key(lockdownd_client_t client, gnutls_datum_t * public_key) | 608 | lockdownd_error_t lockdownd_get_device_public_key(lockdownd_client_t client, gnutls_datum_t * public_key) |
| 603 | { | 609 | { |
| 604 | iphone_error_t ret = IPHONE_E_UNKNOWN_ERROR; | 610 | lockdownd_error_t ret = LOCKDOWN_E_UNKNOWN_ERROR; |
| 605 | plist_t value = NULL; | 611 | plist_t value = NULL; |
| 606 | char *value_value = NULL; | 612 | char *value_value = NULL; |
| 607 | uint64_t size = 0; | 613 | uint64_t size = 0; |
| 608 | 614 | ||
| 609 | ret = lockdownd_get_value(client, NULL, "DevicePublicKey", &value); | 615 | ret = lockdownd_get_value(client, NULL, "DevicePublicKey", &value); |
| 610 | if (ret != IPHONE_E_SUCCESS) { | 616 | if (ret != LOCKDOWN_E_SUCCESS) { |
| 611 | return ret; | 617 | return ret; |
| 612 | } | 618 | } |
| 613 | plist_get_data_val(value, &value_value, &size); | 619 | plist_get_data_val(value, &value_value, &size); |
| @@ -625,15 +631,15 @@ iphone_error_t lockdownd_get_device_public_key(lockdownd_client_t client, gnutls | |||
| 625 | * @param client The pointer to the location of the new lockdownd_client | 631 | * @param client The pointer to the location of the new lockdownd_client |
| 626 | * | 632 | * |
| 627 | * | 633 | * |
| 628 | * @return an error code (IPHONE_E_SUCCESS on success) | 634 | * @return an error code (LOCKDOWN_E_SUCCESS on success) |
| 629 | */ | 635 | */ |
| 630 | iphone_error_t lockdownd_get_device_name(lockdownd_client_t client, char **device_name) | 636 | lockdownd_error_t lockdownd_get_device_name(lockdownd_client_t client, char **device_name) |
| 631 | { | 637 | { |
| 632 | iphone_error_t ret = IPHONE_E_UNKNOWN_ERROR; | 638 | lockdownd_error_t ret = LOCKDOWN_E_UNKNOWN_ERROR; |
| 633 | plist_t value = NULL; | 639 | plist_t value = NULL; |
| 634 | 640 | ||
| 635 | ret = lockdownd_get_value(client, NULL, "DeviceName", &value); | 641 | ret = lockdownd_get_value(client, NULL, "DeviceName", &value); |
| 636 | if (ret != IPHONE_E_SUCCESS) { | 642 | if (ret != LOCKDOWN_E_SUCCESS) { |
| 637 | return ret; | 643 | return ret; |
| 638 | } | 644 | } |
| 639 | plist_get_string_val(value, device_name); | 645 | plist_get_string_val(value, device_name); |
| @@ -649,19 +655,19 @@ iphone_error_t lockdownd_get_device_name(lockdownd_client_t client, char **devic | |||
| 649 | * @param phone The iPhone to create a lockdownd client for | 655 | * @param phone The iPhone to create a lockdownd client for |
| 650 | * @param client The pointer to the location of the new lockdownd_client | 656 | * @param client The pointer to the location of the new lockdownd_client |
| 651 | * | 657 | * |
| 652 | * @return an error code (IPHONE_E_SUCCESS on success) | 658 | * @return an error code (LOCKDOWN_E_SUCCESS on success) |
| 653 | */ | 659 | */ |
| 654 | iphone_error_t lockdownd_new_client(iphone_device_t device, lockdownd_client_t *client) | 660 | lockdownd_error_t lockdownd_client_new(iphone_device_t device, lockdownd_client_t *client) |
| 655 | { | 661 | { |
| 656 | if (!device || !client || (client && *client)) | 662 | if (!device || !client || (client && *client)) |
| 657 | return IPHONE_E_INVALID_ARG; | 663 | return LOCKDOWN_E_INVALID_ARG; |
| 658 | iphone_error_t ret = IPHONE_E_SUCCESS; | 664 | lockdownd_error_t ret = LOCKDOWN_E_SUCCESS; |
| 659 | char *host_id = NULL; | 665 | char *host_id = NULL; |
| 660 | 666 | ||
| 661 | int sfd = usbmuxd_connect(device->handle, 0xf27e); | 667 | int sfd = usbmuxd_connect(device->handle, 0xf27e); |
| 662 | if (sfd < 0) { | 668 | if (sfd < 0) { |
| 663 | log_debug_msg("%s: could not connect to lockdownd (device handle %d)\n", __func__, device->handle); | 669 | log_debug_msg("%s: could not connect to lockdownd (device handle %d)\n", __func__, device->handle); |
| 664 | return IPHONE_E_UNKNOWN_ERROR; | 670 | return LOCKDOWN_E_MUX_ERROR; |
| 665 | } | 671 | } |
| 666 | 672 | ||
| 667 | lockdownd_client_t client_loc = (lockdownd_client_t) malloc(sizeof(struct lockdownd_client_int)); | 673 | lockdownd_client_t client_loc = (lockdownd_client_t) malloc(sizeof(struct lockdownd_client_int)); |
| @@ -669,36 +675,36 @@ iphone_error_t lockdownd_new_client(iphone_device_t device, lockdownd_client_t * | |||
| 669 | client_loc->ssl_session = (gnutls_session_t *) malloc(sizeof(gnutls_session_t)); | 675 | client_loc->ssl_session = (gnutls_session_t *) malloc(sizeof(gnutls_session_t)); |
| 670 | client_loc->in_SSL = 0; | 676 | client_loc->in_SSL = 0; |
| 671 | 677 | ||
| 672 | if (IPHONE_E_SUCCESS != lockdownd_query_type(client_loc)) { | 678 | if (LOCKDOWN_E_SUCCESS != lockdownd_query_type(client_loc)) { |
| 673 | log_debug_msg("QueryType failed in the lockdownd client.\n"); | 679 | log_debug_msg("%s: QueryType failed in the lockdownd client.\n", __func__); |
| 674 | ret = IPHONE_E_NOT_ENOUGH_DATA; | 680 | ret = LOCKDOWN_E_NOT_ENOUGH_DATA; |
| 675 | } | 681 | } |
| 676 | 682 | ||
| 677 | char *uid = NULL; | 683 | char *uuid = NULL; |
| 678 | ret = lockdownd_get_device_uid(client_loc, &uid); | 684 | ret = iphone_device_get_uuid(device, &uuid); |
| 679 | if (IPHONE_E_SUCCESS != ret) { | 685 | if (LOCKDOWN_E_SUCCESS != ret) { |
| 680 | log_debug_msg("Device refused to send uid.\n"); | 686 | log_debug_msg("%s: failed to get device uuid.\n", __func__); |
| 681 | } | 687 | } |
| 682 | log_debug_msg("Device uid: %s\n", uid); | 688 | log_debug_msg("%s: device uuid: %s\n", __func__, uuid); |
| 683 | 689 | ||
| 684 | host_id = get_host_id(); | 690 | userpref_get_host_id(&host_id); |
| 685 | if (IPHONE_E_SUCCESS == ret && !host_id) { | 691 | if (LOCKDOWN_E_SUCCESS == ret && !host_id) { |
| 686 | ret = IPHONE_E_INVALID_CONF; | 692 | ret = LOCKDOWN_E_INVALID_CONF; |
| 687 | } | 693 | } |
| 688 | 694 | ||
| 689 | if (IPHONE_E_SUCCESS == ret && !is_device_known(uid)) | 695 | if (LOCKDOWN_E_SUCCESS == ret && !userpref_has_device_public_key(uuid)) |
| 690 | ret = lockdownd_pair(client_loc, uid, host_id); | 696 | ret = lockdownd_pair(client_loc, uuid, host_id); |
| 691 | 697 | ||
| 692 | if (uid) { | 698 | if (uuid) { |
| 693 | free(uid); | 699 | free(uuid); |
| 694 | uid = NULL; | 700 | uuid = NULL; |
| 695 | } | 701 | } |
| 696 | 702 | ||
| 697 | if (IPHONE_E_SUCCESS == ret) { | 703 | if (LOCKDOWN_E_SUCCESS == ret) { |
| 698 | ret = lockdownd_start_ssl_session(client_loc, host_id); | 704 | ret = lockdownd_start_ssl_session(client_loc, host_id); |
| 699 | if (IPHONE_E_SUCCESS != ret) { | 705 | if (LOCKDOWN_E_SUCCESS != ret) { |
| 700 | ret = IPHONE_E_SSL_ERROR; | 706 | ret = LOCKDOWN_E_SSL_ERROR; |
| 701 | log_debug_msg("SSL Session opening failed.\n"); | 707 | log_debug_msg("%s: SSL Session opening failed.\n", __func__); |
| 702 | } | 708 | } |
| 703 | 709 | ||
| 704 | if (host_id) { | 710 | if (host_id) { |
| @@ -706,7 +712,7 @@ iphone_error_t lockdownd_new_client(iphone_device_t device, lockdownd_client_t * | |||
| 706 | host_id = NULL; | 712 | host_id = NULL; |
| 707 | } | 713 | } |
| 708 | 714 | ||
| 709 | if (IPHONE_E_SUCCESS == ret) | 715 | if (LOCKDOWN_E_SUCCESS == ret) |
| 710 | *client = client_loc; | 716 | *client = client_loc; |
| 711 | } | 717 | } |
| 712 | 718 | ||
| @@ -716,11 +722,11 @@ iphone_error_t lockdownd_new_client(iphone_device_t device, lockdownd_client_t * | |||
| 716 | /** Generates the appropriate keys and pairs the device. It's part of the | 722 | /** Generates the appropriate keys and pairs the device. It's part of the |
| 717 | * lockdownd handshake. | 723 | * lockdownd handshake. |
| 718 | * | 724 | * |
| 719 | * @return an error code (IPHONE_E_SUCCESS on success) | 725 | * @return an error code (LOCKDOWN_E_SUCCESS on success) |
| 720 | */ | 726 | */ |
| 721 | iphone_error_t lockdownd_pair(lockdownd_client_t client, char *uid, char *host_id) | 727 | lockdownd_error_t lockdownd_pair(lockdownd_client_t client, char *uuid, char *host_id) |
| 722 | { | 728 | { |
| 723 | iphone_error_t ret = IPHONE_E_UNKNOWN_ERROR; | 729 | lockdownd_error_t ret = LOCKDOWN_E_UNKNOWN_ERROR; |
| 724 | plist_t dict = NULL; | 730 | plist_t dict = NULL; |
| 725 | plist_t dict_record = NULL; | 731 | plist_t dict_record = NULL; |
| 726 | 732 | ||
| @@ -730,14 +736,14 @@ iphone_error_t lockdownd_pair(lockdownd_client_t client, char *uid, char *host_i | |||
| 730 | gnutls_datum_t public_key = { NULL, 0 }; | 736 | gnutls_datum_t public_key = { NULL, 0 }; |
| 731 | 737 | ||
| 732 | ret = lockdownd_get_device_public_key(client, &public_key); | 738 | ret = lockdownd_get_device_public_key(client, &public_key); |
| 733 | if (ret != IPHONE_E_SUCCESS) { | 739 | if (ret != LOCKDOWN_E_SUCCESS) { |
| 734 | log_debug_msg("Device refused to send public key.\n"); | 740 | log_debug_msg("%s: device refused to send public key.\n", __func__); |
| 735 | return ret; | 741 | return ret; |
| 736 | } | 742 | } |
| 737 | log_debug_msg("device public key :\n %s.\n", public_key.data); | 743 | log_debug_msg("%s: device public key follows:\n%s\n", __func__, public_key.data); |
| 738 | 744 | ||
| 739 | ret = lockdownd_gen_pair_cert(public_key, &device_cert, &host_cert, &root_cert); | 745 | ret = lockdownd_gen_pair_cert(public_key, &device_cert, &host_cert, &root_cert); |
| 740 | if (ret != IPHONE_E_SUCCESS) { | 746 | if (ret != LOCKDOWN_E_SUCCESS) { |
| 741 | free(public_key.data); | 747 | free(public_key.data); |
| 742 | return ret; | 748 | return ret; |
| 743 | } | 749 | } |
| @@ -763,29 +769,28 @@ iphone_error_t lockdownd_pair(lockdownd_client_t client, char *uid, char *host_i | |||
| 763 | plist_free(dict); | 769 | plist_free(dict); |
| 764 | dict = NULL; | 770 | dict = NULL; |
| 765 | 771 | ||
| 766 | if (ret != IPHONE_E_SUCCESS) | 772 | if (ret != LOCKDOWN_E_SUCCESS) |
| 767 | return ret; | 773 | return ret; |
| 768 | 774 | ||
| 769 | /* Now get iPhone's answer */ | 775 | /* Now get iPhone's answer */ |
| 770 | ret = lockdownd_recv(client, &dict); | 776 | ret = lockdownd_recv(client, &dict); |
| 771 | 777 | ||
| 772 | if (ret != IPHONE_E_SUCCESS) | 778 | if (ret != LOCKDOWN_E_SUCCESS) |
| 773 | return ret; | 779 | return ret; |
| 774 | 780 | ||
| 775 | if (lockdown_check_result(dict, "Pair") == RESULT_SUCCESS) { | 781 | if (lockdown_check_result(dict, "Pair") == RESULT_SUCCESS) { |
| 776 | ret = IPHONE_E_SUCCESS; | 782 | ret = LOCKDOWN_E_SUCCESS; |
| 777 | } | 783 | } |
| 778 | plist_free(dict); | 784 | plist_free(dict); |
| 779 | dict = NULL; | 785 | dict = NULL; |
| 780 | 786 | ||
| 781 | /* store public key in config if pairing succeeded */ | 787 | /* store public key in config if pairing succeeded */ |
| 782 | if (ret == IPHONE_E_SUCCESS) { | 788 | if (ret == LOCKDOWN_E_SUCCESS) { |
| 783 | log_dbg_msg(DBGMASK_LOCKDOWND, "lockdownd_pair: pair success\n"); | 789 | log_dbg_msg(DBGMASK_LOCKDOWND, "%s: pair success\n", __func__); |
| 784 | store_device_public_key(uid, public_key); | 790 | userpref_set_device_public_key(uuid, public_key); |
| 785 | ret = IPHONE_E_SUCCESS; | ||
| 786 | } else { | 791 | } else { |
| 787 | log_dbg_msg(DBGMASK_LOCKDOWND, "lockdownd_pair: pair failure\n"); | 792 | log_dbg_msg(DBGMASK_LOCKDOWND, "%s: pair failure\n", __func__); |
| 788 | ret = IPHONE_E_PAIRING_FAILED; | 793 | ret = LOCKDOWN_E_PAIRING_FAILED; |
| 789 | } | 794 | } |
| 790 | free(public_key.data); | 795 | free(public_key.data); |
| 791 | return ret; | 796 | return ret; |
| @@ -796,20 +801,20 @@ iphone_error_t lockdownd_pair(lockdownd_client_t client, char *uid, char *host_i | |||
| 796 | * | 801 | * |
| 797 | * @param client The lockdown client | 802 | * @param client The lockdown client |
| 798 | * | 803 | * |
| 799 | * @return an error code (IPHONE_E_SUCCESS on success) | 804 | * @return an error code (LOCKDOWN_E_SUCCESS on success) |
| 800 | */ | 805 | */ |
| 801 | iphone_error_t lockdownd_enter_recovery(lockdownd_client_t client) | 806 | lockdownd_error_t lockdownd_enter_recovery(lockdownd_client_t client) |
| 802 | { | 807 | { |
| 803 | if (!client) | 808 | if (!client) |
| 804 | return IPHONE_E_INVALID_ARG; | 809 | return LOCKDOWN_E_INVALID_ARG; |
| 805 | 810 | ||
| 806 | iphone_error_t ret = IPHONE_E_UNKNOWN_ERROR; | 811 | lockdownd_error_t ret = LOCKDOWN_E_UNKNOWN_ERROR; |
| 807 | 812 | ||
| 808 | plist_t dict = plist_new_dict(); | 813 | plist_t dict = plist_new_dict(); |
| 809 | plist_add_sub_key_el(dict, "Request"); | 814 | plist_add_sub_key_el(dict, "Request"); |
| 810 | plist_add_sub_string_el(dict, "EnterRecovery"); | 815 | plist_add_sub_string_el(dict, "EnterRecovery"); |
| 811 | 816 | ||
| 812 | log_dbg_msg(DBGMASK_LOCKDOWND, "%s: Telling device to enter recovery mode\n", __func__); | 817 | log_dbg_msg(DBGMASK_LOCKDOWND, "%s: telling device to enter recovery mode\n", __func__); |
| 813 | 818 | ||
| 814 | ret = lockdownd_send(client, dict); | 819 | ret = lockdownd_send(client, dict); |
| 815 | plist_free(dict); | 820 | plist_free(dict); |
| @@ -819,7 +824,7 @@ iphone_error_t lockdownd_enter_recovery(lockdownd_client_t client) | |||
| 819 | 824 | ||
| 820 | if (lockdown_check_result(dict, "EnterRecovery") == RESULT_SUCCESS) { | 825 | if (lockdown_check_result(dict, "EnterRecovery") == RESULT_SUCCESS) { |
| 821 | log_dbg_msg(DBGMASK_LOCKDOWND, "%s: success\n", __func__); | 826 | log_dbg_msg(DBGMASK_LOCKDOWND, "%s: success\n", __func__); |
| 822 | ret = IPHONE_E_SUCCESS; | 827 | ret = LOCKDOWN_E_SUCCESS; |
| 823 | } | 828 | } |
| 824 | plist_free(dict); | 829 | plist_free(dict); |
| 825 | dict = NULL; | 830 | dict = NULL; |
| @@ -832,35 +837,34 @@ iphone_error_t lockdownd_enter_recovery(lockdownd_client_t client) | |||
| 832 | * | 837 | * |
| 833 | * @param client The lockdown client | 838 | * @param client The lockdown client |
| 834 | * | 839 | * |
| 835 | * @return an error code (IPHONE_E_SUCCESS on success) | 840 | * @return an error code (LOCKDOWN_E_SUCCESS on success) |
| 836 | */ | 841 | */ |
| 837 | iphone_error_t lockdownd_goodbye(lockdownd_client_t client) | 842 | lockdownd_error_t lockdownd_goodbye(lockdownd_client_t client) |
| 838 | { | 843 | { |
| 839 | if (!client) | 844 | if (!client) |
| 840 | return IPHONE_E_INVALID_ARG; | 845 | return LOCKDOWN_E_INVALID_ARG; |
| 841 | 846 | ||
| 842 | iphone_error_t ret = IPHONE_E_UNKNOWN_ERROR; | 847 | lockdownd_error_t ret = LOCKDOWN_E_UNKNOWN_ERROR; |
| 843 | 848 | ||
| 844 | plist_t dict = plist_new_dict(); | 849 | plist_t dict = plist_new_dict(); |
| 845 | plist_add_sub_key_el(dict, "Request"); | 850 | plist_add_sub_key_el(dict, "Request"); |
| 846 | plist_add_sub_string_el(dict, "Goodbye"); | 851 | plist_add_sub_string_el(dict, "Goodbye"); |
| 847 | 852 | ||
| 848 | log_dbg_msg(DBGMASK_LOCKDOWND, "lockdownd_goodbye() called\n"); | 853 | log_dbg_msg(DBGMASK_LOCKDOWND, "%s: called\n", __func__); |
| 849 | 854 | ||
| 850 | ret = lockdownd_send(client, dict); | 855 | ret = lockdownd_send(client, dict); |
| 851 | plist_free(dict); | 856 | plist_free(dict); |
| 852 | dict = NULL; | 857 | dict = NULL; |
| 853 | 858 | ||
| 854 | ret = lockdownd_recv(client, &dict); | 859 | ret = lockdownd_recv(client, &dict); |
| 855 | |||
| 856 | if (!dict) { | 860 | if (!dict) { |
| 857 | log_dbg_msg(DBGMASK_LOCKDOWND, "lockdownd_goodbye(): IPHONE_E_PLIST_ERROR\n"); | 861 | log_dbg_msg(DBGMASK_LOCKDOWND, "%s: did not get goodbye response back\n", __func__); |
| 858 | return IPHONE_E_PLIST_ERROR; | 862 | return LOCKDOWN_E_PLIST_ERROR; |
| 859 | } | 863 | } |
| 860 | 864 | ||
| 861 | if (lockdown_check_result(dict, "Goodbye") == RESULT_SUCCESS) { | 865 | if (lockdown_check_result(dict, "Goodbye") == RESULT_SUCCESS) { |
| 862 | log_dbg_msg(DBGMASK_LOCKDOWND, "lockdownd_goodbye(): success\n"); | 866 | log_dbg_msg(DBGMASK_LOCKDOWND, "%s: success\n", __func__); |
| 863 | ret = IPHONE_E_SUCCESS; | 867 | ret = LOCKDOWN_E_SUCCESS; |
| 864 | } | 868 | } |
| 865 | plist_free(dict); | 869 | plist_free(dict); |
| 866 | dict = NULL; | 870 | dict = NULL; |
| @@ -870,14 +874,15 @@ iphone_error_t lockdownd_goodbye(lockdownd_client_t client) | |||
| 870 | /** Generates the device certificate from the public key as well as the host | 874 | /** Generates the device certificate from the public key as well as the host |
| 871 | * and root certificates. | 875 | * and root certificates. |
| 872 | * | 876 | * |
| 873 | * @return an error code (IPHONE_E_SUCCESS on success) | 877 | * @return an error code (LOCKDOWN_E_SUCCESS on success) |
| 874 | */ | 878 | */ |
| 875 | iphone_error_t lockdownd_gen_pair_cert(gnutls_datum_t public_key, gnutls_datum_t * odevice_cert, | 879 | lockdownd_error_t lockdownd_gen_pair_cert(gnutls_datum_t public_key, gnutls_datum_t * odevice_cert, |
| 876 | gnutls_datum_t * ohost_cert, gnutls_datum_t * oroot_cert) | 880 | gnutls_datum_t * ohost_cert, gnutls_datum_t * oroot_cert) |
| 877 | { | 881 | { |
| 878 | if (!public_key.data || !odevice_cert || !ohost_cert || !oroot_cert) | 882 | if (!public_key.data || !odevice_cert || !ohost_cert || !oroot_cert) |
| 879 | return IPHONE_E_INVALID_ARG; | 883 | return LOCKDOWN_E_INVALID_ARG; |
| 880 | iphone_error_t ret = IPHONE_E_UNKNOWN_ERROR; | 884 | lockdownd_error_t ret = LOCKDOWN_E_UNKNOWN_ERROR; |
| 885 | userpref_error_t uret = USERPREF_E_UNKNOWN_ERROR; | ||
| 881 | 886 | ||
| 882 | gnutls_datum_t modulus = { NULL, 0 }; | 887 | gnutls_datum_t modulus = { NULL, 0 }; |
| 883 | gnutls_datum_t exponent = { NULL, 0 }; | 888 | gnutls_datum_t exponent = { NULL, 0 }; |
| @@ -905,7 +910,7 @@ iphone_error_t lockdownd_gen_pair_cert(gnutls_datum_t public_key, gnutls_datum_t | |||
| 905 | ret1 = asn1_read_value(asn1_pub_key, "modulus", modulus.data, (int*)&modulus.size); | 910 | ret1 = asn1_read_value(asn1_pub_key, "modulus", modulus.data, (int*)&modulus.size); |
| 906 | ret2 = asn1_read_value(asn1_pub_key, "publicExponent", exponent.data, (int*)&exponent.size); | 911 | ret2 = asn1_read_value(asn1_pub_key, "publicExponent", exponent.data, (int*)&exponent.size); |
| 907 | if (ASN1_SUCCESS == ret1 && ASN1_SUCCESS == ret2) | 912 | if (ASN1_SUCCESS == ret1 && ASN1_SUCCESS == ret2) |
| 908 | ret = IPHONE_E_SUCCESS; | 913 | ret = LOCKDOWN_E_SUCCESS; |
| 909 | } | 914 | } |
| 910 | if (asn1_pub_key) | 915 | if (asn1_pub_key) |
| 911 | asn1_delete_structure(&asn1_pub_key); | 916 | asn1_delete_structure(&asn1_pub_key); |
| @@ -915,7 +920,7 @@ iphone_error_t lockdownd_gen_pair_cert(gnutls_datum_t public_key, gnutls_datum_t | |||
| 915 | } | 920 | } |
| 916 | 921 | ||
| 917 | /* now generate certifcates */ | 922 | /* now generate certifcates */ |
| 918 | if (IPHONE_E_SUCCESS == ret && 0 != modulus.size && 0 != exponent.size) { | 923 | if (LOCKDOWN_E_SUCCESS == ret && 0 != modulus.size && 0 != exponent.size) { |
| 919 | 924 | ||
| 920 | gnutls_global_init(); | 925 | gnutls_global_init(); |
| 921 | gnutls_datum_t essentially_null = { (unsigned char*)strdup("abababababababab"), strlen("abababababababab") }; | 926 | gnutls_datum_t essentially_null = { (unsigned char*)strdup("abababababababab"), strlen("abababababababab") }; |
| @@ -935,10 +940,9 @@ iphone_error_t lockdownd_gen_pair_cert(gnutls_datum_t public_key, gnutls_datum_t | |||
| 935 | gnutls_x509_privkey_init(&root_privkey); | 940 | gnutls_x509_privkey_init(&root_privkey); |
| 936 | gnutls_x509_privkey_init(&host_privkey); | 941 | gnutls_x509_privkey_init(&host_privkey); |
| 937 | 942 | ||
| 938 | ret = get_keys_and_certs(root_privkey, root_cert, host_privkey, host_cert); | 943 | uret = userpref_get_keys_and_certs(root_privkey, root_cert, host_privkey, host_cert); |
| 939 | |||
| 940 | if (IPHONE_E_SUCCESS == ret) { | ||
| 941 | 944 | ||
| 945 | if (USERPREF_E_SUCCESS == uret) { | ||
| 942 | /* generate device certificate */ | 946 | /* generate device certificate */ |
| 943 | gnutls_x509_crt_set_key(dev_cert, fake_privkey); | 947 | gnutls_x509_crt_set_key(dev_cert, fake_privkey); |
| 944 | gnutls_x509_crt_set_serial(dev_cert, "\x00", 1); | 948 | gnutls_x509_crt_set_serial(dev_cert, "\x00", 1); |
| @@ -948,7 +952,7 @@ iphone_error_t lockdownd_gen_pair_cert(gnutls_datum_t public_key, gnutls_datum_t | |||
| 948 | gnutls_x509_crt_set_expiration_time(dev_cert, time(NULL) + (60 * 60 * 24 * 365 * 10)); | 952 | gnutls_x509_crt_set_expiration_time(dev_cert, time(NULL) + (60 * 60 * 24 * 365 * 10)); |
| 949 | gnutls_x509_crt_sign(dev_cert, root_cert, root_privkey); | 953 | gnutls_x509_crt_sign(dev_cert, root_cert, root_privkey); |
| 950 | 954 | ||
| 951 | if (IPHONE_E_SUCCESS == ret) { | 955 | if (LOCKDOWN_E_SUCCESS == ret) { |
| 952 | /* if everything went well, export in PEM format */ | 956 | /* if everything went well, export in PEM format */ |
| 953 | gnutls_datum_t dev_pem = { NULL, 0 }; | 957 | gnutls_datum_t dev_pem = { NULL, 0 }; |
| 954 | gnutls_x509_crt_export(dev_cert, GNUTLS_X509_FMT_PEM, NULL, &dev_pem.size); | 958 | gnutls_x509_crt_export(dev_cert, GNUTLS_X509_FMT_PEM, NULL, &dev_pem.size); |
| @@ -958,7 +962,9 @@ iphone_error_t lockdownd_gen_pair_cert(gnutls_datum_t public_key, gnutls_datum_t | |||
| 958 | gnutls_datum_t pem_root_cert = { NULL, 0 }; | 962 | gnutls_datum_t pem_root_cert = { NULL, 0 }; |
| 959 | gnutls_datum_t pem_host_cert = { NULL, 0 }; | 963 | gnutls_datum_t pem_host_cert = { NULL, 0 }; |
| 960 | 964 | ||
| 961 | if ( IPHONE_E_SUCCESS == get_certs_as_pem(&pem_root_cert, &pem_host_cert) ) { | 965 | uret = userpref_get_certs_as_pem(&pem_root_cert, &pem_host_cert); |
| 966 | |||
| 967 | if (USERPREF_E_SUCCESS == uret) { | ||
| 962 | /* copy buffer for output */ | 968 | /* copy buffer for output */ |
| 963 | odevice_cert->data = malloc(dev_pem.size); | 969 | odevice_cert->data = malloc(dev_pem.size); |
| 964 | memcpy(odevice_cert->data, dev_pem.data, dev_pem.size); | 970 | memcpy(odevice_cert->data, dev_pem.data, dev_pem.size); |
| @@ -977,6 +983,19 @@ iphone_error_t lockdownd_gen_pair_cert(gnutls_datum_t public_key, gnutls_datum_t | |||
| 977 | } | 983 | } |
| 978 | } | 984 | } |
| 979 | } | 985 | } |
| 986 | |||
| 987 | switch(uret) { | ||
| 988 | case USERPREF_E_INVALID_ARG: | ||
| 989 | ret = LOCKDOWN_E_INVALID_ARG; | ||
| 990 | break; | ||
| 991 | case USERPREF_E_INVALID_CONF: | ||
| 992 | ret = LOCKDOWN_E_INVALID_CONF; | ||
| 993 | break; | ||
| 994 | case USERPREF_E_SSL_ERROR: | ||
| 995 | ret = LOCKDOWN_E_SSL_ERROR; | ||
| 996 | default: | ||
| 997 | break; | ||
| 998 | } | ||
| 980 | } | 999 | } |
| 981 | } | 1000 | } |
| 982 | 1001 | ||
| @@ -993,14 +1012,14 @@ iphone_error_t lockdownd_gen_pair_cert(gnutls_datum_t public_key, gnutls_datum_t | |||
| 993 | * @param client The lockdownd client | 1012 | * @param client The lockdownd client |
| 994 | * @param HostID The HostID used with this phone | 1013 | * @param HostID The HostID used with this phone |
| 995 | * | 1014 | * |
| 996 | * @return an error code (IPHONE_E_SUCCESS on success) | 1015 | * @return an error code (LOCKDOWN_E_SUCCESS on success) |
| 997 | */ | 1016 | */ |
| 998 | iphone_error_t lockdownd_start_ssl_session(lockdownd_client_t client, const char *HostID) | 1017 | lockdownd_error_t lockdownd_start_ssl_session(lockdownd_client_t client, const char *HostID) |
| 999 | { | 1018 | { |
| 1000 | plist_t dict = NULL; | 1019 | plist_t dict = NULL; |
| 1001 | uint32_t return_me = 0; | 1020 | uint32_t return_me = 0; |
| 1002 | 1021 | ||
| 1003 | iphone_error_t ret = IPHONE_E_UNKNOWN_ERROR; | 1022 | lockdownd_error_t ret = LOCKDOWN_E_UNKNOWN_ERROR; |
| 1004 | client->session_id[0] = '\0'; | 1023 | client->session_id[0] = '\0'; |
| 1005 | 1024 | ||
| 1006 | /* Setup DevicePublicKey request plist */ | 1025 | /* Setup DevicePublicKey request plist */ |
| @@ -1014,13 +1033,13 @@ iphone_error_t lockdownd_start_ssl_session(lockdownd_client_t client, const char | |||
| 1014 | plist_free(dict); | 1033 | plist_free(dict); |
| 1015 | dict = NULL; | 1034 | dict = NULL; |
| 1016 | 1035 | ||
| 1017 | if (ret != IPHONE_E_SUCCESS) | 1036 | if (ret != LOCKDOWN_E_SUCCESS) |
| 1018 | return ret; | 1037 | return ret; |
| 1019 | 1038 | ||
| 1020 | ret = lockdownd_recv(client, &dict); | 1039 | ret = lockdownd_recv(client, &dict); |
| 1021 | 1040 | ||
| 1022 | if (!dict) | 1041 | if (!dict) |
| 1023 | return IPHONE_E_PLIST_ERROR; | 1042 | return LOCKDOWN_E_PLIST_ERROR; |
| 1024 | 1043 | ||
| 1025 | if (lockdown_check_result(dict, "StartSession") == RESULT_FAILURE) { | 1044 | if (lockdown_check_result(dict, "StartSession") == RESULT_FAILURE) { |
| 1026 | plist_t error_node = plist_get_dict_el_from_key(dict, "Error"); | 1045 | plist_t error_node = plist_get_dict_el_from_key(dict, "Error"); |
| @@ -1029,12 +1048,14 @@ iphone_error_t lockdownd_start_ssl_session(lockdownd_client_t client, const char | |||
| 1029 | plist_get_string_val(error_node, &error); | 1048 | plist_get_string_val(error_node, &error); |
| 1030 | 1049 | ||
| 1031 | if (!strcmp(error, "InvalidHostID")) { | 1050 | if (!strcmp(error, "InvalidHostID")) { |
| 1032 | //hostid is unknown. Pair and try again | 1051 | /* hostid is unknown. Pair and try again */ |
| 1033 | char *uid = NULL; | 1052 | char *uuid = NULL; |
| 1034 | char* host_id = get_host_id(); | 1053 | char *host_id = NULL; |
| 1035 | if (IPHONE_E_SUCCESS == lockdownd_get_device_uid(client, &uid) ) { | 1054 | userpref_get_host_id(&host_id); |
| 1036 | if (IPHONE_E_SUCCESS == lockdownd_pair(client, uid, host_id) ) { | 1055 | |
| 1037 | //start session again | 1056 | if (LOCKDOWN_E_SUCCESS == lockdownd_get_device_uuid(client, &uuid) ) { |
| 1057 | if (LOCKDOWN_E_SUCCESS == lockdownd_pair(client, uuid, host_id) ) { | ||
| 1058 | /* start session again */ | ||
| 1038 | plist_free(dict); | 1059 | plist_free(dict); |
| 1039 | dict = plist_new_dict(); | 1060 | dict = plist_new_dict(); |
| 1040 | plist_add_sub_key_el(dict, "HostID"); | 1061 | plist_add_sub_key_el(dict, "HostID"); |
| @@ -1049,20 +1070,20 @@ iphone_error_t lockdownd_start_ssl_session(lockdownd_client_t client, const char | |||
| 1049 | ret = lockdownd_recv(client, &dict); | 1070 | ret = lockdownd_recv(client, &dict); |
| 1050 | } | 1071 | } |
| 1051 | } | 1072 | } |
| 1052 | free(uid); | 1073 | free(uuid); |
| 1053 | free(host_id); | 1074 | free(host_id); |
| 1054 | } | 1075 | } |
| 1055 | free(error); | 1076 | free(error); |
| 1056 | } | 1077 | } |
| 1057 | } | 1078 | } |
| 1058 | 1079 | ||
| 1059 | ret = IPHONE_E_SSL_ERROR; | 1080 | ret = LOCKDOWN_E_SSL_ERROR; |
| 1060 | if (lockdown_check_result(dict, "StartSession") == RESULT_SUCCESS) { | 1081 | if (lockdown_check_result(dict, "StartSession") == RESULT_SUCCESS) { |
| 1061 | // Set up GnuTLS... | 1082 | // Set up GnuTLS... |
| 1062 | //gnutls_anon_client_credentials_t anoncred; | 1083 | //gnutls_anon_client_credentials_t anoncred; |
| 1063 | gnutls_certificate_credentials_t xcred; | 1084 | gnutls_certificate_credentials_t xcred; |
| 1064 | 1085 | ||
| 1065 | log_dbg_msg(DBGMASK_LOCKDOWND, "We started the session OK, now trying GnuTLS\n"); | 1086 | log_dbg_msg(DBGMASK_LOCKDOWND, "%s: started the session OK, now trying GnuTLS\n", __func__); |
| 1066 | errno = 0; | 1087 | errno = 0; |
| 1067 | gnutls_global_init(); | 1088 | gnutls_global_init(); |
| 1068 | //gnutls_anon_allocate_client_credentials(&anoncred); | 1089 | //gnutls_anon_allocate_client_credentials(&anoncred); |
| @@ -1084,30 +1105,29 @@ iphone_error_t lockdownd_start_ssl_session(lockdownd_client_t client, const char | |||
| 1084 | } | 1105 | } |
| 1085 | gnutls_credentials_set(*client->ssl_session, GNUTLS_CRD_CERTIFICATE, xcred); // this part is killing me. | 1106 | gnutls_credentials_set(*client->ssl_session, GNUTLS_CRD_CERTIFICATE, xcred); // this part is killing me. |
| 1086 | 1107 | ||
| 1087 | log_dbg_msg(DBGMASK_LOCKDOWND, "GnuTLS step 1...\n"); | 1108 | log_dbg_msg(DBGMASK_LOCKDOWND, "%s: GnuTLS step 1...\n", __func__); |
| 1088 | gnutls_transport_set_ptr(*client->ssl_session, (gnutls_transport_ptr_t) client); | 1109 | gnutls_transport_set_ptr(*client->ssl_session, (gnutls_transport_ptr_t) client); |
| 1089 | log_dbg_msg(DBGMASK_LOCKDOWND, "GnuTLS step 2...\n"); | 1110 | log_dbg_msg(DBGMASK_LOCKDOWND, "%s: GnuTLS step 2...\n", __func__); |
| 1090 | gnutls_transport_set_push_function(*client->ssl_session, (gnutls_push_func) & lockdownd_secuwrite); | 1111 | gnutls_transport_set_push_function(*client->ssl_session, (gnutls_push_func) & lockdownd_secuwrite); |
| 1091 | log_dbg_msg(DBGMASK_LOCKDOWND, "GnuTLS step 3...\n"); | 1112 | log_dbg_msg(DBGMASK_LOCKDOWND, "%s: GnuTLS step 3...\n", __func__); |
| 1092 | gnutls_transport_set_pull_function(*client->ssl_session, (gnutls_pull_func) & lockdownd_securead); | 1113 | gnutls_transport_set_pull_function(*client->ssl_session, (gnutls_pull_func) & lockdownd_securead); |
| 1093 | log_dbg_msg(DBGMASK_LOCKDOWND, "GnuTLS step 4 -- now handshaking...\n"); | 1114 | log_dbg_msg(DBGMASK_LOCKDOWND, "%s: GnuTLS step 4 -- now handshaking...\n", __func__); |
| 1094 | |||
| 1095 | if (errno) | 1115 | if (errno) |
| 1096 | log_dbg_msg(DBGMASK_LOCKDOWND, "WARN: errno says %s before handshake!\n", strerror(errno)); | 1116 | log_dbg_msg(DBGMASK_LOCKDOWND, "%s: WARN: errno says %s before handshake!\n", __func__, strerror(errno)); |
| 1097 | return_me = gnutls_handshake(*client->ssl_session); | 1117 | return_me = gnutls_handshake(*client->ssl_session); |
| 1098 | log_dbg_msg(DBGMASK_LOCKDOWND, "GnuTLS handshake done...\n"); | 1118 | log_dbg_msg(DBGMASK_LOCKDOWND, "%s: GnuTLS handshake done...\n", __func__); |
| 1099 | 1119 | ||
| 1100 | if (return_me != GNUTLS_E_SUCCESS) { | 1120 | if (return_me != GNUTLS_E_SUCCESS) { |
| 1101 | log_dbg_msg(DBGMASK_LOCKDOWND, "GnuTLS reported something wrong.\n"); | 1121 | log_dbg_msg(DBGMASK_LOCKDOWND, "%s: GnuTLS reported something wrong.\n", __func__); |
| 1102 | gnutls_perror(return_me); | 1122 | gnutls_perror(return_me); |
| 1103 | log_dbg_msg(DBGMASK_LOCKDOWND, "oh.. errno says %s\n", strerror(errno)); | 1123 | log_dbg_msg(DBGMASK_LOCKDOWND, "%s: oh.. errno says %s\n", __func__, strerror(errno)); |
| 1104 | return IPHONE_E_SSL_ERROR; | 1124 | return LOCKDOWN_E_SSL_ERROR; |
| 1105 | } else { | 1125 | } else { |
| 1106 | client->in_SSL = 1; | 1126 | client->in_SSL = 1; |
| 1107 | ret = IPHONE_E_SUCCESS; | 1127 | ret = LOCKDOWN_E_SUCCESS; |
| 1108 | } | 1128 | } |
| 1109 | } | 1129 | } |
| 1110 | //store session id | 1130 | /* store session id */ |
| 1111 | plist_t session_node = plist_find_node_by_key(dict, "SessionID"); | 1131 | plist_t session_node = plist_find_node_by_key(dict, "SessionID"); |
| 1112 | if (session_node) { | 1132 | if (session_node) { |
| 1113 | 1133 | ||
| @@ -1120,23 +1140,23 @@ iphone_error_t lockdownd_start_ssl_session(lockdownd_client_t client, const char | |||
| 1120 | plist_get_string_val(session_node_val, &session_id); | 1140 | plist_get_string_val(session_node_val, &session_id); |
| 1121 | 1141 | ||
| 1122 | if (session_node_val_type == PLIST_STRING && session_id) { | 1142 | if (session_node_val_type == PLIST_STRING && session_id) { |
| 1123 | // we need to store the session ID for StopSession | 1143 | /* we need to store the session ID for StopSession */ |
| 1124 | strcpy(client->session_id, session_id); | 1144 | strcpy(client->session_id, session_id); |
| 1125 | log_dbg_msg(DBGMASK_LOCKDOWND, "SessionID: %s\n", client->session_id); | 1145 | log_dbg_msg(DBGMASK_LOCKDOWND, "%s: SessionID: %s\n", __func__, client->session_id); |
| 1126 | } | 1146 | } |
| 1127 | if (session_id) | 1147 | if (session_id) |
| 1128 | free(session_id); | 1148 | free(session_id); |
| 1129 | } | 1149 | } |
| 1130 | } else | 1150 | } else |
| 1131 | log_dbg_msg(DBGMASK_LOCKDOWND, "Failed to get SessionID!\n"); | 1151 | log_dbg_msg(DBGMASK_LOCKDOWND, "%s: Failed to get SessionID!\n", __func__); |
| 1132 | plist_free(dict); | 1152 | plist_free(dict); |
| 1133 | dict = NULL; | 1153 | dict = NULL; |
| 1134 | 1154 | ||
| 1135 | if (ret == IPHONE_E_SUCCESS) | 1155 | if (ret == LOCKDOWN_E_SUCCESS) |
| 1136 | return ret; | 1156 | return ret; |
| 1137 | 1157 | ||
| 1138 | log_dbg_msg(DBGMASK_LOCKDOWND, "Apparently failed negotiating with lockdownd.\n"); | 1158 | log_dbg_msg(DBGMASK_LOCKDOWND, "%s: Apparently failed negotiating with lockdownd.\n", __func__); |
| 1139 | return IPHONE_E_SSL_ERROR; | 1159 | return LOCKDOWN_E_SSL_ERROR; |
| 1140 | } | 1160 | } |
| 1141 | 1161 | ||
| 1142 | /** gnutls callback for writing data to the iPhone. | 1162 | /** gnutls callback for writing data to the iPhone. |
| @@ -1152,12 +1172,10 @@ ssize_t lockdownd_secuwrite(gnutls_transport_ptr_t transport, char *buffer, size | |||
| 1152 | uint32_t bytes = 0; | 1172 | uint32_t bytes = 0; |
| 1153 | lockdownd_client_t client; | 1173 | lockdownd_client_t client; |
| 1154 | client = (lockdownd_client_t) transport; | 1174 | client = (lockdownd_client_t) transport; |
| 1155 | log_dbg_msg(DBGMASK_LOCKDOWND, "lockdownd_secuwrite() called\n"); | 1175 | log_dbg_msg(DBGMASK_LOCKDOWND, "%s: called\n", __func__); |
| 1156 | log_dbg_msg(DBGMASK_LOCKDOWND, "pre-send\nlength = %zi\n", length); | 1176 | log_dbg_msg(DBGMASK_LOCKDOWND, "%s: pre-send length = %zi\n", __func__, length); |
| 1157 | usbmuxd_send(client->sfd, buffer, length, &bytes); | 1177 | usbmuxd_send(client->sfd, buffer, length, &bytes); |
| 1158 | log_dbg_msg(DBGMASK_LOCKDOWND, "post-send\nsent %i bytes\n", bytes); | 1178 | log_dbg_msg(DBGMASK_LOCKDOWND, "%s: post-send sent %i bytes\n", __func__, bytes); |
| 1159 | |||
| 1160 | dump_debug_buffer("sslpacketwrite.out", buffer, length); | ||
| 1161 | return bytes; | 1179 | return bytes; |
| 1162 | } | 1180 | } |
| 1163 | 1181 | ||
| @@ -1179,19 +1197,17 @@ ssize_t lockdownd_securead(gnutls_transport_ptr_t transport, char *buffer, size_ | |||
| 1179 | client = (lockdownd_client_t) transport; | 1197 | client = (lockdownd_client_t) transport; |
| 1180 | char *recv_buffer; | 1198 | char *recv_buffer; |
| 1181 | 1199 | ||
| 1182 | log_debug_msg("lockdownd_securead() called\nlength = %zi\n", length); | 1200 | log_debug_msg("%s: pre-read client wants %zi bytes\n", __func__, length); |
| 1183 | |||
| 1184 | log_debug_msg("pre-read\nclient wants %zi bytes\n", length); | ||
| 1185 | 1201 | ||
| 1186 | recv_buffer = (char *) malloc(sizeof(char) * this_len); | 1202 | recv_buffer = (char *) malloc(sizeof(char) * this_len); |
| 1187 | 1203 | ||
| 1188 | // repeat until we have the full data or an error occurs. | 1204 | // repeat until we have the full data or an error occurs. |
| 1189 | do { | 1205 | do { |
| 1190 | if ((res = usbmuxd_recv(client->sfd, recv_buffer, this_len, (uint32_t*)&bytes)) != IPHONE_E_SUCCESS) { | 1206 | if ((res = usbmuxd_recv(client->sfd, recv_buffer, this_len, (uint32_t*)&bytes)) != LOCKDOWN_E_SUCCESS) { |
| 1191 | log_debug_msg("%s: ERROR: usbmux_recv returned %d\n", __func__, res); | 1207 | log_debug_msg("%s: ERROR: usbmux_recv returned %d\n", __func__, res); |
| 1192 | return res; | 1208 | return res; |
| 1193 | } | 1209 | } |
| 1194 | log_debug_msg("post-read\nwe got %i bytes\n", bytes); | 1210 | log_debug_msg("%s: post-read we got %i bytes\n", __func__, bytes); |
| 1195 | 1211 | ||
| 1196 | // increase read count | 1212 | // increase read count |
| 1197 | tbytes += bytes; | 1213 | tbytes += bytes; |
| @@ -1205,7 +1221,7 @@ ssize_t lockdownd_securead(gnutls_transport_ptr_t transport, char *buffer, size_ | |||
| 1205 | } | 1221 | } |
| 1206 | 1222 | ||
| 1207 | this_len = length - tbytes; | 1223 | this_len = length - tbytes; |
| 1208 | log_debug_msg("re-read\ntrying to read missing %i bytes\n", this_len); | 1224 | log_debug_msg("%s: re-read trying to read missing %i bytes\n", __func__, this_len); |
| 1209 | } while (tbytes < length); | 1225 | } while (tbytes < length); |
| 1210 | 1226 | ||
| 1211 | if (recv_buffer) { | 1227 | if (recv_buffer) { |
| @@ -1221,22 +1237,23 @@ ssize_t lockdownd_securead(gnutls_transport_ptr_t transport, char *buffer, size_ | |||
| 1221 | * @param service The name of the service to start | 1237 | * @param service The name of the service to start |
| 1222 | * @param port The port number the service was started on | 1238 | * @param port The port number the service was started on |
| 1223 | 1239 | ||
| 1224 | * @return an error code (IPHONE_E_SUCCESS on success) | 1240 | * @return an error code (LOCKDOWN_E_SUCCESS on success) |
| 1225 | */ | 1241 | */ |
| 1226 | iphone_error_t lockdownd_start_service(lockdownd_client_t client, const char *service, int *port) | 1242 | lockdownd_error_t lockdownd_start_service(lockdownd_client_t client, const char *service, int *port) |
| 1227 | { | 1243 | { |
| 1228 | if (!client || !service || !port) | 1244 | if (!client || !service || !port) |
| 1229 | return IPHONE_E_INVALID_ARG; | 1245 | return LOCKDOWN_E_INVALID_ARG; |
| 1230 | 1246 | ||
| 1231 | char *host_id = get_host_id(); | 1247 | char *host_id = NULL; |
| 1248 | userpref_get_host_id(&host_id); | ||
| 1232 | if (!host_id) | 1249 | if (!host_id) |
| 1233 | return IPHONE_E_INVALID_CONF; | 1250 | return LOCKDOWN_E_INVALID_CONF; |
| 1234 | if (!client->in_SSL && !lockdownd_start_ssl_session(client, host_id)) | 1251 | if (!client->in_SSL && !lockdownd_start_ssl_session(client, host_id)) |
| 1235 | return IPHONE_E_SSL_ERROR; | 1252 | return LOCKDOWN_E_SSL_ERROR; |
| 1236 | 1253 | ||
| 1237 | plist_t dict = NULL; | 1254 | plist_t dict = NULL; |
| 1238 | uint32_t port_loc = 0; | 1255 | uint32_t port_loc = 0; |
| 1239 | iphone_error_t ret = IPHONE_E_UNKNOWN_ERROR; | 1256 | lockdownd_error_t ret = LOCKDOWN_E_UNKNOWN_ERROR; |
| 1240 | 1257 | ||
| 1241 | free(host_id); | 1258 | free(host_id); |
| 1242 | host_id = NULL; | 1259 | host_id = NULL; |
| @@ -1252,18 +1269,18 @@ iphone_error_t lockdownd_start_service(lockdownd_client_t client, const char *se | |||
| 1252 | plist_free(dict); | 1269 | plist_free(dict); |
| 1253 | dict = NULL; | 1270 | dict = NULL; |
| 1254 | 1271 | ||
| 1255 | if (IPHONE_E_SUCCESS != ret) | 1272 | if (LOCKDOWN_E_SUCCESS != ret) |
| 1256 | return ret; | 1273 | return ret; |
| 1257 | 1274 | ||
| 1258 | ret = lockdownd_recv(client, &dict); | 1275 | ret = lockdownd_recv(client, &dict); |
| 1259 | 1276 | ||
| 1260 | if (IPHONE_E_SUCCESS != ret) | 1277 | if (LOCKDOWN_E_SUCCESS != ret) |
| 1261 | return ret; | 1278 | return ret; |
| 1262 | 1279 | ||
| 1263 | if (!dict) | 1280 | if (!dict) |
| 1264 | return IPHONE_E_PLIST_ERROR; | 1281 | return LOCKDOWN_E_PLIST_ERROR; |
| 1265 | 1282 | ||
| 1266 | ret = IPHONE_E_UNKNOWN_ERROR; | 1283 | ret = LOCKDOWN_E_UNKNOWN_ERROR; |
| 1267 | if (lockdown_check_result(dict, "StartService") == RESULT_SUCCESS) { | 1284 | if (lockdown_check_result(dict, "StartService") == RESULT_SUCCESS) { |
| 1268 | plist_t port_key_node = plist_find_node_by_key(dict, "Port"); | 1285 | plist_t port_key_node = plist_find_node_by_key(dict, "Port"); |
| 1269 | plist_t port_value_node = plist_get_next_sibling(port_key_node); | 1286 | plist_t port_value_node = plist_get_next_sibling(port_key_node); |
| @@ -1277,17 +1294,17 @@ iphone_error_t lockdownd_start_service(lockdownd_client_t client, const char *se | |||
| 1277 | plist_get_uint_val(port_value_node, &port_value); | 1294 | plist_get_uint_val(port_value_node, &port_value); |
| 1278 | if (port_key && !strcmp(port_key, "Port")) { | 1295 | if (port_key && !strcmp(port_key, "Port")) { |
| 1279 | port_loc = port_value; | 1296 | port_loc = port_value; |
| 1280 | ret = IPHONE_E_SUCCESS; | 1297 | ret = LOCKDOWN_E_SUCCESS; |
| 1281 | } | 1298 | } |
| 1282 | if (port_key) | 1299 | if (port_key) |
| 1283 | free(port_key); | 1300 | free(port_key); |
| 1284 | 1301 | ||
| 1285 | if (port && ret == IPHONE_E_SUCCESS) | 1302 | if (port && ret == LOCKDOWN_E_SUCCESS) |
| 1286 | *port = port_loc; | 1303 | *port = port_loc; |
| 1287 | } | 1304 | } |
| 1288 | } | 1305 | } |
| 1289 | else | 1306 | else |
| 1290 | ret = IPHONE_E_START_SERVICE_FAILED; | 1307 | ret = LOCKDOWN_E_START_SERVICE_FAILED; |
| 1291 | 1308 | ||
| 1292 | plist_free(dict); | 1309 | plist_free(dict); |
| 1293 | dict = NULL; | 1310 | dict = NULL; |
diff --git a/src/lockdown.h b/src/lockdown.h index 185d27a..1e193f6 100644 --- a/src/lockdown.h +++ b/src/lockdown.h | |||
| @@ -24,6 +24,7 @@ | |||
| 24 | 24 | ||
| 25 | #include <gnutls/gnutls.h> | 25 | #include <gnutls/gnutls.h> |
| 26 | #include <string.h> | 26 | #include <string.h> |
| 27 | |||
| 27 | #include "libiphone/lockdown.h" | 28 | #include "libiphone/lockdown.h" |
| 28 | 29 | ||
| 29 | struct lockdownd_client_int { | 30 | struct lockdownd_client_int { |
| @@ -33,13 +34,14 @@ struct lockdownd_client_int { | |||
| 33 | char session_id[40]; | 34 | char session_id[40]; |
| 34 | }; | 35 | }; |
| 35 | 36 | ||
| 36 | iphone_error_t lockdownd_get_device_public_key(lockdownd_client_t client, gnutls_datum_t * public_key); | 37 | lockdownd_error_t lockdownd_get_device_public_key(lockdownd_client_t client, gnutls_datum_t * public_key); |
| 37 | iphone_error_t lockdownd_gen_pair_cert(gnutls_datum_t public_key, gnutls_datum_t * device_cert, | 38 | lockdownd_error_t lockdownd_gen_pair_cert(gnutls_datum_t public_key, gnutls_datum_t * device_cert, |
| 38 | gnutls_datum_t * host_cert, gnutls_datum_t * root_cert); | 39 | gnutls_datum_t * host_cert, gnutls_datum_t * root_cert); |
| 39 | 40 | ||
| 40 | // SSL functions | 41 | /* SSL functions */ |
| 41 | iphone_error_t lockdownd_start_ssl_session(lockdownd_client_t client, const char *HostID); | 42 | lockdownd_error_t lockdownd_start_ssl_session(lockdownd_client_t client, const char *HostID); |
| 42 | ssize_t lockdownd_securead(gnutls_transport_ptr_t transport, char *buffer, size_t length); | 43 | ssize_t lockdownd_securead(gnutls_transport_ptr_t transport, char *buffer, size_t length); |
| 43 | ssize_t lockdownd_secuwrite(gnutls_transport_ptr_t transport, char *buffer, size_t length); | 44 | ssize_t lockdownd_secuwrite(gnutls_transport_ptr_t transport, char *buffer, size_t length); |
| 44 | 45 | ||
| 46 | |||
| 45 | #endif | 47 | #endif |
diff --git a/src/userpref.c b/src/userpref.c index 0e83133..4b6dd98 100644 --- a/src/userpref.c +++ b/src/userpref.c | |||
| @@ -22,6 +22,7 @@ | |||
| 22 | #include <glib.h> | 22 | #include <glib.h> |
| 23 | #include <glib/gprintf.h> | 23 | #include <glib/gprintf.h> |
| 24 | #include <stdio.h> | 24 | #include <stdio.h> |
| 25 | #include <stdint.h> | ||
| 25 | #include <stdlib.h> | 26 | #include <stdlib.h> |
| 26 | #include <string.h> | 27 | #include <string.h> |
| 27 | #include <gnutls/gnutls.h> | 28 | #include <gnutls/gnutls.h> |
| @@ -42,7 +43,7 @@ | |||
| 42 | 43 | ||
| 43 | /** Creates a freedesktop compatible configuration directory for libiphone. | 44 | /** Creates a freedesktop compatible configuration directory for libiphone. |
| 44 | */ | 45 | */ |
| 45 | static void create_config_dir(void) | 46 | static void userpref_create_config_dir(void) |
| 46 | { | 47 | { |
| 47 | gchar *config_dir = g_build_path(G_DIR_SEPARATOR_S, g_get_user_config_dir(), LIBIPHONE_CONF_DIR, NULL); | 48 | gchar *config_dir = g_build_path(G_DIR_SEPARATOR_S, g_get_user_config_dir(), LIBIPHONE_CONF_DIR, NULL); |
| 48 | 49 | ||
| @@ -62,9 +63,10 @@ static int get_rand(int min, int max) | |||
| 62 | * | 63 | * |
| 63 | * @return A null terminated string containing a valid HostID. | 64 | * @return A null terminated string containing a valid HostID. |
| 64 | */ | 65 | */ |
| 65 | static char *lockdownd_generate_hostid() | 66 | static char *userpref_generate_host_id() |
| 66 | { | 67 | { |
| 67 | char *hostid = (char *) malloc(sizeof(char) * 37); // HostID's are just UUID's, and UUID's are 36 characters long | 68 | /* HostID's are just UUID's, and UUID's are 36 characters long */ |
| 69 | char *hostid = (char *) malloc(sizeof(char) * 37); | ||
| 68 | const char *chars = "ABCDEF0123456789"; | 70 | const char *chars = "ABCDEF0123456789"; |
| 69 | srand(time(NULL)); | 71 | srand(time(NULL)); |
| 70 | int i = 0; | 72 | int i = 0; |
| @@ -77,7 +79,8 @@ static char *lockdownd_generate_hostid() | |||
| 77 | hostid[i] = chars[get_rand(0, 16)]; | 79 | hostid[i] = chars[get_rand(0, 16)]; |
| 78 | } | 80 | } |
| 79 | } | 81 | } |
| 80 | hostid[36] = '\0'; // make it a real string | 82 | /* make it a real string */ |
| 83 | hostid[36] = '\0'; | ||
| 81 | return hostid; | 84 | return hostid; |
| 82 | } | 85 | } |
| 83 | 86 | ||
| @@ -85,7 +88,7 @@ static char *lockdownd_generate_hostid() | |||
| 85 | * | 88 | * |
| 86 | * @param host_id A null terminated string containing a valid HostID. | 89 | * @param host_id A null terminated string containing a valid HostID. |
| 87 | */ | 90 | */ |
| 88 | static int write_host_id(char *host_id) | 91 | static int userpref_set_host_id(char *host_id) |
| 89 | { | 92 | { |
| 90 | GKeyFile *key_file; | 93 | GKeyFile *key_file; |
| 91 | gsize length; | 94 | gsize length; |
| @@ -96,13 +99,13 @@ static int write_host_id(char *host_id) | |||
| 96 | return 0; | 99 | return 0; |
| 97 | 100 | ||
| 98 | /* Make sure config directory exists */ | 101 | /* Make sure config directory exists */ |
| 99 | create_config_dir(); | 102 | userpref_create_config_dir(); |
| 100 | 103 | ||
| 101 | /* Now parse file to get the HostID */ | 104 | /* Now parse file to get the HostID */ |
| 102 | key_file = g_key_file_new(); | 105 | key_file = g_key_file_new(); |
| 103 | 106 | ||
| 104 | /* Store in config file */ | 107 | /* Store in config file */ |
| 105 | log_debug_msg("init_config_file(): setting hostID to %s\n", host_id); | 108 | log_debug_msg("%s: setting hostID to %s\n", __func__, host_id); |
| 106 | g_key_file_set_value(key_file, "Global", "HostID", host_id); | 109 | g_key_file_set_value(key_file, "Global", "HostID", host_id); |
| 107 | 110 | ||
| 108 | /* Write config file on disk */ | 111 | /* Write config file on disk */ |
| @@ -125,9 +128,8 @@ static int write_host_id(char *host_id) | |||
| 125 | * | 128 | * |
| 126 | * @return The string containing the HostID or NULL | 129 | * @return The string containing the HostID or NULL |
| 127 | */ | 130 | */ |
| 128 | char *get_host_id(void) | 131 | void userpref_get_host_id(char **host_id) |
| 129 | { | 132 | { |
| 130 | char *host_id = NULL; | ||
| 131 | gchar *config_file; | 133 | gchar *config_file; |
| 132 | GKeyFile *key_file; | 134 | GKeyFile *key_file; |
| 133 | gchar *loc_host_id; | 135 | gchar *loc_host_id; |
| @@ -140,20 +142,19 @@ char *get_host_id(void) | |||
| 140 | if (g_key_file_load_from_file(key_file, config_file, G_KEY_FILE_KEEP_COMMENTS, NULL)) { | 142 | if (g_key_file_load_from_file(key_file, config_file, G_KEY_FILE_KEEP_COMMENTS, NULL)) { |
| 141 | loc_host_id = g_key_file_get_value(key_file, "Global", "HostID", NULL); | 143 | loc_host_id = g_key_file_get_value(key_file, "Global", "HostID", NULL); |
| 142 | if (loc_host_id) | 144 | if (loc_host_id) |
| 143 | host_id = strdup((char *) loc_host_id); | 145 | *host_id = strdup((char *) loc_host_id); |
| 144 | g_free(loc_host_id); | 146 | g_free(loc_host_id); |
| 145 | } | 147 | } |
| 146 | g_key_file_free(key_file); | 148 | g_key_file_free(key_file); |
| 147 | g_free(config_file); | 149 | g_free(config_file); |
| 148 | 150 | ||
| 149 | if (!host_id) { | 151 | if (!host_id) { |
| 150 | //no config, generate host_id | 152 | /* no config, generate host_id */ |
| 151 | host_id = lockdownd_generate_hostid(); | 153 | *host_id = userpref_generate_host_id(); |
| 152 | write_host_id(host_id); | 154 | userpref_set_host_id(*host_id); |
| 153 | } | 155 | } |
| 154 | 156 | ||
| 155 | log_debug_msg("get_host_id(): Using %s as HostID\n", host_id); | 157 | log_debug_msg("%s: Using %s as HostID\n", __func__, *host_id); |
| 156 | return host_id; | ||
| 157 | } | 158 | } |
| 158 | 159 | ||
| 159 | /** Determines whether this iPhone has been connected to this system before. | 160 | /** Determines whether this iPhone has been connected to this system before. |
| @@ -163,13 +164,13 @@ char *get_host_id(void) | |||
| 163 | * @return 1 if the iPhone has been connected previously to this configuration | 164 | * @return 1 if the iPhone has been connected previously to this configuration |
| 164 | * or 0 otherwise. | 165 | * or 0 otherwise. |
| 165 | */ | 166 | */ |
| 166 | int is_device_known(char *uid) | 167 | int userpref_has_device_public_key(char *uuid) |
| 167 | { | 168 | { |
| 168 | int ret = 0; | 169 | int ret = 0; |
| 169 | gchar *config_file; | 170 | gchar *config_file; |
| 170 | 171 | ||
| 171 | /* first get config file */ | 172 | /* first get config file */ |
| 172 | gchar *device_file = g_strconcat(uid, ".pem", NULL); | 173 | gchar *device_file = g_strconcat(uuid, ".pem", NULL); |
| 173 | config_file = g_build_path(G_DIR_SEPARATOR_S, g_get_user_config_dir(), LIBIPHONE_CONF_DIR, device_file, NULL); | 174 | config_file = g_build_path(G_DIR_SEPARATOR_S, g_get_user_config_dir(), LIBIPHONE_CONF_DIR, device_file, NULL); |
| 174 | if (g_file_test(config_file, (G_FILE_TEST_EXISTS | G_FILE_TEST_IS_REGULAR))) | 175 | if (g_file_test(config_file, (G_FILE_TEST_EXISTS | G_FILE_TEST_IS_REGULAR))) |
| 175 | ret = 1; | 176 | ret = 1; |
| @@ -186,17 +187,19 @@ int is_device_known(char *uid) | |||
| 186 | * @return 1 on success and 0 if no public key is given or if it has already | 187 | * @return 1 on success and 0 if no public key is given or if it has already |
| 187 | * been marked as connected previously. | 188 | * been marked as connected previously. |
| 188 | */ | 189 | */ |
| 189 | int store_device_public_key(char *uid, gnutls_datum_t public_key) | 190 | userpref_error_t userpref_set_device_public_key(char *uuid, gnutls_datum_t public_key) |
| 190 | { | 191 | { |
| 191 | 192 | if (NULL == public_key.data) | |
| 192 | if (NULL == public_key.data || is_device_known(uid)) | 193 | return USERPREF_E_INVALID_ARG; |
| 193 | return 0; | 194 | |
| 195 | if (userpref_has_device_public_key(uuid)) | ||
| 196 | return USERPREF_E_SUCCESS; | ||
| 194 | 197 | ||
| 195 | /* ensure config directory exists */ | 198 | /* ensure config directory exists */ |
| 196 | create_config_dir(); | 199 | userpref_create_config_dir(); |
| 197 | 200 | ||
| 198 | /* build file path */ | 201 | /* build file path */ |
| 199 | gchar *device_file = g_strconcat(uid, ".pem", NULL); | 202 | gchar *device_file = g_strconcat(uuid, ".pem", NULL); |
| 200 | gchar *pem = g_build_path(G_DIR_SEPARATOR_S, g_get_user_config_dir(), LIBIPHONE_CONF_DIR, device_file, NULL); | 203 | gchar *pem = g_build_path(G_DIR_SEPARATOR_S, g_get_user_config_dir(), LIBIPHONE_CONF_DIR, device_file, NULL); |
| 201 | 204 | ||
| 202 | /* store file */ | 205 | /* store file */ |
| @@ -205,7 +208,8 @@ int store_device_public_key(char *uid, gnutls_datum_t public_key) | |||
| 205 | fclose(pFile); | 208 | fclose(pFile); |
| 206 | g_free(pem); | 209 | g_free(pem); |
| 207 | g_free(device_file); | 210 | g_free(device_file); |
| 208 | return 1; | 211 | |
| 212 | return USERPREF_E_SUCCESS; | ||
| 209 | } | 213 | } |
| 210 | 214 | ||
| 211 | /** Private function which reads the given file into a gnutls structure. | 215 | /** Private function which reads the given file into a gnutls structure. |
| @@ -215,7 +219,7 @@ int store_device_public_key(char *uid, gnutls_datum_t public_key) | |||
| 215 | * | 219 | * |
| 216 | * @return 1 if the file contents where read successfully and 0 otherwise. | 220 | * @return 1 if the file contents where read successfully and 0 otherwise. |
| 217 | */ | 221 | */ |
| 218 | static int read_file_in_confdir(const char *file, gnutls_datum_t * data) | 222 | static int userpref_get_file_contents(const char *file, gnutls_datum_t * data) |
| 219 | { | 223 | { |
| 220 | gboolean success; | 224 | gboolean success; |
| 221 | gsize size; | 225 | gsize size; |
| @@ -237,17 +241,17 @@ static int read_file_in_confdir(const char *file, gnutls_datum_t * data) | |||
| 237 | return success; | 241 | return success; |
| 238 | } | 242 | } |
| 239 | 243 | ||
| 240 | |||
| 241 | /** Private function which generate private keys and certificates. | 244 | /** Private function which generate private keys and certificates. |
| 242 | * | 245 | * |
| 243 | * @return IPHONE_E_SUCCESS if keys were successfully generated. | 246 | * @return 1 if keys were successfully generated, 0 otherwise |
| 244 | */ | 247 | */ |
| 245 | static iphone_error_t gen_keys_and_cert(void) | 248 | static userpref_error_t userpref_gen_keys_and_cert(void) |
| 246 | { | 249 | { |
| 247 | iphone_error_t ret = IPHONE_E_UNKNOWN_ERROR; | 250 | userpref_error_t ret = USERPREF_E_SSL_ERROR; |
| 251 | |||
| 248 | gnutls_x509_privkey_t root_privkey; | 252 | gnutls_x509_privkey_t root_privkey; |
| 249 | gnutls_x509_privkey_t host_privkey; | ||
| 250 | gnutls_x509_crt_t root_cert; | 253 | gnutls_x509_crt_t root_cert; |
| 254 | gnutls_x509_privkey_t host_privkey; | ||
| 251 | gnutls_x509_crt_t host_cert; | 255 | gnutls_x509_crt_t host_cert; |
| 252 | 256 | ||
| 253 | gnutls_global_deinit(); | 257 | gnutls_global_deinit(); |
| @@ -275,7 +279,6 @@ static iphone_error_t gen_keys_and_cert(void) | |||
| 275 | gnutls_x509_crt_set_expiration_time(root_cert, time(NULL) + (60 * 60 * 24 * 365 * 10)); | 279 | gnutls_x509_crt_set_expiration_time(root_cert, time(NULL) + (60 * 60 * 24 * 365 * 10)); |
| 276 | gnutls_x509_crt_sign(root_cert, root_cert, root_privkey); | 280 | gnutls_x509_crt_sign(root_cert, root_cert, root_privkey); |
| 277 | 281 | ||
| 278 | |||
| 279 | gnutls_x509_crt_set_key(host_cert, host_privkey); | 282 | gnutls_x509_crt_set_key(host_cert, host_privkey); |
| 280 | gnutls_x509_crt_set_serial(host_cert, "\x00", 1); | 283 | gnutls_x509_crt_set_serial(host_cert, "\x00", 1); |
| 281 | gnutls_x509_crt_set_version(host_cert, 3); | 284 | gnutls_x509_crt_set_version(host_cert, 3); |
| @@ -312,14 +315,14 @@ static iphone_error_t gen_keys_and_cert(void) | |||
| 312 | 315 | ||
| 313 | if (NULL != root_cert_pem.data && 0 != root_cert_pem.size && | 316 | if (NULL != root_cert_pem.data && 0 != root_cert_pem.size && |
| 314 | NULL != host_cert_pem.data && 0 != host_cert_pem.size) | 317 | NULL != host_cert_pem.data && 0 != host_cert_pem.size) |
| 315 | ret = IPHONE_E_SUCCESS; | 318 | ret = USERPREF_E_SUCCESS; |
| 316 | 319 | ||
| 317 | /* store values in config file */ | 320 | /* store values in config file */ |
| 318 | init_config_file( &root_key_pem, &host_key_pem, &root_cert_pem, &host_cert_pem); | 321 | userpref_set_keys_and_certs( &root_key_pem, &root_cert_pem, &host_key_pem, &host_cert_pem); |
| 319 | 322 | ||
| 320 | gnutls_free(root_key_pem.data); | 323 | gnutls_free(root_key_pem.data); |
| 321 | gnutls_free(host_key_pem.data); | ||
| 322 | gnutls_free(root_cert_pem.data); | 324 | gnutls_free(root_cert_pem.data); |
| 325 | gnutls_free(host_key_pem.data); | ||
| 323 | gnutls_free(host_cert_pem.data); | 326 | gnutls_free(host_cert_pem.data); |
| 324 | 327 | ||
| 325 | //restore gnutls env | 328 | //restore gnutls env |
| @@ -334,18 +337,18 @@ static iphone_error_t gen_keys_and_cert(void) | |||
| 334 | * @param key_name The filename of the private key to import. | 337 | * @param key_name The filename of the private key to import. |
| 335 | * @param key the gnutls key structure. | 338 | * @param key the gnutls key structure. |
| 336 | * | 339 | * |
| 337 | * @return IPHONE_E_SUCCESS if the key was successfully imported. | 340 | * @return 1 if the key was successfully imported. |
| 338 | */ | 341 | */ |
| 339 | static iphone_error_t import_key(const char* key_name, gnutls_x509_privkey_t key) | 342 | static userpref_error_t userpref_import_key(const char* key_name, gnutls_x509_privkey_t key) |
| 340 | { | 343 | { |
| 341 | iphone_error_t ret = IPHONE_E_INVALID_CONF; | 344 | userpref_error_t ret = USERPREF_E_INVALID_CONF; |
| 342 | gnutls_datum_t pem_key = { NULL, 0 }; | 345 | gnutls_datum_t pem_key = { NULL, 0 }; |
| 343 | 346 | ||
| 344 | if ( read_file_in_confdir(key_name, &pem_key) ) { | 347 | if (userpref_get_file_contents(key_name, &pem_key)) { |
| 345 | if (GNUTLS_E_SUCCESS == gnutls_x509_privkey_import(key, &pem_key, GNUTLS_X509_FMT_PEM)) | 348 | if (GNUTLS_E_SUCCESS == gnutls_x509_privkey_import(key, &pem_key, GNUTLS_X509_FMT_PEM)) |
| 346 | ret = IPHONE_E_SUCCESS; | 349 | ret = USERPREF_E_SUCCESS; |
| 347 | else | 350 | else |
| 348 | ret = IPHONE_E_SSL_ERROR; | 351 | ret = USERPREF_E_SSL_ERROR; |
| 349 | } | 352 | } |
| 350 | gnutls_free(pem_key.data); | 353 | gnutls_free(pem_key.data); |
| 351 | return ret; | 354 | return ret; |
| @@ -358,16 +361,16 @@ static iphone_error_t import_key(const char* key_name, gnutls_x509_privkey_t key | |||
| 358 | * | 361 | * |
| 359 | * @return IPHONE_E_SUCCESS if the certificate was successfully imported. | 362 | * @return IPHONE_E_SUCCESS if the certificate was successfully imported. |
| 360 | */ | 363 | */ |
| 361 | static iphone_error_t import_crt(const char* crt_name, gnutls_x509_crt_t cert) | 364 | static userpref_error_t userpref_import_crt(const char* crt_name, gnutls_x509_crt_t cert) |
| 362 | { | 365 | { |
| 363 | iphone_error_t ret = IPHONE_E_INVALID_CONF; | 366 | userpref_error_t ret = USERPREF_E_INVALID_CONF; |
| 364 | gnutls_datum_t pem_cert = { NULL, 0 }; | 367 | gnutls_datum_t pem_cert = { NULL, 0 }; |
| 365 | 368 | ||
| 366 | if ( read_file_in_confdir(crt_name, &pem_cert) ) { | 369 | if (userpref_get_file_contents(crt_name, &pem_cert)) { |
| 367 | if (GNUTLS_E_SUCCESS == gnutls_x509_crt_import(cert, &pem_cert, GNUTLS_X509_FMT_PEM)) | 370 | if (GNUTLS_E_SUCCESS == gnutls_x509_crt_import(cert, &pem_cert, GNUTLS_X509_FMT_PEM)) |
| 368 | ret = IPHONE_E_SUCCESS; | 371 | ret = USERPREF_E_SUCCESS; |
| 369 | else | 372 | else |
| 370 | ret = IPHONE_E_SSL_ERROR; | 373 | ret = USERPREF_E_SSL_ERROR; |
| 371 | } | 374 | } |
| 372 | gnutls_free(pem_cert.data); | 375 | gnutls_free(pem_cert.data); |
| 373 | return ret; | 376 | return ret; |
| @@ -383,41 +386,41 @@ static iphone_error_t import_crt(const char* crt_name, gnutls_x509_crt_t cert) | |||
| 383 | * @param host_privkey The host private key. | 386 | * @param host_privkey The host private key. |
| 384 | * @param host_crt The host certificate. | 387 | * @param host_crt The host certificate. |
| 385 | * | 388 | * |
| 386 | * @return IPHONE_E_SUCCESS if the keys and certificates were successfully retrieved. | 389 | * @return 1 if the keys and certificates were successfully retrieved, 0 otherwise |
| 387 | */ | 390 | */ |
| 388 | iphone_error_t get_keys_and_certs(gnutls_x509_privkey_t root_privkey, gnutls_x509_crt_t root_crt, gnutls_x509_privkey_t host_privkey, gnutls_x509_crt_t host_crt) | 391 | userpref_error_t userpref_get_keys_and_certs(gnutls_x509_privkey_t root_privkey, gnutls_x509_crt_t root_crt, gnutls_x509_privkey_t host_privkey, gnutls_x509_crt_t host_crt) |
| 389 | { | 392 | { |
| 390 | iphone_error_t ret = IPHONE_E_SUCCESS; | 393 | userpref_error_t ret = USERPREF_E_SUCCESS; |
| 391 | 394 | ||
| 392 | if (ret == IPHONE_E_SUCCESS) | 395 | if (ret == USERPREF_E_SUCCESS) |
| 393 | ret = import_key(LIBIPHONE_ROOT_PRIVKEY, root_privkey); | 396 | ret = userpref_import_key(LIBIPHONE_ROOT_PRIVKEY, root_privkey); |
| 394 | 397 | ||
| 395 | if (ret == IPHONE_E_SUCCESS) | 398 | if (ret == USERPREF_E_SUCCESS) |
| 396 | ret = import_key(LIBIPHONE_HOST_PRIVKEY, host_privkey); | 399 | ret = userpref_import_key(LIBIPHONE_HOST_PRIVKEY, host_privkey); |
| 397 | 400 | ||
| 398 | if (ret == IPHONE_E_SUCCESS) | 401 | if (ret == USERPREF_E_SUCCESS) |
| 399 | ret = import_crt(LIBIPHONE_ROOT_CERTIF, root_crt); | 402 | ret = userpref_import_crt(LIBIPHONE_ROOT_CERTIF, root_crt); |
| 400 | 403 | ||
| 401 | if (ret == IPHONE_E_SUCCESS) | 404 | if (ret == USERPREF_E_SUCCESS) |
| 402 | ret = import_crt(LIBIPHONE_HOST_CERTIF, host_crt); | 405 | ret = userpref_import_crt(LIBIPHONE_HOST_CERTIF, host_crt); |
| 403 | 406 | ||
| 404 | 407 | ||
| 405 | if (IPHONE_E_SUCCESS != ret) { | 408 | if (USERPREF_E_SUCCESS != ret) { |
| 406 | //we had problem reading or importing root cert | 409 | //we had problem reading or importing root cert |
| 407 | //try with a new ones. | 410 | //try with a new ones. |
| 408 | ret = gen_keys_and_cert(); | 411 | ret = userpref_gen_keys_and_cert(); |
| 409 | 412 | ||
| 410 | if (ret == IPHONE_E_SUCCESS) | 413 | if (ret == USERPREF_E_SUCCESS) |
| 411 | ret = import_key(LIBIPHONE_ROOT_PRIVKEY, root_privkey); | 414 | ret = userpref_import_key(LIBIPHONE_ROOT_PRIVKEY, root_privkey); |
| 412 | 415 | ||
| 413 | if (ret == IPHONE_E_SUCCESS) | 416 | if (ret == USERPREF_E_SUCCESS) |
| 414 | ret = import_key(LIBIPHONE_HOST_PRIVKEY, host_privkey); | 417 | ret = userpref_import_key(LIBIPHONE_HOST_PRIVKEY, host_privkey); |
| 415 | 418 | ||
| 416 | if (ret == IPHONE_E_SUCCESS) | 419 | if (ret == USERPREF_E_SUCCESS) |
| 417 | ret = import_crt(LIBIPHONE_ROOT_CERTIF, root_crt); | 420 | ret = userpref_import_crt(LIBIPHONE_ROOT_CERTIF, root_crt); |
| 418 | 421 | ||
| 419 | if (ret == IPHONE_E_SUCCESS) | 422 | if (ret == USERPREF_E_SUCCESS) |
| 420 | ret = import_crt(LIBIPHONE_HOST_CERTIF, host_crt); | 423 | ret = userpref_import_crt(LIBIPHONE_HOST_CERTIF, host_crt); |
| 421 | } | 424 | } |
| 422 | 425 | ||
| 423 | return ret; | 426 | return ret; |
| @@ -428,46 +431,43 @@ iphone_error_t get_keys_and_certs(gnutls_x509_privkey_t root_privkey, gnutls_x50 | |||
| 428 | * @param pem_root_cert The root certificate. | 431 | * @param pem_root_cert The root certificate. |
| 429 | * @param pem_host_cert The host certificate. | 432 | * @param pem_host_cert The host certificate. |
| 430 | * | 433 | * |
| 431 | * @return IPHONE_E_SUCCESS if the certificates were successfully retrieved. | 434 | * @return 1 if the certificates were successfully retrieved, 0 otherwise |
| 432 | */ | 435 | */ |
| 433 | iphone_error_t get_certs_as_pem(gnutls_datum_t *pem_root_cert, gnutls_datum_t *pem_host_cert) | 436 | userpref_error_t userpref_get_certs_as_pem(gnutls_datum_t *pem_root_cert, gnutls_datum_t *pem_host_cert) |
| 434 | { | 437 | { |
| 435 | iphone_error_t ret = IPHONE_E_INVALID_CONF; | 438 | if (!pem_root_cert || !pem_host_cert) |
| 436 | 439 | return USERPREF_E_INVALID_ARG; | |
| 437 | if ( !pem_root_cert || !pem_host_cert) | ||
| 438 | return IPHONE_E_INVALID_ARG; | ||
| 439 | 440 | ||
| 440 | if ( read_file_in_confdir(LIBIPHONE_ROOT_CERTIF, pem_root_cert) && read_file_in_confdir(LIBIPHONE_HOST_CERTIF, pem_host_cert)) | 441 | if (userpref_get_file_contents(LIBIPHONE_ROOT_CERTIF, pem_root_cert) && userpref_get_file_contents(LIBIPHONE_HOST_CERTIF, pem_host_cert)) |
| 441 | ret = IPHONE_E_SUCCESS; | 442 | return USERPREF_E_SUCCESS; |
| 442 | else { | 443 | else { |
| 443 | g_free(pem_root_cert->data); | 444 | g_free(pem_root_cert->data); |
| 444 | g_free(pem_host_cert->data); | 445 | g_free(pem_host_cert->data); |
| 445 | } | 446 | } |
| 446 | return ret; | 447 | return USERPREF_E_INVALID_CONF; |
| 447 | } | 448 | } |
| 449 | |||
| 448 | /** Create and save a configuration file containing the given data. | 450 | /** Create and save a configuration file containing the given data. |
| 449 | * | 451 | * |
| 450 | * @note: All fields must specified and be non-null | 452 | * @note: All fields must specified and be non-null |
| 451 | * | 453 | * |
| 452 | * @param host_id The UUID of the host | ||
| 453 | * @param root_key The root key | 454 | * @param root_key The root key |
| 454 | * @param host_key The host key | ||
| 455 | * @param root_cert The root certificate | 455 | * @param root_cert The root certificate |
| 456 | * @param host_key The host key | ||
| 456 | * @param host_cert The host certificate | 457 | * @param host_cert The host certificate |
| 457 | * | 458 | * |
| 458 | * @return 1 on success and 0 otherwise. | 459 | * @return 1 on success and 0 otherwise. |
| 459 | */ | 460 | */ |
| 460 | int init_config_file( gnutls_datum_t * root_key, gnutls_datum_t * host_key, gnutls_datum_t * root_cert, | 461 | userpref_error_t userpref_set_keys_and_certs(gnutls_datum_t * root_key, gnutls_datum_t * root_cert, gnutls_datum_t * host_key, gnutls_datum_t * host_cert) |
| 461 | gnutls_datum_t * host_cert) | ||
| 462 | { | 462 | { |
| 463 | FILE *pFile; | 463 | FILE *pFile; |
| 464 | gchar *pem; | 464 | gchar *pem; |
| 465 | 465 | ||
| 466 | if (!root_key || !host_key || !root_cert || !host_cert) | 466 | if (!root_key || !host_key || !root_cert || !host_cert) |
| 467 | return 0; | 467 | return USERPREF_E_INVALID_ARG; |
| 468 | 468 | ||
| 469 | /* Make sure config directory exists */ | 469 | /* Make sure config directory exists */ |
| 470 | create_config_dir(); | 470 | userpref_create_config_dir(); |
| 471 | 471 | ||
| 472 | /* Now write keys and certificates to disk */ | 472 | /* Now write keys and certificates to disk */ |
| 473 | pem = g_build_path(G_DIR_SEPARATOR_S, g_get_user_config_dir(), LIBIPHONE_CONF_DIR, LIBIPHONE_ROOT_PRIVKEY, NULL); | 473 | pem = g_build_path(G_DIR_SEPARATOR_S, g_get_user_config_dir(), LIBIPHONE_CONF_DIR, LIBIPHONE_ROOT_PRIVKEY, NULL); |
| @@ -494,5 +494,5 @@ int init_config_file( gnutls_datum_t * root_key, gnutls_datum_t * host_key, gnut | |||
| 494 | fclose(pFile); | 494 | fclose(pFile); |
| 495 | g_free(pem); | 495 | g_free(pem); |
| 496 | 496 | ||
| 497 | return 1; | 497 | return USERPREF_E_SUCCESS; |
| 498 | } | 498 | } |
diff --git a/src/userpref.h b/src/userpref.h index deced04..414c093 100644 --- a/src/userpref.h +++ b/src/userpref.h | |||
| @@ -23,19 +23,21 @@ | |||
| 23 | #define USERPREF_H | 23 | #define USERPREF_H |
| 24 | 24 | ||
| 25 | #include <gnutls/gnutls.h> | 25 | #include <gnutls/gnutls.h> |
| 26 | #include "libiphone/libiphone.h" | ||
| 27 | 26 | ||
| 27 | #define USERPREF_E_SUCCESS 0 | ||
| 28 | #define USERPREF_E_INVALID_ARG -1 | ||
| 29 | #define USERPREF_E_INVALID_CONF -2 | ||
| 30 | #define USERPREF_E_SSL_ERROR -3 | ||
| 28 | 31 | ||
| 29 | iphone_error_t get_keys_and_certs(gnutls_x509_privkey_t root_privkey, gnutls_x509_crt_t root_crt, gnutls_x509_privkey_t host_privkey, gnutls_x509_crt_t host_crt); | 32 | #define USERPREF_E_UNKNOWN_ERROR -256 |
| 30 | 33 | ||
| 31 | iphone_error_t get_certs_as_pem(gnutls_datum_t *pem_root_cert, gnutls_datum_t *pem_host_cert); | 34 | typedef int16_t userpref_error_t; |
| 32 | 35 | ||
| 33 | char *get_host_id(void); | 36 | userpref_error_t userpref_get_keys_and_certs(gnutls_x509_privkey_t root_privkey, gnutls_x509_crt_t root_crt, gnutls_x509_privkey_t host_privkey, gnutls_x509_crt_t host_crt); |
| 37 | userpref_error_t userpref_set_keys_and_certs(gnutls_datum_t * root_key, gnutls_datum_t * root_cert, gnutls_datum_t * host_key, gnutls_datum_t * host_cert); | ||
| 38 | userpref_error_t userpref_get_certs_as_pem(gnutls_datum_t *pem_root_cert, gnutls_datum_t *pem_host_cert); | ||
| 39 | userpref_error_t userpref_set_device_public_key(char *uuid, gnutls_datum_t public_key); | ||
| 40 | int userpref_has_device_public_key(char *uuid); | ||
| 41 | void userpref_get_host_id(char **host_id); | ||
| 34 | 42 | ||
| 35 | int is_device_known(char *uid); | ||
| 36 | |||
| 37 | int store_device_public_key(char *uid, gnutls_datum_t public_key); | ||
| 38 | |||
| 39 | int init_config_file( gnutls_datum_t * root_key, gnutls_datum_t * host_key, gnutls_datum_t * root_cert, | ||
| 40 | gnutls_datum_t * host_cert); | ||
| 41 | #endif | 43 | #endif |
diff --git a/src/utils.c b/src/utils.c index 5b0872d..3c08351 100644 --- a/src/utils.c +++ b/src/utils.c | |||
| @@ -20,7 +20,10 @@ | |||
| 20 | */ | 20 | */ |
| 21 | #include <stdarg.h> | 21 | #include <stdarg.h> |
| 22 | #include <stdio.h> | 22 | #include <stdio.h> |
| 23 | #include <stdint.h> | ||
| 24 | |||
| 23 | #include "utils.h" | 25 | #include "utils.h" |
| 26 | #include "libiphone/libiphone.h" | ||
| 24 | 27 | ||
| 25 | int toto_debug = 0; | 28 | int toto_debug = 0; |
| 26 | uint16_t dbg_mask = 0; | 29 | uint16_t dbg_mask = 0; |
| @@ -31,7 +34,7 @@ uint16_t dbg_mask = 0; | |||
| 31 | * | 34 | * |
| 32 | * @param level Set to 0 for no debugging or 1 for debugging. | 35 | * @param level Set to 0 for no debugging or 1 for debugging. |
| 33 | */ | 36 | */ |
| 34 | void iphone_set_debug(int level) | 37 | void iphone_set_debug_level(int level) |
| 35 | { | 38 | { |
| 36 | toto_debug = level; | 39 | toto_debug = level; |
| 37 | } | 40 | } |
| @@ -116,13 +119,12 @@ inline void log_debug_buffer(const char *data, const int length) | |||
| 116 | inline void dump_debug_buffer(const char *file, const char *data, const int length) | 119 | inline void dump_debug_buffer(const char *file, const char *data, const int length) |
| 117 | { | 120 | { |
| 118 | #ifndef STRIP_DEBUG_CODE | 121 | #ifndef STRIP_DEBUG_CODE |
| 119 | |||
| 120 | /* run the real fprintf */ | 122 | /* run the real fprintf */ |
| 121 | if (toto_debug) { | 123 | if (toto_debug) { |
| 122 | FILE *my_ssl_packet = fopen(file, "w+"); | 124 | FILE *my_ssl_packet = fopen(file, "w+"); |
| 123 | fwrite(data, 1, length, my_ssl_packet); | 125 | fwrite(data, 1, length, my_ssl_packet); |
| 124 | fflush(my_ssl_packet); | 126 | fflush(my_ssl_packet); |
| 125 | fprintf(stderr, "Wrote SSL packet to drive, too.\n"); | 127 | fprintf(stderr, "%s: Wrote SSL packet to drive, too.\n", __func__); |
| 126 | fclose(my_ssl_packet); | 128 | fclose(my_ssl_packet); |
| 127 | } | 129 | } |
| 128 | #endif | 130 | #endif |
diff --git a/src/utils.h b/src/utils.h index 1750b8e..430e812 100644 --- a/src/utils.h +++ b/src/utils.h | |||
| @@ -22,13 +22,10 @@ | |||
| 22 | #ifndef UTILS_H | 22 | #ifndef UTILS_H |
| 23 | #define UTILS_H | 23 | #define UTILS_H |
| 24 | 24 | ||
| 25 | #include "libiphone/libiphone.h" | ||
| 26 | |||
| 27 | |||
| 28 | |||
| 29 | inline void log_debug_msg(const char *format, ...); | 25 | inline void log_debug_msg(const char *format, ...); |
| 30 | inline void log_dbg_msg(uint16_t id, const char *format, ...); | 26 | inline void log_dbg_msg(uint16_t id, const char *format, ...); |
| 31 | 27 | ||
| 32 | inline void log_debug_buffer(const char *data, const int length); | 28 | inline void log_debug_buffer(const char *data, const int length); |
| 33 | inline void dump_debug_buffer(const char *file, const char *data, const int length); | 29 | inline void dump_debug_buffer(const char *file, const char *data, const int length); |
| 30 | |||
| 34 | #endif | 31 | #endif |
