diff options
Diffstat (limited to 'src/house_arrest.c')
-rw-r--r-- | src/house_arrest.c | 179 |
1 files changed, 46 insertions, 133 deletions
diff --git a/src/house_arrest.c b/src/house_arrest.c index 5baa76e..caad731 100644 --- a/src/house_arrest.c +++ b/src/house_arrest.c | |||
@@ -8,17 +8,20 @@ | |||
8 | * modify it under the terms of the GNU Lesser General Public | 8 | * modify it under the terms of the GNU Lesser General Public |
9 | * License as published by the Free Software Foundation; either | 9 | * License as published by the Free Software Foundation; either |
10 | * version 2.1 of the License, or (at your option) any later version. | 10 | * version 2.1 of the License, or (at your option) any later version. |
11 | * | 11 | * |
12 | * This library is distributed in the hope that it will be useful, | 12 | * This library is distributed in the hope that it will be useful, |
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
15 | * Lesser General Public License for more details. | 15 | * Lesser General Public License for more details. |
16 | * | 16 | * |
17 | * You should have received a copy of the GNU Lesser General Public | 17 | * You should have received a copy of the GNU Lesser General Public |
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 | 21 | ||
22 | #ifdef HAVE_CONFIG_H | ||
23 | #include <config.h> | ||
24 | #endif | ||
22 | #include <string.h> | 25 | #include <string.h> |
23 | #include <stdlib.h> | 26 | #include <stdlib.h> |
24 | #include <unistd.h> | 27 | #include <unistd.h> |
@@ -27,7 +30,7 @@ | |||
27 | #include "house_arrest.h" | 30 | #include "house_arrest.h" |
28 | #include "property_list_service.h" | 31 | #include "property_list_service.h" |
29 | #include "afc.h" | 32 | #include "afc.h" |
30 | #include "debug.h" | 33 | #include "common/debug.h" |
31 | 34 | ||
32 | /** | 35 | /** |
33 | * Convert a property_list_service_error_t value to a house_arrest_error_t | 36 | * Convert a property_list_service_error_t value to a house_arrest_error_t |
@@ -40,39 +43,25 @@ | |||
40 | */ | 43 | */ |
41 | static house_arrest_error_t house_arrest_error(property_list_service_error_t err) | 44 | static house_arrest_error_t house_arrest_error(property_list_service_error_t err) |
42 | { | 45 | { |
43 | switch (err) { | 46 | switch (err) { |
44 | case PROPERTY_LIST_SERVICE_E_SUCCESS: | 47 | case PROPERTY_LIST_SERVICE_E_SUCCESS: |
45 | return HOUSE_ARREST_E_SUCCESS; | 48 | return HOUSE_ARREST_E_SUCCESS; |
46 | case PROPERTY_LIST_SERVICE_E_INVALID_ARG: | 49 | case PROPERTY_LIST_SERVICE_E_INVALID_ARG: |
47 | return HOUSE_ARREST_E_INVALID_ARG; | 50 | return HOUSE_ARREST_E_INVALID_ARG; |
48 | case PROPERTY_LIST_SERVICE_E_PLIST_ERROR: | 51 | case PROPERTY_LIST_SERVICE_E_PLIST_ERROR: |
49 | return HOUSE_ARREST_E_PLIST_ERROR; | 52 | return HOUSE_ARREST_E_PLIST_ERROR; |
50 | case PROPERTY_LIST_SERVICE_E_MUX_ERROR: | 53 | case PROPERTY_LIST_SERVICE_E_MUX_ERROR: |
51 | return HOUSE_ARREST_E_CONN_FAILED; | 54 | return HOUSE_ARREST_E_CONN_FAILED; |
52 | default: | 55 | default: |
53 | break; | 56 | break; |
54 | } | 57 | } |
55 | return HOUSE_ARREST_E_UNKNOWN_ERROR; | 58 | return HOUSE_ARREST_E_UNKNOWN_ERROR; |
56 | } | 59 | } |
57 | 60 | ||
58 | /** | 61 | house_arrest_error_t house_arrest_client_new(idevice_t device, lockdownd_service_descriptor_t service, house_arrest_client_t *client) |
59 | * Connects to the house_arrest service on the specified device. | ||
60 | * | ||
61 | * @param device The device to connect to. | ||
62 | * @param port Destination port (usually given by lockdownd_start_service). | ||
63 | * @param client Pointer that will point to a newly allocated | ||
64 | * housearrest_client_t upon successful return. | ||
65 | * | ||
66 | * @return HOUSE_ARREST_E_SUCCESS on success, HOUSE_ARREST_E_INVALID_ARG when | ||
67 | * client is NULL, or an HOUSE_ARREST_E_* error code otherwise. | ||
68 | */ | ||
69 | house_arrest_error_t house_arrest_client_new(idevice_t device, uint16_t port, house_arrest_client_t *client) | ||
70 | { | 62 | { |
71 | if (!device) | ||
72 | return HOUSE_ARREST_E_INVALID_ARG; | ||
73 | |||
74 | property_list_service_client_t plistclient = NULL; | 63 | property_list_service_client_t plistclient = NULL; |
75 | house_arrest_error_t err = house_arrest_error(property_list_service_client_new(device, port, &plistclient)); | 64 | house_arrest_error_t err = house_arrest_error(property_list_service_client_new(device, service, &plistclient)); |
76 | if (err != HOUSE_ARREST_E_SUCCESS) { | 65 | if (err != HOUSE_ARREST_E_SUCCESS) { |
77 | return err; | 66 | return err; |
78 | } | 67 | } |
@@ -85,27 +74,20 @@ house_arrest_error_t house_arrest_client_new(idevice_t device, uint16_t port, ho | |||
85 | return HOUSE_ARREST_E_SUCCESS; | 74 | return HOUSE_ARREST_E_SUCCESS; |
86 | } | 75 | } |
87 | 76 | ||
88 | /** | 77 | house_arrest_error_t house_arrest_client_start_service(idevice_t device, house_arrest_client_t * client, const char* label) |
89 | * Disconnects an house_arrest client from the device and frees up the | 78 | { |
90 | * house_arrest client data. | 79 | house_arrest_error_t err = HOUSE_ARREST_E_UNKNOWN_ERROR; |
91 | * | 80 | service_client_factory_start_service(device, HOUSE_ARREST_SERVICE_NAME, (void**)client, label, SERVICE_CONSTRUCTOR(house_arrest_client_new), &err); |
92 | * @note After using afc_client_new_from_house_arrest_client(), make sure | 81 | return err; |
93 | * you call afc_client_free() before calling this function to ensure | 82 | } |
94 | * a proper cleanup. Do not call this function if you still need to | 83 | |
95 | * perform AFC operations since it will close the connection. | ||
96 | * | ||
97 | * @param client The house_arrest client to disconnect and free. | ||
98 | * | ||
99 | * @return HOUSE_ARREST_E_SUCCESS on success, HOUSE_ARREST_E_INVALID_ARG when | ||
100 | * client is NULL, or an HOUSE_ARREST_E_* error code otherwise. | ||
101 | */ | ||
102 | house_arrest_error_t house_arrest_client_free(house_arrest_client_t client) | 84 | house_arrest_error_t house_arrest_client_free(house_arrest_client_t client) |
103 | { | 85 | { |
104 | if (!client) | 86 | if (!client) |
105 | return HOUSE_ARREST_E_INVALID_ARG; | 87 | return HOUSE_ARREST_E_INVALID_ARG; |
106 | 88 | ||
107 | house_arrest_error_t err = HOUSE_ARREST_E_SUCCESS; | 89 | house_arrest_error_t err = HOUSE_ARREST_E_SUCCESS; |
108 | if (client->parent && client->parent->connection) { | 90 | if (client->parent && client->parent->parent->connection) { |
109 | house_arrest_error(property_list_service_client_free(client->parent)); | 91 | house_arrest_error(property_list_service_client_free(client->parent)); |
110 | } | 92 | } |
111 | client->parent = NULL; | 93 | client->parent = NULL; |
@@ -114,70 +96,34 @@ house_arrest_error_t house_arrest_client_free(house_arrest_client_t client) | |||
114 | return err; | 96 | return err; |
115 | } | 97 | } |
116 | 98 | ||
117 | /** | ||
118 | * Sends a generic request to the connected house_arrest service. | ||
119 | * | ||
120 | * @param client The house_arrest client to use. | ||
121 | * @param dict The request to send as a plist of type PLIST_DICT. | ||
122 | * | ||
123 | * @note If this function returns HOUSE_ARREST_E_SUCCESS it does not mean | ||
124 | * that the request was successful. To check for success or failure you | ||
125 | * need to call house_arrest_get_result(). | ||
126 | * @see house_arrest_get_result | ||
127 | * | ||
128 | * @return HOUSE_ARREST_E_SUCCESS if the request was successfully sent, | ||
129 | * HOUSE_ARREST_E_INVALID_ARG if client or dict is invalid, | ||
130 | * HOUSE_ARREST_E_PLIST_ERROR if dict is not a plist of type PLIST_DICT, | ||
131 | * HOUSE_ARREST_E_INVALID_MODE if the client is not in the correct mode, | ||
132 | * or HOUSE_ARREST_E_CONN_FAILED if a connection error occured. | ||
133 | */ | ||
134 | house_arrest_error_t house_arrest_send_request(house_arrest_client_t client, plist_t dict) | 99 | house_arrest_error_t house_arrest_send_request(house_arrest_client_t client, plist_t dict) |
135 | { | 100 | { |
136 | if (!client || !client->parent || !dict) | 101 | if (!client || !client->parent || !dict) |
137 | return HOUSE_ARREST_E_INVALID_ARG; | 102 | return HOUSE_ARREST_E_INVALID_ARG; |
138 | if (plist_get_node_type(dict) != PLIST_DICT) | 103 | if (plist_get_node_type(dict) != PLIST_DICT) |
139 | return HOUSE_ARREST_E_PLIST_ERROR; | 104 | return HOUSE_ARREST_E_PLIST_ERROR; |
140 | if (client->mode != HOUSE_ARREST_CLIENT_MODE_NORMAL) | 105 | if (client->mode != HOUSE_ARREST_CLIENT_MODE_NORMAL) |
141 | return HOUSE_ARREST_E_INVALID_MODE; | 106 | return HOUSE_ARREST_E_INVALID_MODE; |
142 | 107 | ||
143 | house_arrest_error_t res = house_arrest_error(property_list_service_send_xml_plist(client->parent, dict)); | 108 | house_arrest_error_t res = house_arrest_error(property_list_service_send_xml_plist(client->parent, dict)); |
144 | if (res != HOUSE_ARREST_E_SUCCESS) { | 109 | if (res != HOUSE_ARREST_E_SUCCESS) { |
145 | debug_info("could not send plist, error %d", res); | 110 | debug_info("could not send plist, error %d", res); |
146 | } | 111 | } |
147 | return res; | 112 | return res; |
148 | } | 113 | } |
149 | 114 | ||
150 | /** | ||
151 | * Send a command to the connected house_arrest service. | ||
152 | * Calls house_arrest_send_request() internally. | ||
153 | * | ||
154 | * @param client The house_arrest client to use. | ||
155 | * @param command The command to send. Currently, only VendContainer and | ||
156 | * VendDocuments are known. | ||
157 | * @param appid The application identifier to pass along with the . | ||
158 | * | ||
159 | * @note If this function returns HOUSE_ARREST_E_SUCCESS it does not mean | ||
160 | * that the command was successful. To check for success or failure you | ||
161 | * need to call house_arrest_get_result(). | ||
162 | * @see house_arrest_get_result | ||
163 | * | ||
164 | * @return HOUSE_ARREST_E_SUCCESS if the command was successfully sent, | ||
165 | * HOUSE_ARREST_E_INVALID_ARG if client, command, or appid is invalid, | ||
166 | * HOUSE_ARREST_E_INVALID_MODE if the client is not in the correct mode, | ||
167 | * or HOUSE_ARREST_E_CONN_FAILED if a connection error occured. | ||
168 | */ | ||
169 | house_arrest_error_t house_arrest_send_command(house_arrest_client_t client, const char *command, const char *appid) | 115 | house_arrest_error_t house_arrest_send_command(house_arrest_client_t client, const char *command, const char *appid) |
170 | { | 116 | { |
171 | if (!client || !client->parent || !command || !appid) | 117 | if (!client || !client->parent || !command || !appid) |
172 | return HOUSE_ARREST_E_INVALID_ARG; | 118 | return HOUSE_ARREST_E_INVALID_ARG; |
173 | if (client->mode != HOUSE_ARREST_CLIENT_MODE_NORMAL) | 119 | if (client->mode != HOUSE_ARREST_CLIENT_MODE_NORMAL) |
174 | return HOUSE_ARREST_E_INVALID_MODE; | 120 | return HOUSE_ARREST_E_INVALID_MODE; |
175 | 121 | ||
176 | house_arrest_error_t res = HOUSE_ARREST_E_UNKNOWN_ERROR; | 122 | house_arrest_error_t res = HOUSE_ARREST_E_UNKNOWN_ERROR; |
177 | 123 | ||
178 | plist_t dict = plist_new_dict(); | 124 | plist_t dict = plist_new_dict(); |
179 | plist_dict_insert_item(dict, "Command", plist_new_string(command)); | 125 | plist_dict_set_item(dict, "Command", plist_new_string(command)); |
180 | plist_dict_insert_item(dict, "Identifier", plist_new_string(appid)); | 126 | plist_dict_set_item(dict, "Identifier", plist_new_string(appid)); |
181 | 127 | ||
182 | res = house_arrest_send_request(client, dict); | 128 | res = house_arrest_send_request(client, dict); |
183 | 129 | ||
@@ -186,63 +132,30 @@ house_arrest_error_t house_arrest_send_command(house_arrest_client_t client, con | |||
186 | return res; | 132 | return res; |
187 | } | 133 | } |
188 | 134 | ||
189 | /** | ||
190 | * Retrieves the result of a previously sent house_arrest_request_* request. | ||
191 | * | ||
192 | * @param client The house_arrest client to use | ||
193 | * @param dict Pointer that will be set to a plist containing the result to | ||
194 | * the last performed operation. It holds a key 'Status' with the value | ||
195 | * 'Complete' on success or a key 'Error' with an error description as | ||
196 | * value. The caller is responsible for freeing the returned plist. | ||
197 | * | ||
198 | * @return HOUSE_ARREST_E_SUCCESS if a result plist was retrieved, | ||
199 | * HOUSE_ARREST_E_INVALID_ARG if client is invalid, | ||
200 | * HOUSE_ARREST_E_INVALID_MODE if the client is not in the correct mode, | ||
201 | * or HOUSE_ARREST_E_CONN_FAILED if a connection error occured. | ||
202 | */ | ||
203 | house_arrest_error_t house_arrest_get_result(house_arrest_client_t client, plist_t *dict) | 135 | house_arrest_error_t house_arrest_get_result(house_arrest_client_t client, plist_t *dict) |
204 | { | 136 | { |
205 | if (!client || !client->parent) | 137 | if (!client || !client->parent) |
206 | return HOUSE_ARREST_E_INVALID_ARG; | 138 | return HOUSE_ARREST_E_INVALID_ARG; |
207 | if (client->mode != HOUSE_ARREST_CLIENT_MODE_NORMAL) | 139 | if (client->mode != HOUSE_ARREST_CLIENT_MODE_NORMAL) |
208 | return HOUSE_ARREST_E_INVALID_MODE; | 140 | return HOUSE_ARREST_E_INVALID_MODE; |
209 | 141 | ||
210 | house_arrest_error_t res = house_arrest_error(property_list_service_receive_plist(client->parent, dict)); | 142 | house_arrest_error_t res = house_arrest_error(property_list_service_receive_plist(client->parent, dict)); |
211 | if (res != HOUSE_ARREST_E_SUCCESS) { | 143 | if (res != HOUSE_ARREST_E_SUCCESS) { |
212 | debug_info("could not get result, error %d", res); | 144 | debug_info("could not get result, error %d", res); |
213 | if (*dict) { | 145 | if (*dict) { |
214 | plist_free(*dict); | 146 | plist_free(*dict); |
215 | *dict = NULL; | 147 | *dict = NULL; |
216 | } | 148 | } |
217 | } | 149 | } |
218 | return res; | 150 | return res; |
219 | } | 151 | } |
220 | 152 | ||
221 | /** | ||
222 | * Creates an AFC client using the given house_arrest client's connection | ||
223 | * allowing file access to a specific application directory requested by | ||
224 | * functions like house_arrest_request_vendor_documents(). | ||
225 | * | ||
226 | * @param client The house_arrest client to use. | ||
227 | * @param afc_client Pointer that will be set to a newly allocated afc_client_t | ||
228 | * upon successful return. | ||
229 | * | ||
230 | * @note After calling this function the house_arrest client will go in an | ||
231 | * AFC mode that will only allow calling house_arrest_client_free(). | ||
232 | * Only call house_arrest_client_free() if all AFC operations have | ||
233 | * completed since it will close the connection. | ||
234 | * | ||
235 | * @return AFC_E_SUCCESS if the afc client was successfully created, | ||
236 | * AFC_E_INVALID_ARG if client is invalid or was already used to create | ||
237 | * an afc client, or an AFC_E_* error code returned by | ||
238 | * afc_client_new_from_connection(). | ||
239 | */ | ||
240 | afc_error_t afc_client_new_from_house_arrest_client(house_arrest_client_t client, afc_client_t *afc_client) | 153 | afc_error_t afc_client_new_from_house_arrest_client(house_arrest_client_t client, afc_client_t *afc_client) |
241 | { | 154 | { |
242 | if (!client || !client->parent || (client->mode == HOUSE_ARREST_CLIENT_MODE_AFC)) { | 155 | if (!client || !client->parent || (client->mode == HOUSE_ARREST_CLIENT_MODE_AFC)) { |
243 | return AFC_E_INVALID_ARG; | 156 | return AFC_E_INVALID_ARG; |
244 | } | 157 | } |
245 | afc_error_t err = afc_client_new_from_connection(client->parent->connection, afc_client); | 158 | afc_error_t err = afc_client_new_with_service_client(client->parent->parent, afc_client); |
246 | if (err == AFC_E_SUCCESS) { | 159 | if (err == AFC_E_SUCCESS) { |
247 | client->mode = HOUSE_ARREST_CLIENT_MODE_AFC; | 160 | client->mode = HOUSE_ARREST_CLIENT_MODE_AFC; |
248 | } | 161 | } |