summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/libimobiledevice/lockdown.h18
-rw-r--r--src/lockdown.c84
2 files changed, 96 insertions, 6 deletions
diff --git a/include/libimobiledevice/lockdown.h b/include/libimobiledevice/lockdown.h
index ab6ae88..3a088c1 100644
--- a/include/libimobiledevice/lockdown.h
+++ b/include/libimobiledevice/lockdown.h
@@ -184,7 +184,7 @@ lockdownd_error_t lockdownd_remove_value(lockdownd_client_t client, const char *
184 * @param client The lockdownd client 184 * @param client The lockdownd client
185 * @param identifier The identifier of the service to start 185 * @param identifier The identifier of the service to start
186 * @param descriptor The service descriptor on success or NULL on failure 186 * @param descriptor The service descriptor on success or NULL on failure
187 187 *
188 * @return LOCKDOWN_E_SUCCESS on success, LOCKDOWN_E_INVALID_ARG if a parameter 188 * @return LOCKDOWN_E_SUCCESS on success, LOCKDOWN_E_INVALID_ARG if a parameter
189 * is NULL, LOCKDOWN_E_INVALID_SERVICE if the requested service is not known 189 * is NULL, LOCKDOWN_E_INVALID_SERVICE if the requested service is not known
190 * by the device, LOCKDOWN_E_START_SERVICE_FAILED if the service could not be 190 * by the device, LOCKDOWN_E_START_SERVICE_FAILED if the service could not be
@@ -193,6 +193,22 @@ lockdownd_error_t lockdownd_remove_value(lockdownd_client_t client, const char *
193lockdownd_error_t lockdownd_start_service(lockdownd_client_t client, const char *identifier, lockdownd_service_descriptor_t *service); 193lockdownd_error_t lockdownd_start_service(lockdownd_client_t client, const char *identifier, lockdownd_service_descriptor_t *service);
194 194
195/** 195/**
196 * Requests to start a service and retrieve it's port on success.
197 * Sends the escrow bag from the device's pair record.
198 *
199 * @param client The lockdownd client
200 * @param identifier The identifier of the service to start
201 * @param descriptor The service descriptor on success or NULL on failure
202 *
203 * @return LOCKDOWN_E_SUCCESS on success, LOCKDOWN_E_INVALID_ARG if a parameter
204 * is NULL, LOCKDOWN_E_INVALID_SERVICE if the requested service is not known
205 * by the device, LOCKDOWN_E_START_SERVICE_FAILED if the service could not because
206 * started by the device, LOCKDOWN_E_INVALID_CONF if the host id or escrow bag are
207 * missing from the device record.
208 */
209lockdownd_error_t lockdownd_start_service_with_escrow_bag(lockdownd_client_t client, const char *identifier, lockdownd_service_descriptor_t *service);
210
211/**
196 * Opens a session with lockdownd and switches to SSL mode if device wants it. 212 * Opens a session with lockdownd and switches to SSL mode if device wants it.
197 * 213 *
198 * @param client The lockdownd client 214 * @param client The lockdownd client
diff --git a/src/lockdown.c b/src/lockdown.c
index c6efb16..5c07bcc 100644
--- a/src/lockdown.c
+++ b/src/lockdown.c
@@ -1132,7 +1132,71 @@ lockdownd_error_t lockdownd_start_session(lockdownd_client_t client, const char
1132 return ret; 1132 return ret;
1133} 1133}
1134 1134
1135lockdownd_error_t lockdownd_start_service(lockdownd_client_t client, const char *identifier, lockdownd_service_descriptor_t *service) 1135/**
1136 * Internal function used by lockdownd_do_start_service to create the
1137 * StartService request's plist.
1138 *
1139 * @param client The lockdownd client
1140 * @param identifier The identifier of the service to start
1141 * @param send_escrow_bag Should we send the device's escrow bag with the request
1142 * @param request The request's plist on success, NULL on failure
1143 *
1144 * @return LOCKDOWN_E_SUCCESS on success, LOCKDOWN_E_INVALID_CONF on failure
1145 * to read the escrow bag from the device's record (when used).
1146 */
1147static lockdownd_error_t lockdownd_build_start_service_request(lockdownd_client_t client, const char *identifier, int send_escrow_bag, plist_t *request)
1148{
1149 plist_t dict = plist_new_dict();
1150
1151 /* create the basic request params */
1152 plist_dict_add_label(dict, client->label);
1153 plist_dict_set_item(dict, "Request", plist_new_string("StartService"));
1154 plist_dict_set_item(dict, "Service", plist_new_string(identifier));
1155
1156 /* if needed - get the escrow bag for the device and send it with the request */
1157 if (send_escrow_bag) {
1158 /* get the pairing record */
1159 plist_t pair_record = NULL;
1160 userpref_read_pair_record(client->udid, &pair_record);
1161 if (!pair_record) {
1162 debug_info("ERROR: failed to read pair record for device: %s", client->udid);
1163 plist_free(dict);
1164 return LOCKDOWN_E_INVALID_CONF;
1165 }
1166
1167 /* try to read the escrow bag from the record */
1168 plist_t escrow_bag = plist_dict_get_item(pair_record, USERPREF_ESCROW_BAG_KEY);
1169 if (!escrow_bag || (PLIST_DATA != plist_get_node_type(escrow_bag))) {
1170 debug_info("ERROR: Failed to retrieve the escrow bag from the device's record");
1171 plist_free(dict);
1172 plist_free(pair_record);
1173 return LOCKDOWN_E_INVALID_CONF;
1174 }
1175
1176 debug_info("Adding escrow bag to StartService for %s", identifier);
1177 plist_dict_set_item(dict, USERPREF_ESCROW_BAG_KEY, plist_copy(escrow_bag));
1178 plist_free(pair_record);
1179 }
1180
1181 *request = dict;
1182 return LOCKDOWN_E_SUCCESS;
1183}
1184
1185/**
1186 * Function used internally by lockdownd_start_service and lockdownd_start_service_with_escrow_bag.
1187 *
1188 * @param client The lockdownd client
1189 * @param identifier The identifier of the service to start
1190 * @param send_escrow_bag Should we send the device's escrow bag with the request
1191 * @param descriptor The service descriptor on success or NULL on failure
1192 *
1193 * @return LOCKDOWN_E_SUCCESS on success, LOCKDOWN_E_INVALID_ARG if a parameter
1194 * is NULL, LOCKDOWN_E_INVALID_SERVICE if the requested service is not known
1195 * by the device, LOCKDOWN_E_START_SERVICE_FAILED if the service could not because
1196 * started by the device, LOCKDOWN_E_INVALID_CONF if the host id or escrow bag (when
1197 * used) are missing from the device record.
1198 */
1199static lockdownd_error_t lockdownd_do_start_service(lockdownd_client_t client, const char *identifier, int send_escrow_bag, lockdownd_service_descriptor_t *service)
1136{ 1200{
1137 if (!client || !identifier || !service) 1201 if (!client || !identifier || !service)
1138 return LOCKDOWN_E_INVALID_ARG; 1202 return LOCKDOWN_E_INVALID_ARG;
@@ -1147,10 +1211,10 @@ lockdownd_error_t lockdownd_start_service(lockdownd_client_t client, const char
1147 uint16_t port_loc = 0; 1211 uint16_t port_loc = 0;
1148 lockdownd_error_t ret = LOCKDOWN_E_UNKNOWN_ERROR; 1212 lockdownd_error_t ret = LOCKDOWN_E_UNKNOWN_ERROR;
1149 1213
1150 dict = plist_new_dict(); 1214 /* create StartService request */
1151 plist_dict_add_label(dict, client->label); 1215 ret = lockdownd_build_start_service_request(client, identifier, send_escrow_bag, &dict);
1152 plist_dict_set_item(dict,"Request", plist_new_string("StartService")); 1216 if (LOCKDOWN_E_SUCCESS != ret)
1153 plist_dict_set_item(dict,"Service", plist_new_string(identifier)); 1217 return ret;
1154 1218
1155 /* send to device */ 1219 /* send to device */
1156 ret = lockdownd_send(client, dict); 1220 ret = lockdownd_send(client, dict);
@@ -1217,6 +1281,16 @@ lockdownd_error_t lockdownd_start_service(lockdownd_client_t client, const char
1217 return ret; 1281 return ret;
1218} 1282}
1219 1283
1284lockdownd_error_t lockdownd_start_service(lockdownd_client_t client, const char *identifier, lockdownd_service_descriptor_t *service)
1285{
1286 return lockdownd_do_start_service(client, identifier, 0, service);
1287}
1288
1289lockdownd_error_t lockdownd_start_service_with_escrow_bag(lockdownd_client_t client, const char *identifier, lockdownd_service_descriptor_t *service)
1290{
1291 return lockdownd_do_start_service(client, identifier, 1, service);
1292}
1293
1220lockdownd_error_t lockdownd_activate(lockdownd_client_t client, plist_t activation_record) 1294lockdownd_error_t lockdownd_activate(lockdownd_client_t client, plist_t activation_record)
1221{ 1295{
1222 if (!client) 1296 if (!client)