Hello community,

here is the log from the commit of package libimobiledevice for 
openSUSE:Factory checked in at 2018-06-22 13:13:38
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/libimobiledevice (Old)
 and      /work/SRC/openSUSE:Factory/.libimobiledevice.new (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "libimobiledevice"

Fri Jun 22 13:13:38 2018 rev:37 rq:616171 version:1.2.0+git20180427.26373b3

Changes:
--------
--- /work/SRC/openSUSE:Factory/libimobiledevice/libimobiledevice.changes        
2017-02-08 10:43:07.716861555 +0100
+++ /work/SRC/openSUSE:Factory/.libimobiledevice.new/libimobiledevice.changes   
2018-06-22 13:13:38.366917511 +0200
@@ -1,0 +2,27 @@
+Tue Jun 12 01:28:19 UTC 2018 - i...@marguerite.su
+
+- update version 1.2.0+git20180427.26373b3
+  * Propagate lower level errors to callers instead of returning unknown
+  * Added IDEVICE_DEVICE_PAIRED event constant matching the corresponding
+  * Define htobe16 if not defined
+  * Fix parameter check of instproxy_check_capabilities_match()
+  * Avoid double free with OpenSSL 1.1.0
+  * Don't use ERR_remove_thread_state() with OpenSSL 1.1.0
+  * #ifdef out code which is a no-op with OpenSSL 1.1.0
+  * cython: Fix build error after error constant rename
+  * gnutls: check for interrupted gnutls_handshake()
+  * idevicescreenshot: Detect screenshot image format to determine file 
extension
+  * Add basic mobileactivation service implementation
+  * mobileactivation: Add new functions required for drmHandshake / session 
mode device activation
+  * lockdown: Don't explicitly validate pairing unless we're dealing with an 
older device
+  * mobileactivation: Don't convert activation record if it is already passed 
as PLIST_DATA
+  * mobileactivation: Allow passing activation response headers as required 
for iOS 11.2+
+  * lockdown: Plug small memory leak
+  * idevicesyslog: Wait for passcode entry on device when required
+  * idevicediagnostics: Add HDMI to the list of valid options for diagnostics 
command
+  * idevicediagnostics: Add ioregentry command to query device IORegistry by 
entry
+  * userpref: [GnuTLS] Fix 3.6.0 SHA1 compatibility
+  * userpref: [GnuTLS] Use valid serial for >= 3.6.0
+  * build: Fix autogen.sh with srcdir != builddir
+
+-------------------------------------------------------------------

Old:
----
  libimobiledevice-1.2.0+git20170122.45fda81.tar.xz

New:
----
  libimobiledevice-1.2.0+git20180427.26373b3.tar.xz

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ libimobiledevice.spec ++++++
--- /var/tmp/diff_new_pack.R7VbkB/_old  2018-06-22 13:13:39.142888736 +0200
+++ /var/tmp/diff_new_pack.R7VbkB/_new  2018-06-22 13:13:39.146888588 +0200
@@ -18,7 +18,7 @@
 
 %define soname 6
 Name:           libimobiledevice
-Version:        1.2.0+git20170122.45fda81
+Version:        1.2.0+git20180427.26373b3
 Release:        0
 Summary:        Native protocols library for iOS devices
 License:        LGPL-2.1+

++++++ libimobiledevice-1.2.0+git20170122.45fda81.tar.xz -> 
libimobiledevice-1.2.0+git20180427.26373b3.tar.xz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libimobiledevice-1.2.0+git20170122.45fda81/README 
new/libimobiledevice-1.2.0+git20180427.26373b3/README
--- old/libimobiledevice-1.2.0+git20170122.45fda81/README       2017-01-22 
13:28:45.551033668 +0100
+++ new/libimobiledevice-1.2.0+git20180427.26373b3/README       2018-04-27 
19:24:36.000000000 +0200
@@ -8,7 +8,7 @@
 ============
 
 Development Packages of:
-       libgnutls or openssl
+       OpenSSL or GnuTLS
        libplist
        libusbmuxd
 
@@ -20,7 +20,7 @@
        autoconf
        libtool
        pkg-config
-       gcc
+       gcc or clang
 
 Optional:
        cython (Python bindings)
@@ -34,6 +34,16 @@
        make
        sudo make install
 
+If you require a custom prefix or other option being passed to ./configure
+you can pass them directly to ./autogen.sh like this:
+        ./autogen.sh --prefix=/opt/local --enable-debug-code
+        make
+        sudo make install
+
+By default, OpenSSL will be used. If you prefer GnuTLS, configure with
+ --disable-openssl like this:
+       ./autogen.sh --disable-openssl
+
 Who/What/Where?
 ===============
 
@@ -47,7 +57,7 @@
        git clone https://github.com/libimobiledevice/libimobiledevice.git
 
 Tickets:
-       http://github.com/libimobiledevice/libimobiledevice/issues
+       https://github.com/libimobiledevice/libimobiledevice/issues
 
 Mailing List:
        
http://lists.libimobiledevice.org/mailman/listinfo/libimobiledevice-devel
@@ -66,4 +76,4 @@
 authorized, sponsored, or otherwise approved by Apple Inc.
 
 README Updated on:
-       2015-01-28
+       2017-04-28
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/libimobiledevice-1.2.0+git20170122.45fda81/autogen.sh 
new/libimobiledevice-1.2.0+git20180427.26373b3/autogen.sh
--- old/libimobiledevice-1.2.0+git20170122.45fda81/autogen.sh   2017-01-22 
13:28:45.551033668 +0100
+++ new/libimobiledevice-1.2.0+git20180427.26373b3/autogen.sh   2018-04-27 
19:24:36.000000000 +0200
@@ -1,4 +1,11 @@
 #!/bin/sh
+
+olddir=`pwd`
+srcdir=`dirname $0`
+test -z "$srcdir" && srcdir=.
+
+cd "$srcdir"
+
 gprefix=`which glibtoolize 2>&1 >/dev/null`
 if [ $? -eq 0 ]; then 
   glibtoolize --force
@@ -10,6 +17,8 @@
 automake --add-missing
 autoconf
 
+cd "$olddir"
+
 if [ -z "$NOCONFIGURE" ]; then
-    ./configure "$@"
+    $srcdir/configure "$@"
 fi
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/libimobiledevice-1.2.0+git20170122.45fda81/common/userpref.c 
new/libimobiledevice-1.2.0+git20180427.26373b3/common/userpref.c
--- old/libimobiledevice-1.2.0+git20170122.45fda81/common/userpref.c    
2017-01-22 13:28:45.555033668 +0100
+++ new/libimobiledevice-1.2.0+git20180427.26373b3/common/userpref.c    
2018-04-27 19:24:36.000000000 +0200
@@ -598,21 +598,21 @@
 
        /* generate certificates */
        gnutls_x509_crt_set_key(root_cert, root_privkey);
-       gnutls_x509_crt_set_serial(root_cert, "\x00", 1);
+       gnutls_x509_crt_set_serial(root_cert, "\x01", 1);
        gnutls_x509_crt_set_version(root_cert, 3);
        gnutls_x509_crt_set_ca_status(root_cert, 1);
        gnutls_x509_crt_set_activation_time(root_cert, time(NULL));
        gnutls_x509_crt_set_expiration_time(root_cert, time(NULL) + (60 * 60 * 
24 * 365 * 10));
-       gnutls_x509_crt_sign(root_cert, root_cert, root_privkey);
+       gnutls_x509_crt_sign2(root_cert, root_cert, root_privkey, 
GNUTLS_DIG_SHA1, 0);
 
        gnutls_x509_crt_set_key(host_cert, host_privkey);
-       gnutls_x509_crt_set_serial(host_cert, "\x00", 1);
+       gnutls_x509_crt_set_serial(host_cert, "\x01", 1);
        gnutls_x509_crt_set_version(host_cert, 3);
        gnutls_x509_crt_set_ca_status(host_cert, 0);
        gnutls_x509_crt_set_key_usage(host_cert, GNUTLS_KEY_KEY_ENCIPHERMENT | 
GNUTLS_KEY_DIGITAL_SIGNATURE);
        gnutls_x509_crt_set_activation_time(host_cert, time(NULL));
        gnutls_x509_crt_set_expiration_time(host_cert, time(NULL) + (60 * 60 * 
24 * 365 * 10));
-       gnutls_x509_crt_sign(host_cert, root_cert, root_privkey);
+       gnutls_x509_crt_sign2(host_cert, root_cert, root_privkey, 
GNUTLS_DIG_SHA1, 0);
 
        /* export to PEM format */
        size_t root_key_export_size = 0;
@@ -703,7 +703,7 @@
                if (GNUTLS_E_SUCCESS == gnutls_error) {
                        /* now generate device certificate */
                        gnutls_x509_crt_set_key(dev_cert, fake_privkey);
-                       gnutls_x509_crt_set_serial(dev_cert, "\x00", 1);
+                       gnutls_x509_crt_set_serial(dev_cert, "\x01", 1);
                        gnutls_x509_crt_set_version(dev_cert, 3);
                        gnutls_x509_crt_set_ca_status(dev_cert, 0);
                        gnutls_x509_crt_set_activation_time(dev_cert, 
time(NULL));
@@ -720,7 +720,7 @@
                        }
 
                        gnutls_x509_crt_set_key_usage(dev_cert, 
GNUTLS_KEY_DIGITAL_SIGNATURE | GNUTLS_KEY_KEY_ENCIPHERMENT);
-                       gnutls_error = gnutls_x509_crt_sign(dev_cert, 
root_cert, root_privkey);
+                       gnutls_error = gnutls_x509_crt_sign2(dev_cert, 
root_cert, root_privkey, GNUTLS_DIG_SHA1, 0);
                        if (GNUTLS_E_SUCCESS == gnutls_error) {
                                /* if everything went well, export in PEM 
format */
                                size_t export_size = 0;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/libimobiledevice-1.2.0+git20170122.45fda81/cython/lockdown.pxi 
new/libimobiledevice-1.2.0+git20180427.26373b3/cython/lockdown.pxi
--- old/libimobiledevice-1.2.0+git20170122.45fda81/cython/lockdown.pxi  
2017-01-22 13:28:45.555033668 +0100
+++ new/libimobiledevice-1.2.0+git20180427.26373b3/cython/lockdown.pxi  
2018-04-27 19:24:36.000000000 +0200
@@ -7,7 +7,7 @@
         LOCKDOWN_E_PAIRING_FAILED
         LOCKDOWN_E_SSL_ERROR
         LOCKDOWN_E_DICT_ERROR
-        LOCKDOWN_E_NOT_ENOUGH_DATA
+        LOCKDOWN_E_RECEIVE_TIMEOUT
         LOCKDOWN_E_SET_VALUE_PROHIBITED
         LOCKDOWN_E_GET_VALUE_PROHIBITED
         LOCKDOWN_E_MUX_ERROR
@@ -78,7 +78,7 @@
             LOCKDOWN_E_PAIRING_FAILED: "Pairing failed",
             LOCKDOWN_E_SSL_ERROR: "SSL error",
             LOCKDOWN_E_DICT_ERROR: "Dictionary error",
-            LOCKDOWN_E_NOT_ENOUGH_DATA: "Not enough data",
+            LOCKDOWN_E_RECEIVE_TIMEOUT: "Receive timeout",
             LOCKDOWN_E_MUX_ERROR: "Mux Protocol Error",
             LOCKDOWN_E_NO_RUNNING_SESSION: "No running session",
             LOCKDOWN_E_INVALID_RESPONSE: "Invalid response",
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/libimobiledevice-1.2.0+git20170122.45fda81/include/Makefile.am 
new/libimobiledevice-1.2.0+git20180427.26373b3/include/Makefile.am
--- old/libimobiledevice-1.2.0+git20170122.45fda81/include/Makefile.am  
2017-01-22 13:28:45.555033668 +0100
+++ new/libimobiledevice-1.2.0+git20180427.26373b3/include/Makefile.am  
2018-04-27 19:24:36.000000000 +0200
@@ -20,5 +20,6 @@
                         libimobiledevice/diagnostics_relay.h\
                         libimobiledevice/debugserver.h\
                         libimobiledevice/syslog_relay.h\
+                        libimobiledevice/mobileactivation.h\
                         libimobiledevice/property_list_service.h\
                         libimobiledevice/service.h
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/libimobiledevice-1.2.0+git20170122.45fda81/include/endianness.h 
new/libimobiledevice-1.2.0+git20180427.26373b3/include/endianness.h
--- old/libimobiledevice-1.2.0+git20170122.45fda81/include/endianness.h 
2017-01-22 13:28:45.555033668 +0100
+++ new/libimobiledevice-1.2.0+git20180427.26373b3/include/endianness.h 
2018-04-27 19:24:36.000000000 +0200
@@ -27,6 +27,10 @@
 #endif
 #endif
 
+#ifndef htobe16
+#define htobe16 be16toh
+#endif
+
 #ifndef __bswap_32
 #define __bswap_32(x) ((((x) & 0xFF000000) >> 24) \
                     | (((x) & 0x00FF0000) >> 8) \
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/libimobiledevice-1.2.0+git20170122.45fda81/include/libimobiledevice/libimobiledevice.h
 
new/libimobiledevice-1.2.0+git20180427.26373b3/include/libimobiledevice/libimobiledevice.h
--- 
old/libimobiledevice-1.2.0+git20170122.45fda81/include/libimobiledevice/libimobiledevice.h
  2017-01-22 13:28:45.559033668 +0100
+++ 
new/libimobiledevice-1.2.0+git20180427.26373b3/include/libimobiledevice/libimobiledevice.h
  2018-04-27 19:24:36.000000000 +0200
@@ -55,7 +55,8 @@
 /** The event type for device add or removal */
 enum idevice_event_type {
        IDEVICE_DEVICE_ADD = 1,
-       IDEVICE_DEVICE_REMOVE
+       IDEVICE_DEVICE_REMOVE,
+       IDEVICE_DEVICE_PAIRED
 };
 
 /* event data structure */
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/libimobiledevice-1.2.0+git20170122.45fda81/include/libimobiledevice/lockdown.h
 
new/libimobiledevice-1.2.0+git20180427.26373b3/include/libimobiledevice/lockdown.h
--- 
old/libimobiledevice-1.2.0+git20170122.45fda81/include/libimobiledevice/lockdown.h
  2017-01-22 13:28:45.559033668 +0100
+++ 
new/libimobiledevice-1.2.0+git20180427.26373b3/include/libimobiledevice/lockdown.h
  2018-04-27 19:24:36.000000000 +0200
@@ -43,7 +43,7 @@
        LOCKDOWN_E_PAIRING_FAILED                          =  -4,
        LOCKDOWN_E_SSL_ERROR                               =  -5,
        LOCKDOWN_E_DICT_ERROR                              =  -6,
-       LOCKDOWN_E_NOT_ENOUGH_DATA                         =  -7,
+       LOCKDOWN_E_RECEIVE_TIMEOUT                         =  -7,
        LOCKDOWN_E_MUX_ERROR                               =  -8,
        LOCKDOWN_E_NO_RUNNING_SESSION                      =  -9,
        /* native */
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/libimobiledevice-1.2.0+git20170122.45fda81/include/libimobiledevice/mobileactivation.h
 
new/libimobiledevice-1.2.0+git20180427.26373b3/include/libimobiledevice/mobileactivation.h
--- 
old/libimobiledevice-1.2.0+git20170122.45fda81/include/libimobiledevice/mobileactivation.h
  1970-01-01 01:00:00.000000000 +0100
+++ 
new/libimobiledevice-1.2.0+git20180427.26373b3/include/libimobiledevice/mobileactivation.h
  2018-04-27 19:24:36.000000000 +0200
@@ -0,0 +1,191 @@
+/**
+ * @file libimobiledevice/mobileactivation.h
+ * @brief Handle device activation and deactivation.
+ * \internal
+ *
+ * Copyright (c) 2016-2017 Nikias Bassen, All Rights Reserved.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  
USA
+ */
+
+#ifndef IMOBILEACTIVATION_H
+#define IMOBILEACTIVATION_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <libimobiledevice/libimobiledevice.h>
+#include <libimobiledevice/lockdown.h>
+
+#define MOBILEACTIVATION_SERVICE_NAME "com.apple.mobileactivationd"
+
+/** Error Codes */
+typedef enum {
+       MOBILEACTIVATION_E_SUCCESS         =  0,
+       MOBILEACTIVATION_E_INVALID_ARG     = -1,
+       MOBILEACTIVATION_E_PLIST_ERROR     = -2,
+       MOBILEACTIVATION_E_MUX_ERROR       = -3,
+       MOBILEACTIVATION_E_UNKNOWN_REQUEST = -4,
+       MOBILEACTIVATION_E_REQUEST_FAILED  = -5,
+       MOBILEACTIVATION_E_UNKNOWN_ERROR   = -256
+} mobileactivation_error_t;
+
+typedef struct mobileactivation_client_private mobileactivation_client_private;
+typedef mobileactivation_client_private *mobileactivation_client_t; /**< The 
client handle. */
+
+/**
+ * Connects to the mobileactivation service on the specified device.
+ *
+ * @param device The device to connect to.
+ * @param service The service descriptor returned by lockdownd_start_service.
+ * @param client Reference that will point to a newly allocated
+ *     mobileactivation_client_t upon successful return.
+ *
+ * @return MOBILEACTIVATION_E_SUCCESS on success,
+ *     MOBILEACTIVATION_E_INVALID_ARG when one of the parameters is invalid,
+ *     or MOBILEACTIVATION_E_MUX_ERROR when the connection failed.
+ */
+mobileactivation_error_t mobileactivation_client_new(idevice_t device, 
lockdownd_service_descriptor_t service, mobileactivation_client_t *client);
+
+/**
+ * Starts a new mobileactivation service on the specified device and connects 
to it.
+ *
+ * @param device The device to connect to.
+ * @param client Pointer that will point to a newly allocated
+ *     mobileactivation_client_t upon successful return. Must be freed using
+ *     mobileactivation_client_free() after use.
+ * @param label The label to use for communication. Usually the program name.
+ *  Pass NULL to disable sending the label in requests to lockdownd.
+ *
+ * @return MOBILEACTIVATION_E_SUCCESS on success, or an MOBILEACTIVATION_E_*
+ *     error code otherwise.
+ */
+mobileactivation_error_t mobileactivation_client_start_service(idevice_t 
device, mobileactivation_client_t* client, const char* label);
+
+/**
+ * Disconnects a mobileactivation client from the device and frees up the
+ * mobileactivation client data.
+ *
+ * @param client The mobileactivation client to disconnect and free.
+ *
+ * @return MOBILEACTIVATION_E_SUCCESS on success,
+ *     MOBILEACTIVATION_E_INVALID_ARG when one of client or client->parent
+ *     is invalid, or MOBILEACTIVATION_E_UNKNOWN_ERROR when the was an
+ *     error freeing the parent property_list_service client.
+ */
+mobileactivation_error_t 
mobileactivation_client_free(mobileactivation_client_t client);
+
+
+/**
+ * Retrieves the device's activation state.
+ *
+ * @param client The mobileactivation client.
+ * @param state Pointer to a plist_t variable that will be set to the
+ *     activation state reported by the mobileactivation service. The
+ *     consumer is responsible for freeing the returned object using
+ *     plist_free().
+ *
+ * @return MOBILEACTIVATION_E_SUCCESS on success, or an MOBILEACTIVATION_E_*
+ *     error code otherwise.
+ */
+mobileactivation_error_t 
mobileactivation_get_activation_state(mobileactivation_client_t client, plist_t 
*state);
+
+/**
+ * Retrieves a session blob required for 'drmHandshake' via albert.apple.com.
+ *
+ * @param client The mobileactivation client
+ * @param blob Pointer to a plist_t variable that will be set to the
+ *     session blob created by the mobielactivation service. The
+ *     consumer is responsible for freeing the returned object using
+ *     plist_free().
+ *
+ * @return MOBILEACTIVATION_E_SUCCESS on success, or an MOBILEACTIVATION_E_*
+ *     error code otherwise.
+ */
+mobileactivation_error_t 
mobileactivation_create_activation_session_info(mobileactivation_client_t 
client, plist_t *blob);
+
+/**
+ * Retrieves the activation info required for device activation.
+ *
+ * @param client The mobileactivation client
+ * @param info Pointer to a plist_t variable that will be set to the
+ *     activation info created by the mobileactivation service. The
+ *     consumer is responsible for freeing the returned object using
+ *     plist_free().
+ *
+ * @return MOBILEACTIVATION_E_SUCCESS on success, or an MOBILEACTIVATION_E_*
+ *     error code otherwise.
+ */
+mobileactivation_error_t 
mobileactivation_create_activation_info(mobileactivation_client_t client, 
plist_t *info);
+
+/**
+ * Retrieves the activation info required for device activation in 'session'
+ * mode. This function expects a handshake result retrieved from
+ * https://albert.apple.com/deviceservies/drmHandshake  with a blob
+ * provided by mobileactivation_create_activation_session_info().
+ *
+ * @param client The mobileactivation client
+ * @aram handshake_result The handshake result returned from drmHandshake
+ * @param info Pointer to a plist_t variable that will be set to the
+ *     activation info created by the mobileactivation service. The
+ *     consumer is responsible for freeing the returned object using
+ *     plist_free().
+ *
+ * @return MOBILEACTIVATION_E_SUCCESS on success, or an MOBILEACTIVATION_E_*
+ *     error code otherwise.
+ */
+mobileactivation_error_t 
mobileactivation_create_activation_info_with_session(mobileactivation_client_t 
client, plist_t handshake_result, plist_t *info);
+
+/**
+ * Activates the device with the given activation record.
+ * The activation record plist dictionary must be obtained using the
+ * activation protocol requesting from Apple's https webservice.
+ *
+ * @param client The mobileactivation client
+ * @param activation_record The activation record plist dictionary
+ *
+ * @return MOBILEACTIVATION_E_SUCCESS on success, or an MOBILEACTIVATION_E_*
+ *     error code otherwise.
+ */
+mobileactivation_error_t mobileactivation_activate(mobileactivation_client_t 
client, plist_t activation_record);
+
+/**
+ * Activates the device with the given activation record in 'session' mode.
+ * The activation record plist must be obtained using the
+ * activation protocol requesting from Apple's https webservice.
+ *
+ * @param client The mobileactivation client
+ * @param activation_record The activation record in plist format
+ * @param headers A plist dictionary with the activation response headers
+ *     as returned from Apple's https webservice with the activation record
+ *
+ * @return MOBILEACTIVATION_E_SUCCESS on success, or an MOBILEACTIVATION_E_*
+ *     error code otherwise.
+ */
+mobileactivation_error_t 
mobileactivation_activate_with_session(mobileactivation_client_t client, 
plist_t activation_record, plist_t headers);
+
+/**
+ * Deactivates the device.
+ *
+ * @param client The mobileactivation client
+ */
+mobileactivation_error_t mobileactivation_deactivate(mobileactivation_client_t 
client);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/libimobiledevice-1.2.0+git20170122.45fda81/src/Makefile.am 
new/libimobiledevice-1.2.0+git20180427.26373b3/src/Makefile.am
--- old/libimobiledevice-1.2.0+git20170122.45fda81/src/Makefile.am      
2017-01-22 13:28:45.559033668 +0100
+++ new/libimobiledevice-1.2.0+git20180427.26373b3/src/Makefile.am      
2018-04-27 19:24:36.000000000 +0200
@@ -28,6 +28,7 @@
                       heartbeat.c heartbeat.h\
                       debugserver.c debugserver.h\
                       webinspector.c webinspector.h\
+                      mobileactivation.c mobileactivation.h\
                       syslog_relay.c syslog_relay.h
 
 if WIN32
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/libimobiledevice-1.2.0+git20170122.45fda81/src/idevice.c 
new/libimobiledevice-1.2.0+git20180427.26373b3/src/idevice.c
--- old/libimobiledevice-1.2.0+git20170122.45fda81/src/idevice.c        
2017-01-22 13:28:45.559033668 +0100
+++ new/libimobiledevice-1.2.0+git20180427.26373b3/src/idevice.c        
2018-04-27 19:24:36.000000000 +0200
@@ -37,10 +37,7 @@
 #ifdef HAVE_OPENSSL
 #include <openssl/err.h>
 #include <openssl/ssl.h>
-#if OPENSSL_VERSION_NUMBER >= 0x10000001L
-/* since OpenSSL 1.0.0-beta1 */
-#define HAVE_ERR_REMOVE_THREAD_STATE 1
-#endif
+
 #else
 #include <gnutls/gnutls.h>
 #endif
@@ -51,6 +48,28 @@
 #include "common/debug.h"
 
 #ifdef HAVE_OPENSSL
+
+#if OPENSSL_VERSION_NUMBER < 0x10002000L
+static void SSL_COMP_free_compression_methods(void)
+{
+       sk_SSL_COMP_free(SSL_COMP_get_compression_methods());
+}
+#endif
+
+static void openssl_remove_thread_state(void)
+{
+/*  ERR_remove_thread_state() is available since OpenSSL 1.0.0-beta1, but
+ *  deprecated in OpenSSL 1.1.0 */
+#if OPENSSL_VERSION_NUMBER < 0x10100000L
+#if OPENSSL_VERSION_NUMBER >= 0x10000001L
+       ERR_remove_thread_state(NULL);
+#else
+       ERR_remove_state(0);
+#endif
+#endif
+}
+
+#if OPENSSL_VERSION_NUMBER < 0x10100000L
 static mutex_t *mutex_buf = NULL;
 static void locking_function(int mode, int n, const char* file, int line)
 {
@@ -65,10 +84,12 @@
        return ((unsigned long)THREAD_ID);
 }
 #endif
+#endif
 
 static void internal_idevice_init(void)
 {
 #ifdef HAVE_OPENSSL
+#if OPENSSL_VERSION_NUMBER < 0x10100000L
        int i;
        SSL_library_init();
 
@@ -80,6 +101,7 @@
 
        CRYPTO_set_id_callback(id_function);
        CRYPTO_set_locking_callback(locking_function);
+#endif
 #else
        gnutls_global_init();
 #endif
@@ -88,6 +110,7 @@
 static void internal_idevice_deinit(void)
 {
 #ifdef HAVE_OPENSSL
+#if OPENSSL_VERSION_NUMBER < 0x10100000L
        int i;
        if (mutex_buf) {
                CRYPTO_set_id_callback(NULL);
@@ -100,11 +123,8 @@
 
        EVP_cleanup();
        CRYPTO_cleanup_all_ex_data();
-       sk_SSL_COMP_free(SSL_COMP_get_compression_methods());
-#ifdef HAVE_ERR_REMOVE_THREAD_STATE
-       ERR_remove_thread_state(NULL);
-#else
-       ERR_remove_state(0);
+       SSL_COMP_free_compression_methods();
+       openssl_remove_thread_state();
 #endif
 #else
        gnutls_global_deinit();
@@ -236,6 +256,7 @@
                dev->udid = strdup(muxdev.udid);
                dev->conn_type = CONNECTION_USBMUXD;
                dev->conn_data = (void*)(long)muxdev.handle;
+               dev->version = 0;
                *device = dev;
                return IDEVICE_E_SUCCESS;
        }
@@ -376,8 +397,8 @@
        if (connection->type == CONNECTION_USBMUXD) {
                int res = usbmuxd_recv_timeout((int)(long)connection->data, 
data, len, recv_bytes, timeout);
                if (res < 0) {
-                       debug_info("ERROR: usbmuxd_recv_timeout returned %d 
(%s)", res, strerror(-res));
-                       return IDEVICE_E_UNKNOWN_ERROR;
+                       debug_info("ERROR: usbmuxd_recv_timeout returned %d 
(%s)", res, strerror(errno));
+                       return (res == -EAGAIN ? IDEVICE_E_NOT_ENOUGH_DATA : 
IDEVICE_E_UNKNOWN_ERROR);
                }
                return IDEVICE_E_SUCCESS;
        } else {
@@ -677,7 +698,11 @@
                return IDEVICE_E_INVALID_ARG;
 
        idevice_error_t ret = IDEVICE_E_SSL_ERROR;
+#ifdef HAVE_OPENSSL
        uint32_t return_me = 0;
+#else
+       int return_me = 0;
+#endif
        plist_t pair_record = NULL;
 
        userpref_read_pair_record(connection->udid, &pair_record);
@@ -756,11 +781,7 @@
                debug_info("SSL mode enabled, cipher: %s", SSL_get_cipher(ssl));
        }
        /* required for proper multi-thread clean up to prevent leaks */
-#ifdef HAVE_ERR_REMOVE_THREAD_STATE
-       ERR_remove_thread_state(NULL);
-#else
-       ERR_remove_state(0);
-#endif
+       openssl_remove_thread_state();
 #else
        ssl_data_t ssl_data_loc = (ssl_data_t)malloc(sizeof(struct 
ssl_data_private));
 
@@ -801,14 +822,17 @@
        if (errno) {
                debug_info("WARNING: errno says %s before handshake!", 
strerror(errno));
        }
-       return_me = gnutls_handshake(ssl_data_loc->session);
+
+       do {
+               return_me = gnutls_handshake(ssl_data_loc->session);
+       } while(return_me == GNUTLS_E_AGAIN || return_me == 
GNUTLS_E_INTERRUPTED);
+
        debug_info("GnuTLS handshake done...");
 
        if (return_me != GNUTLS_E_SUCCESS) {
                internal_ssl_cleanup(ssl_data_loc);
                free(ssl_data_loc);
-               debug_info("GnuTLS reported something wrong.");
-               gnutls_perror(return_me);
+               debug_info("GnuTLS reported something wrong: %s", 
gnutls_strerror(return_me));
                debug_info("oh.. errno says %s", strerror(errno));
        } else {
                connection->ssl_data = ssl_data_loc;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/libimobiledevice-1.2.0+git20170122.45fda81/src/idevice.h 
new/libimobiledevice-1.2.0+git20180427.26373b3/src/idevice.h
--- old/libimobiledevice-1.2.0+git20170122.45fda81/src/idevice.h        
2017-01-22 13:28:45.559033668 +0100
+++ new/libimobiledevice-1.2.0+git20180427.26373b3/src/idevice.h        
2018-04-27 19:24:36.000000000 +0200
@@ -76,6 +76,7 @@
        char *udid;
        enum connection_type conn_type;
        void *conn_data;
+       int version;
 };
 
 #endif
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/libimobiledevice-1.2.0+git20170122.45fda81/src/installation_proxy.c 
new/libimobiledevice-1.2.0+git20180427.26373b3/src/installation_proxy.c
--- old/libimobiledevice-1.2.0+git20170122.45fda81/src/installation_proxy.c     
2017-01-22 13:28:45.559033668 +0100
+++ new/libimobiledevice-1.2.0+git20180427.26373b3/src/installation_proxy.c     
2018-04-27 19:24:36.000000000 +0200
@@ -772,7 +772,7 @@
 
 LIBIMOBILEDEVICE_API instproxy_error_t 
instproxy_check_capabilities_match(instproxy_client_t client, const char** 
capabilities, plist_t client_options, plist_t *result)
 {
-       if (!capabilities || (plist_get_node_type(capabilities) != PLIST_ARRAY 
&& plist_get_node_type(capabilities) != PLIST_DICT))
+       if (!client || !capabilities || !result)
                return INSTPROXY_E_INVALID_ARG;
 
        plist_t lookup_result = NULL;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/libimobiledevice-1.2.0+git20170122.45fda81/src/lockdown.c 
new/libimobiledevice-1.2.0+git20180427.26373b3/src/lockdown.c
--- old/libimobiledevice-1.2.0+git20170122.45fda81/src/lockdown.c       
2017-01-22 13:28:45.559033668 +0100
+++ new/libimobiledevice-1.2.0+git20180427.26373b3/src/lockdown.c       
2018-04-27 19:24:36.000000000 +0200
@@ -136,6 +136,36 @@
 }
 
 /**
+ * Convert a property_list_service_error_t value to a lockdownd_error_t
+ * value. Used internally to get correct error codes.
+ *
+ * @param err A property_list_service_error_t error code
+ *
+ * @return A matching lockdownd_error_t error code,
+ *     LOCKDOWND_E_UNKNOWN_ERROR otherwise.
+ */
+static lockdownd_error_t lockdownd_error(property_list_service_error_t err)
+{
+       switch (err) {
+               case PROPERTY_LIST_SERVICE_E_SUCCESS:
+                       return LOCKDOWN_E_SUCCESS;
+               case PROPERTY_LIST_SERVICE_E_INVALID_ARG:
+                       return LOCKDOWN_E_INVALID_ARG;
+               case PROPERTY_LIST_SERVICE_E_PLIST_ERROR:
+                       return LOCKDOWN_E_PLIST_ERROR;
+               case PROPERTY_LIST_SERVICE_E_MUX_ERROR:
+                       return LOCKDOWN_E_MUX_ERROR;
+               case PROPERTY_LIST_SERVICE_E_SSL_ERROR:
+                       return LOCKDOWN_E_SSL_ERROR;
+               case PROPERTY_LIST_SERVICE_E_RECEIVE_TIMEOUT:
+                       return LOCKDOWN_E_RECEIVE_TIMEOUT;
+               default:
+                       break;
+       }
+       return LOCKDOWN_E_UNKNOWN_ERROR;
+}
+
+/**
  * Internally used function for checking the result from lockdown's answer
  * plist to a previously sent request.
  *
@@ -349,18 +379,8 @@
 {
        if (!client || !plist || (plist && *plist))
                return LOCKDOWN_E_INVALID_ARG;
-       lockdownd_error_t ret = LOCKDOWN_E_SUCCESS;
-       property_list_service_error_t err;
-
-       err = property_list_service_receive_plist(client->parent, plist);
-       if (err != PROPERTY_LIST_SERVICE_E_SUCCESS) {
-               ret = LOCKDOWN_E_UNKNOWN_ERROR;
-       }
 
-       if (!*plist)
-               ret = LOCKDOWN_E_PLIST_ERROR;
-
-       return ret;
+       return 
lockdownd_error(property_list_service_receive_plist(client->parent, plist));
 }
 
 LIBIMOBILEDEVICE_API lockdownd_error_t lockdownd_send(lockdownd_client_t 
client, plist_t plist)
@@ -368,14 +388,7 @@
        if (!client || !plist)
                return LOCKDOWN_E_INVALID_ARG;
 
-       lockdownd_error_t ret = LOCKDOWN_E_SUCCESS;
-       property_list_service_error_t err;
-
-       err = property_list_service_send_xml_plist(client->parent, plist);
-       if (err != PROPERTY_LIST_SERVICE_E_SUCCESS) {
-               ret = LOCKDOWN_E_UNKNOWN_ERROR;
-       }
-       return ret;
+       return 
lockdownd_error(property_list_service_send_xml_plist(client->parent, plist));
 }
 
 LIBIMOBILEDEVICE_API lockdownd_error_t lockdownd_query_type(lockdownd_client_t 
client, char **type)
@@ -686,16 +699,28 @@
        }
 
        /* perform handshake */
-       if (LOCKDOWN_E_SUCCESS != lockdownd_query_type(client_loc, &type)) {
+       ret = lockdownd_query_type(client_loc, &type);
+       if (LOCKDOWN_E_SUCCESS != ret) {
                debug_info("QueryType failed in the lockdownd client.");
-               ret = LOCKDOWN_E_NOT_ENOUGH_DATA;
-       } else {
-               if (strcmp("com.apple.mobile.lockdown", type)) {
-                       debug_info("Warning QueryType request returned 
\"%s\".", type);
-               }
+       } else if (strcmp("com.apple.mobile.lockdown", type)) {
+               debug_info("Warning QueryType request returned \"%s\".", type);
        }
        free(type);
 
+       if (device->version == 0) {
+               plist_t p_version = NULL;
+               if (lockdownd_get_value(client_loc, NULL, "ProductVersion", 
&p_version) == LOCKDOWN_E_SUCCESS) {
+                       int vers[3] = {0, 0, 0};
+                       char *s_version = NULL;
+                       plist_get_string_val(p_version, &s_version);
+                       if (s_version && sscanf(s_version, "%d.%d.%d", 
&vers[0], &vers[1], &vers[2]) >= 2) {
+                               device->version = ((vers[0] & 0xFF) << 16) | 
((vers[1] & 0xFF) << 8) | (vers[2] & 0xFF);
+                       }
+                       free(s_version);
+               }
+               plist_free(p_version);
+       }
+
        userpref_read_pair_record(client_loc->udid, &pair_record);
        if (pair_record) {
                pair_record_get_host_id(pair_record, &host_id);
@@ -712,18 +737,18 @@
        plist_free(pair_record);
        pair_record = NULL;
 
-       /* in any case, we need to validate pairing to receive trusted host 
status */
-       ret = lockdownd_validate_pair(client_loc, NULL);
-
-       /* if not paired yet, let's do it now */
-       if (LOCKDOWN_E_INVALID_HOST_ID == ret) {
-               free(host_id);
-               host_id = NULL;
-               ret = lockdownd_pair(client_loc, NULL);
-               if (LOCKDOWN_E_SUCCESS == ret) {
-                       ret = lockdownd_validate_pair(client_loc, NULL);
-               } else if (LOCKDOWN_E_PAIRING_DIALOG_RESPONSE_PENDING == ret) {
-                       debug_info("Device shows the pairing dialog.");
+       if (device->version < 0x070000) {
+               /* for older devices, we need to validate pairing to receive 
trusted host status */
+               ret = lockdownd_validate_pair(client_loc, NULL);
+
+               /* if not paired yet, let's do it now */
+               if (LOCKDOWN_E_INVALID_HOST_ID == ret) {
+                       free(host_id);
+                       host_id = NULL;
+                       ret = lockdownd_pair(client_loc, NULL);
+                       if (LOCKDOWN_E_SUCCESS == ret) {
+                               ret = lockdownd_validate_pair(client_loc, NULL);
+                       }
                }
        }
 
@@ -1113,7 +1138,6 @@
 LIBIMOBILEDEVICE_API lockdownd_error_t 
lockdownd_start_session(lockdownd_client_t client, const char *host_id, char 
**session_id, int *ssl_enabled)
 {
        lockdownd_error_t ret = LOCKDOWN_E_SUCCESS;
-       property_list_service_error_t plret;
        plist_t dict = NULL;
 
        if (!client || !host_id)
@@ -1184,20 +1208,14 @@
                        debug_info("Failed to get SessionID!");
                }
 
-               debug_info("Enable SSL Session: %s", (use_ssl?"true":"false"));
+               debug_info("Enable SSL Session: %s", (use_ssl ? "true" : 
"false"));
 
                if (use_ssl) {
-                       plret = 
property_list_service_enable_ssl(client->parent);
-                       if (plret == PROPERTY_LIST_SERVICE_E_SUCCESS) {
-                               ret = LOCKDOWN_E_SUCCESS;
-                               client->ssl_enabled = 1;
-                       } else {
-                               ret = LOCKDOWN_E_SSL_ERROR;
-                               client->ssl_enabled = 0;
-                       }
+                       ret = 
lockdownd_error(property_list_service_enable_ssl(client->parent));
+                       client->ssl_enabled = (ret == LOCKDOWN_E_SUCCESS ? 1 : 
0);
                } else {
-                       client->ssl_enabled = 0;
                        ret = LOCKDOWN_E_SUCCESS;
+                       client->ssl_enabled = 0;
                }
        }
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/libimobiledevice-1.2.0+git20170122.45fda81/src/mobileactivation.c 
new/libimobiledevice-1.2.0+git20180427.26373b3/src/mobileactivation.c
--- old/libimobiledevice-1.2.0+git20170122.45fda81/src/mobileactivation.c       
1970-01-01 01:00:00.000000000 +0100
+++ new/libimobiledevice-1.2.0+git20180427.26373b3/src/mobileactivation.c       
2018-04-27 19:24:36.000000000 +0200
@@ -0,0 +1,313 @@
+/*
+ * mobileactivation.c
+ * com.apple.mobileactivationd service implementation.
+ *
+ * Copyright (c) 2016-2017 Nikias Bassen, All Rights Reserved.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  
USA
+ */
+#include <string.h>
+#include <stdlib.h>
+#include "mobileactivation.h"
+#include "property_list_service.h"
+#include "common/debug.h"
+
+/**
+ * Convert a property_list_service_error_t value to a mobileactivation_error_t 
value.
+ * Used internally to get correct error codes.
+ *
+ * @param err An property_list_service_error_t error code
+ *
+ * @return A matching mobileactivation_error_t error code,
+ *     MOBILEACTIVATION_E_UNKNOWN_ERROR otherwise.
+ */
+static mobileactivation_error_t 
mobileactivation_error(property_list_service_error_t err)
+{
+       switch (err) {
+               case PROPERTY_LIST_SERVICE_E_SUCCESS:
+                       return MOBILEACTIVATION_E_SUCCESS;
+               case PROPERTY_LIST_SERVICE_E_INVALID_ARG:
+                       return MOBILEACTIVATION_E_INVALID_ARG;
+               case PROPERTY_LIST_SERVICE_E_PLIST_ERROR:
+                       return MOBILEACTIVATION_E_PLIST_ERROR;
+               case PROPERTY_LIST_SERVICE_E_MUX_ERROR:
+                       return MOBILEACTIVATION_E_MUX_ERROR;
+               default:
+                       break;
+       }
+       return MOBILEACTIVATION_E_UNKNOWN_ERROR;
+}
+
+LIBIMOBILEDEVICE_API mobileactivation_error_t 
mobileactivation_client_new(idevice_t device, lockdownd_service_descriptor_t 
service, mobileactivation_client_t *client)
+{
+       if (!device || !service || service->port == 0 || !client || *client) {
+               return MOBILEACTIVATION_E_INVALID_ARG;
+       }
+
+       property_list_service_client_t plistclient = NULL;
+       if (property_list_service_client_new(device, service, &plistclient) != 
PROPERTY_LIST_SERVICE_E_SUCCESS) {
+               return MOBILEACTIVATION_E_MUX_ERROR;
+       }
+
+       /* create client object */
+       mobileactivation_client_t client_loc = (mobileactivation_client_t) 
malloc(sizeof(struct mobileactivation_client_private));
+       client_loc->parent = plistclient;
+
+       /* all done, return success */
+       *client = client_loc;
+       return MOBILEACTIVATION_E_SUCCESS;
+}
+
+LIBIMOBILEDEVICE_API mobileactivation_error_t 
mobileactivation_client_start_service(idevice_t device, 
mobileactivation_client_t * client, const char* label)
+{
+       mobileactivation_error_t err = MOBILEACTIVATION_E_UNKNOWN_ERROR;
+       service_client_factory_start_service(device, 
MOBILEACTIVATION_SERVICE_NAME, (void**)client, label, 
SERVICE_CONSTRUCTOR(mobileactivation_client_new), &err);
+       return err;
+}
+
+LIBIMOBILEDEVICE_API mobileactivation_error_t 
mobileactivation_client_free(mobileactivation_client_t client)
+{
+       if (!client)
+               return MOBILEACTIVATION_E_INVALID_ARG;
+
+       if (property_list_service_client_free(client->parent) != 
PROPERTY_LIST_SERVICE_E_SUCCESS) {
+               return MOBILEACTIVATION_E_UNKNOWN_ERROR;
+       }
+       free(client);
+       return MOBILEACTIVATION_E_SUCCESS;
+}
+
+static plist_t plist_data_from_plist(plist_t plist)
+{
+       if (plist && plist_get_node_type(plist) == PLIST_DATA) {
+               return plist_copy(plist);
+       }
+       plist_t result = NULL;
+       char *xml = NULL;
+       uint32_t xml_len = 0;
+       plist_to_xml(plist, &xml, &xml_len);
+       result = plist_new_data(xml, xml_len);
+       free(xml);
+       return result;
+}
+
+static mobileactivation_error_t mobileactivation_check_result(plist_t dict, 
const char *command)
+{
+       mobileactivation_error_t ret = MOBILEACTIVATION_E_UNKNOWN_ERROR;
+
+       if (!dict || plist_get_node_type(dict) != PLIST_DICT) {
+               return MOBILEACTIVATION_E_PLIST_ERROR;
+       }
+
+       plist_t err_node = plist_dict_get_item(dict, "Error");
+       if (!err_node) {
+               return MOBILEACTIVATION_E_SUCCESS;
+       } else {
+               char *errmsg = NULL;
+               plist_get_string_val(err_node, &errmsg);
+               debug_info("ERROR: %s: %s", command, errmsg);
+               ret = MOBILEACTIVATION_E_REQUEST_FAILED;
+               free(errmsg);
+       }
+       return ret;
+}
+
+static mobileactivation_error_t 
mobileactivation_send_command_plist(mobileactivation_client_t client, plist_t 
command, plist_t *result)
+{
+       if (!client || !command)
+               return MOBILEACTIVATION_E_INVALID_ARG;
+
+       plist_t cmd = plist_dict_get_item(command, "Command");
+       char* command_str = NULL;
+       if (cmd) {
+               plist_get_string_val(cmd, &command_str);
+       }
+       if (!command_str)
+               return MOBILEACTIVATION_E_INVALID_ARG;
+
+       mobileactivation_error_t ret = MOBILEACTIVATION_E_UNKNOWN_ERROR;
+       *result = NULL;
+
+       ret = 
mobileactivation_error(property_list_service_send_binary_plist(client->parent, 
command));
+
+       plist_t dict = NULL;
+       ret = 
mobileactivation_error(property_list_service_receive_plist(client->parent, 
&dict));
+       if (!dict) {
+               debug_info("ERROR: Did not get reply for %s command", 
command_str);
+               free(command_str);
+               return MOBILEACTIVATION_E_PLIST_ERROR;
+       }
+
+       *result = dict;
+       ret = mobileactivation_check_result(dict, command_str);
+       free(command_str);
+       return ret;
+}
+
+static mobileactivation_error_t 
mobileactivation_send_command(mobileactivation_client_t client, const char* 
command, plist_t value, plist_t *result)
+{
+       if (!client || !command || !result)
+               return MOBILEACTIVATION_E_INVALID_ARG;
+
+       mobileactivation_error_t ret = MOBILEACTIVATION_E_UNKNOWN_ERROR;
+       *result = NULL;
+
+       plist_t dict = plist_new_dict();
+       plist_dict_set_item(dict, "Command", plist_new_string(command));
+       if (value) {
+               plist_dict_set_item(dict, "Value", plist_copy(value));
+       }
+
+       ret = mobileactivation_send_command_plist(client, dict, result);
+       plist_free(dict);
+       return ret;
+}
+
+LIBIMOBILEDEVICE_API mobileactivation_error_t 
mobileactivation_get_activation_state(mobileactivation_client_t client, plist_t 
*state)
+{
+       if (!client || !state)
+               return MOBILEACTIVATION_E_INVALID_ARG;
+
+       plist_t result = NULL;
+       mobileactivation_error_t ret = mobileactivation_send_command(client, 
"GetActivationStateRequest", NULL, &result);
+       if (ret == MOBILEACTIVATION_E_SUCCESS) {
+               plist_t node = plist_dict_get_item(result, "Value");
+               if (!node) {
+                       debug_info("ERROR: GetActivationStateRequest command 
returned success but has no value in reply");
+                       ret = MOBILEACTIVATION_E_UNKNOWN_ERROR;
+               } else {
+                       *state = plist_copy(node);
+               }
+       }
+       plist_free(result);
+       result = NULL;
+
+       return ret;
+}
+
+LIBIMOBILEDEVICE_API mobileactivation_error_t 
mobileactivation_create_activation_session_info(mobileactivation_client_t 
client, plist_t *blob)
+{
+       if (!client || !blob)
+               return MOBILEACTIVATION_E_INVALID_ARG;
+
+       plist_t result = NULL;
+       mobileactivation_error_t ret = mobileactivation_send_command(client, 
"CreateTunnel1SessionInfoRequest", NULL, &result);
+       if (ret == MOBILEACTIVATION_E_SUCCESS) {
+               plist_t node = plist_dict_get_item(result, "Value");
+               if (!node) {
+                       debug_info("ERROR: CreateTunnel1SessionInfoRequest 
command returned success but has no value in reply");
+                       ret = MOBILEACTIVATION_E_UNKNOWN_ERROR;
+               } else {
+                       *blob = plist_copy(node);
+               }
+       }
+
+       return ret;
+}
+
+LIBIMOBILEDEVICE_API mobileactivation_error_t 
mobileactivation_create_activation_info(mobileactivation_client_t client, 
plist_t *info)
+{
+       if (!client || !info)
+               return MOBILEACTIVATION_E_INVALID_ARG;
+
+       plist_t result = NULL;
+       mobileactivation_error_t ret = mobileactivation_send_command(client, 
"CreateActivationInfoRequest", NULL, &result);
+       if (ret == MOBILEACTIVATION_E_SUCCESS) {
+               plist_t node = plist_dict_get_item(result, "Value");
+               if (!node) {
+                       debug_info("ERROR: CreateActivationInfoRequest command 
returned success but has no value in reply");
+                       ret = MOBILEACTIVATION_E_UNKNOWN_ERROR;
+               } else {
+                       *info = plist_copy(node);
+               }
+       }
+       plist_free(result);
+       result = NULL;
+
+       return ret;
+}
+
+LIBIMOBILEDEVICE_API mobileactivation_error_t 
mobileactivation_create_activation_info_with_session(mobileactivation_client_t 
client, plist_t handshake_response, plist_t *info)
+{
+       if (!client || !info)
+               return MOBILEACTIVATION_E_INVALID_ARG;
+
+       plist_t result = NULL;
+       plist_t data = plist_data_from_plist(handshake_response);
+       mobileactivation_error_t ret = mobileactivation_send_command(client, 
"CreateTunnel1ActivationInfoRequest", data, &result);
+       plist_free(data);
+       if (ret == MOBILEACTIVATION_E_SUCCESS) {
+               plist_t node = plist_dict_get_item(result, "Value");
+               if (!node) {
+                       debug_info("ERROR: CreateTunnel1ActivationInfoRequest 
command returned success but has no value in reply");
+                       ret = MOBILEACTIVATION_E_UNKNOWN_ERROR;
+               } else {
+                       *info = plist_copy(node);
+               }
+       }
+       plist_free(result);
+       result = NULL;
+
+       return ret;     
+}
+
+LIBIMOBILEDEVICE_API mobileactivation_error_t 
mobileactivation_activate(mobileactivation_client_t client, plist_t 
activation_record)
+{
+       if (!client || !activation_record)
+               return MOBILEACTIVATION_E_INVALID_ARG;
+
+       plist_t result = NULL;
+       mobileactivation_error_t ret = mobileactivation_send_command(client, 
"HandleActivationInfoRequest", activation_record, &result);
+       plist_free(result);
+       result = NULL;
+
+       return ret;
+}
+
+LIBIMOBILEDEVICE_API mobileactivation_error_t 
mobileactivation_activate_with_session(mobileactivation_client_t client, 
plist_t activation_record, plist_t headers)
+{
+       if (!client || !activation_record)
+               return MOBILEACTIVATION_E_INVALID_ARG;
+
+       plist_t result = NULL;
+
+       plist_t dict = plist_new_dict();
+       plist_dict_set_item(dict, "Command", 
plist_new_string("HandleActivationInfoWithSessionRequest"));
+       plist_dict_set_item(dict, "Value", 
plist_data_from_plist(activation_record));
+       if (headers) {
+               plist_dict_set_item(dict, "ActivationResponseHeaders", 
plist_copy(headers));
+       }
+
+       mobileactivation_error_t ret = 
mobileactivation_send_command_plist(client, dict, &result);
+       plist_free(dict);
+       plist_free(result);
+       result = NULL;
+
+       return ret;
+}
+
+
+LIBIMOBILEDEVICE_API mobileactivation_error_t 
mobileactivation_deactivate(mobileactivation_client_t client)
+{
+       if (!client)
+               return MOBILEACTIVATION_E_INVALID_ARG;
+
+       plist_t result = NULL;
+       mobileactivation_error_t ret = mobileactivation_send_command(client, 
"DeactivateRequest", NULL, &result);
+       plist_free(result);
+       result = NULL;
+
+       return ret;
+}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/libimobiledevice-1.2.0+git20170122.45fda81/src/mobileactivation.h 
new/libimobiledevice-1.2.0+git20180427.26373b3/src/mobileactivation.h
--- old/libimobiledevice-1.2.0+git20170122.45fda81/src/mobileactivation.h       
1970-01-01 01:00:00.000000000 +0100
+++ new/libimobiledevice-1.2.0+git20180427.26373b3/src/mobileactivation.h       
2018-04-27 19:24:36.000000000 +0200
@@ -0,0 +1,32 @@
+/*
+ * mobileactivation.h
+ * com.apple.mobileactivationd service header file.
+ *
+ * Copyright (c) 2016 Nikias Bassen, All Rights Reserved.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  
USA
+ */
+
+#ifndef __MOBILEACTIVATION_H
+#define __MOBILEACTIVATION_H
+
+#include "libimobiledevice/mobileactivation.h"
+#include "property_list_service.h"
+
+struct mobileactivation_client_private {
+       property_list_service_client_t parent;
+};
+
+#endif
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/libimobiledevice-1.2.0+git20170122.45fda81/src/property_list_service.c 
new/libimobiledevice-1.2.0+git20180427.26373b3/src/property_list_service.c
--- old/libimobiledevice-1.2.0+git20170122.45fda81/src/property_list_service.c  
2017-01-22 13:28:45.563033669 +0100
+++ new/libimobiledevice-1.2.0+git20180427.26373b3/src/property_list_service.c  
2018-04-27 19:24:36.000000000 +0200
@@ -98,7 +98,8 @@
  * @return PROPERTY_LIST_SERVICE_E_SUCCESS on success,
  *      PROPERTY_LIST_SERVICE_E_INVALID_ARG when one or more parameters are
  *      invalid, PROPERTY_LIST_SERVICE_E_PLIST_ERROR when dict is not a valid
- *      plist, or PROPERTY_LIST_SERVICE_E_UNKNOWN_ERROR when an unspecified
+ *      plist, PROPERTY_LIST_SERVICE_E_MUX_ERROR when a communication error
+ *      occurs, or PROPERTY_LIST_SERVICE_E_UNKNOWN_ERROR when an unspecified
  *      error occurs.
  */
 static property_list_service_error_t 
internal_plist_send(property_list_service_client_t client, plist_t plist, int 
binary)
@@ -140,6 +141,7 @@
        }
        if (bytes <= 0) {
                debug_info("ERROR: sending to device failed.");
+               res = PROPERTY_LIST_SERVICE_E_MUX_ERROR;
        }
 
        free(content);
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/libimobiledevice-1.2.0+git20170122.45fda81/tools/idevicediagnostics.c 
new/libimobiledevice-1.2.0+git20180427.26373b3/tools/idevicediagnostics.c
--- old/libimobiledevice-1.2.0+git20170122.45fda81/tools/idevicediagnostics.c   
2017-01-22 13:28:45.563033669 +0100
+++ new/libimobiledevice-1.2.0+git20180427.26373b3/tools/idevicediagnostics.c   
2018-04-27 19:24:36.000000000 +0200
@@ -40,7 +40,8 @@
        CMD_SHUTDOWN,
        CMD_DIAGNOSTICS,
        CMD_MOBILEGESTALT,
-       CMD_IOREGISTRY
+       CMD_IOREGISTRY,
+       CMD_IOREGISTRY_ENTRY
 };
 
 static void print_xml(plist_t node)
@@ -104,7 +105,7 @@
                        cmd = CMD_DIAGNOSTICS;
                        /*  read type */
                        i++;
-                       if (!argv[i] || ((strcmp(argv[i], "All") != 0) && 
(strcmp(argv[i], "WiFi") != 0) && (strcmp(argv[i], "GasGauge") != 0) && 
(strcmp(argv[i], "NAND") != 0))) {
+                       if (!argv[i] || ((strcmp(argv[i], "All") != 0) && 
(strcmp(argv[i], "WiFi") != 0) && (strcmp(argv[i], "GasGauge") != 0) && 
(strcmp(argv[i], "NAND") != 0) && (strcmp(argv[i], "HDMI") != 0))) {
                                if (argv[i] == NULL) {
                                        cmd_arg = strdup("All");
                                        continue;
@@ -156,6 +157,15 @@
                        }
                        continue;
                }
+               else if (!strcmp(argv[i], "ioregentry")) {
+                       cmd = CMD_IOREGISTRY_ENTRY;
+                       /* read key */
+                       i++;
+                       if (argv[i]) {
+                               cmd_arg = strdup(argv[i]);
+                       }
+                       continue;
+               }
                else {
                        print_usage(argc, argv);
                        return 0;
@@ -232,6 +242,16 @@
                                                printf("Unable to query 
mobilegestalt keys.\n");
                                        }
                                break;
+                               case CMD_IOREGISTRY_ENTRY:
+                                       if 
(diagnostics_relay_query_ioregistry_entry(diagnostics_client, cmd_arg == NULL ? 
"": cmd_arg, "", &node) == DIAGNOSTICS_RELAY_E_SUCCESS) {
+                                               if (node) {
+                                                       print_xml(node);
+                                                       result = EXIT_SUCCESS;
+                                               }
+                                       } else {
+                                               printf("Unable to retrieve 
IORegistry from device.\n");
+                                       }
+                                       break;
                                case CMD_IOREGISTRY:
                                        if 
(diagnostics_relay_query_ioregistry_plane(diagnostics_client, cmd_arg == NULL ? 
"": cmd_arg, &node) == DIAGNOSTICS_RELAY_E_SUCCESS) {
                                                if (node) {
@@ -292,6 +312,7 @@
        printf("  diagnostics [TYPE]\t\tprint diagnostics information from 
device by TYPE (All, WiFi, GasGauge, NAND)\n");
        printf("  mobilegestalt KEY [...]\tprint mobilegestalt keys passed as 
arguments seperated by a space.\n");
        printf("  ioreg [PLANE]\t\t\tprint IORegistry of device, optionally by 
PLANE (IODeviceTree, IOPower, IOService) (iOS 5+ only)\n");
+       printf("  ioregentry [KEY]\t\tprint IORegistry entry of device 
(AppleARMPMUCharger, ASPStorage, ...) (iOS 5+ only)\n");
        printf("  shutdown\t\t\tshutdown device\n");
        printf("  restart\t\t\trestart device\n");
        printf("  sleep\t\t\t\tput device into sleep mode (disconnects from 
host)\n\n");
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/libimobiledevice-1.2.0+git20170122.45fda81/tools/idevicescreenshot.c 
new/libimobiledevice-1.2.0+git20180427.26373b3/tools/idevicescreenshot.c
--- old/libimobiledevice-1.2.0+git20170122.45fda81/tools/idevicescreenshot.c    
2017-01-22 13:28:45.567033669 +0100
+++ new/libimobiledevice-1.2.0+git20180427.26373b3/tools/idevicescreenshot.c    
2018-04-27 19:24:36.000000000 +0200
@@ -99,12 +99,22 @@
                } else {
                        char *imgdata = NULL;
                        uint64_t imgsize = 0;
-                       if (!filename) {
-                               time_t now = time(NULL);
-                               filename = (char*)malloc(36);
-                               strftime(filename, 36, 
"screenshot-%Y-%m-%d-%H-%M-%S.tiff", gmtime(&now));
-                       }
                        if (screenshotr_take_screenshot(shotr, &imgdata, 
&imgsize) == SCREENSHOTR_E_SUCCESS) {
+                               if (!filename) {
+                                       const char *fileext = NULL;
+                                       if (memcmp(imgdata, "\x89PNG", 4) == 0) 
{
+                                               fileext = ".png";
+                                       } else if (memcmp(imgdata, "MM\x00*", 
4) == 0) {
+                                               fileext = ".tiff";
+                                       } else {
+                                               printf("WARNING: screenshot 
data has unexpected image format.\n");
+                                               fileext = ".dat";
+                                       }
+                                       time_t now = time(NULL);
+                                       filename = (char*)malloc(36);
+                                       size_t pos = strftime(filename, 36, 
"screenshot-%Y-%m-%d-%H-%M-%S", gmtime(&now));
+                                       sprintf(filename+pos, "%s", fileext);
+                               }
                                FILE *f = fopen(filename, "wb");
                                if (f) {
                                        if (fwrite(imgdata, 1, (size_t)imgsize, 
f) == (size_t)imgsize) {
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/libimobiledevice-1.2.0+git20170122.45fda81/tools/idevicesyslog.c 
new/libimobiledevice-1.2.0+git20180427.26373b3/tools/idevicesyslog.c
--- old/libimobiledevice-1.2.0+git20170122.45fda81/tools/idevicesyslog.c        
2017-01-22 13:28:45.567033669 +0100
+++ new/libimobiledevice-1.2.0+git20180427.26373b3/tools/idevicesyslog.c        
2018-04-27 19:24:36.000000000 +0200
@@ -63,9 +63,40 @@
                return -1;
        }
 
-       /* start and connect to syslog_relay service */
+       lockdownd_client_t lockdown = NULL;
+       lockdownd_error_t lerr = lockdownd_client_new_with_handshake(device, 
&lockdown, "idevicesyslog");
+       if (lerr != LOCKDOWN_E_SUCCESS) {
+               fprintf(stderr, "ERROR: Could not connect to lockdownd: %d\n", 
lerr);
+               idevice_free(device);
+               device = NULL;
+               return -1;
+       }
+
+       /* start syslog_relay service */
+       lockdownd_service_descriptor_t svc = NULL;
+       lerr = lockdownd_start_service(lockdown, SYSLOG_RELAY_SERVICE_NAME, 
&svc);
+       if (lerr == LOCKDOWN_E_PASSWORD_PROTECTED) {
+               fprintf(stderr, "*** Device is passcode protected, enter 
passcode on the device to continue ***\n");
+               while (1) {
+                       lerr = lockdownd_start_service(lockdown, 
SYSLOG_RELAY_SERVICE_NAME, &svc);
+                       if (lerr != LOCKDOWN_E_PASSWORD_PROTECTED) {
+                               break;
+                       }
+                       sleep(1);
+               }
+       }
+       if (lerr != LOCKDOWN_E_SUCCESS) {
+               fprintf(stderr, "ERROR: Could not connect to lockdownd: %d\n", 
lerr);
+               idevice_free(device);
+               device = NULL;
+               return -1;
+       }
+       lockdownd_client_free(lockdown);
+
+       /* connect to syslog_relay service */
        syslog_relay_error_t serr = SYSLOG_RELAY_E_UNKNOWN_ERROR;
-       serr = syslog_relay_client_start_service(device, &syslog, 
"idevicesyslog");
+       serr = syslog_relay_client_new(device, svc, &syslog);
+       lockdownd_service_descriptor_free(svc);
        if (serr != SYSLOG_RELAY_E_SUCCESS) {
                fprintf(stderr, "ERROR: Could not start service 
com.apple.syslog_relay.\n");
                idevice_free(device);


Reply via email to