summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--.github/workflows/build.yml14
-rw-r--r--3rd_party/ed25519/Makefile.am2
-rw-r--r--3rd_party/ed25519/seed.c2
-rw-r--r--3rd_party/libsrp6a-sha512/Makefile.am12
-rw-r--r--3rd_party/libsrp6a-sha512/t_conv.c35
-rw-r--r--3rd_party/libsrp6a-sha512/t_math.c111
-rw-r--r--3rd_party/libsrp6a-sha512/t_misc.c21
-rw-r--r--3rd_party/libsrp6a-sha512/t_sha.c40
-rw-r--r--3rd_party/libsrp6a-sha512/t_sha.h24
-rw-r--r--3rd_party/libsrp6a-sha512/t_truerand.c3
-rw-r--r--common/Makefile.am18
-rw-r--r--common/debug.c4
-rw-r--r--common/userpref.c27
-rw-r--r--configure.ac2
-rw-r--r--cython/Makefile.am16
-rw-r--r--docs/Makefile.am1
-rw-r--r--docs/idevicedevmodectl.158
-rwxr-xr-xgit-version-gen1
-rw-r--r--src/Makefile.am14
-rw-r--r--src/idevice.c124
-rw-r--r--src/installation_proxy.c2
-rw-r--r--src/lockdown-cu.c2
-rw-r--r--src/lockdown.c54
-rw-r--r--src/mobilebackup.c20
-rw-r--r--src/restore.c2
-rw-r--r--src/reverse_proxy.c10
-rw-r--r--tools/Makefile.am11
-rw-r--r--tools/idevicebackup.c41
-rw-r--r--tools/idevicebackup2.c10
-rw-r--r--tools/idevicecrashreport.c4
-rw-r--r--tools/idevicedebug.c5
-rw-r--r--tools/idevicedevmodectl.c452
-rw-r--r--tools/ideviceimagemounter.c55
-rw-r--r--tools/ideviceinfo.c6
-rw-r--r--tools/idevicepair.c5
-rw-r--r--tools/ideviceprovision.c4
36 files changed, 896 insertions, 316 deletions
diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml
index 7aee501..b13cfc1 100644
--- a/.github/workflows/build.yml
+++ b/.github/workflows/build.yml
@@ -12,7 +12,7 @@ jobs:
- name: install dependencies
run: |
sudo apt-get update
- sudo apt-get install cython
+ sudo apt-get install cython3
- name: prepare environment
run: |
echo "target_triplet=`gcc -dumpmachine`" >> $GITHUB_ENV
@@ -45,7 +45,7 @@ jobs:
done
sudo cp -r extract/* /
sudo ldconfig
- - uses: actions/checkout@v2
+ - uses: actions/checkout@v3
with:
fetch-depth: 0
- name: autogen
@@ -60,7 +60,7 @@ jobs:
DESTDIR=`pwd`/dest make install
tar -C dest -cf libimobiledevice.tar usr
- name: publish artifact
- uses: actions/upload-artifact@v2
+ uses: actions/upload-artifact@v3
with:
name: libimobiledevice-latest_${{env.target_triplet}}
path: libimobiledevice.tar
@@ -104,7 +104,7 @@ jobs:
tar -C extract -xvf $I
done
sudo cp -r extract/* /
- - uses: actions/checkout@v2
+ - uses: actions/checkout@v3
- name: install additional requirements
run: |
mkdir -p lib
@@ -146,7 +146,7 @@ jobs:
DESTDIR=`pwd`/dest make install
tar -C dest -cf libimobiledevice.tar usr
- name: publish artifact
- uses: actions/upload-artifact@v2
+ uses: actions/upload-artifact@v3
with:
name: libimobiledevice-latest_macOS
path: libimobiledevice.tar
@@ -210,7 +210,7 @@ jobs:
tar -C extract -xvf $I
done
cp -r extract/* /
- - uses: actions/checkout@v2
+ - uses: actions/checkout@v3
- name: autogen
run: ./autogen.sh CC=gcc CXX=g++ --enable-debug
- name: make
@@ -223,7 +223,7 @@ jobs:
DESTDIR=`pwd`/dest make install
tar -C dest -cf libimobiledevice.tar ${{ env.dest }}
- name: publish artifact
- uses: actions/upload-artifact@v2
+ uses: actions/upload-artifact@v3
with:
name: libimobiledevice-latest_${{ matrix.arch }}-${{ env.dest }}
path: libimobiledevice.tar
diff --git a/3rd_party/ed25519/Makefile.am b/3rd_party/ed25519/Makefile.am
index c475331..d8e4e04 100644
--- a/3rd_party/ed25519/Makefile.am
+++ b/3rd_party/ed25519/Makefile.am
@@ -6,7 +6,7 @@ AM_CPPFLAGS = \
AM_CFLAGS = \
$(GLOBAL_CFLAGS) \
- $(openssl_CFLAGS)
+ $(ssl_lib_CFLAGS)
AM_LDFLAGS =
diff --git a/3rd_party/ed25519/seed.c b/3rd_party/ed25519/seed.c
index 11a2e3e..cf252b8 100644
--- a/3rd_party/ed25519/seed.c
+++ b/3rd_party/ed25519/seed.c
@@ -30,7 +30,7 @@ int ed25519_create_seed(unsigned char *seed) {
return 1;
}
- fread(seed, 1, 32, f);
+ if(fread(seed, 1, 32, f)){}
fclose(f);
#endif
diff --git a/3rd_party/libsrp6a-sha512/Makefile.am b/3rd_party/libsrp6a-sha512/Makefile.am
index d304585..2acd582 100644
--- a/3rd_party/libsrp6a-sha512/Makefile.am
+++ b/3rd_party/libsrp6a-sha512/Makefile.am
@@ -5,8 +5,6 @@ AM_CPPFLAGS = \
-I$(top_srcdir) \
-Wno-incompatible-pointer-types
-include_HEADERS = srp.h srp_aux.h cstr.h
-
AM_CFLAGS = -DHAVE_CONFIG_H
if HAVE_OPENSSL
AM_CFLAGS += -DOPENSSL=1 $(openssl_CFLAGS)
@@ -25,7 +23,9 @@ noinst_LTLIBRARIES = libsrp6a-sha512.la
libsrp6a_sha512_la_SOURCES = \
t_conv.c t_math.c t_misc.c \
t_truerand.c cstr.c \
- srp.c srp6a_sha512_client.c
-if !HAVE_OPENSSL
-libsrp6a_sha512_la_SOURCES += t_sha.c
-endif
+ srp.c srp6a_sha512_client.c \
+ srp.h srp_aux.h cstr.h \
+ t_sha.c
+#if !HAVE_OPENSSL
+#libsrp6a_sha512_la_SOURCES += t_sha.c
+#endif
diff --git a/3rd_party/libsrp6a-sha512/t_conv.c b/3rd_party/libsrp6a-sha512/t_conv.c
index f7f50e2..76d4e58 100644
--- a/3rd_party/libsrp6a-sha512/t_conv.c
+++ b/3rd_party/libsrp6a-sha512/t_conv.c
@@ -33,8 +33,7 @@
#include "cstr.h"
static int
-hexDigitToInt(c)
- char c;
+hexDigitToInt(char c)
{
if(c >= '0' && c <= '9')
return c - '0';
@@ -50,9 +49,7 @@ hexDigitToInt(c)
* Convert a hex string to a string of bytes; return size of dst
*/
_TYPE( int )
-t_fromhex(dst, src)
- char * dst;
- const char * src;
+t_fromhex(char *dst, const char *src)
{
register char *chp = dst;
register unsigned size = strlen(src);
@@ -76,10 +73,7 @@ t_fromhex(dst, src)
* Convert a string of bytes to their hex representation
*/
_TYPE( char * )
-t_tohex(dst, src, size)
- char * dst;
- const char * src;
- unsigned size;
+t_tohex(char *dst, const char *src, unsigned size)
{
int notleading = 0;
@@ -103,10 +97,7 @@ t_tohex(dst, src, size)
}
_TYPE( char * )
-t_tohexcstr(dst, src, size)
- cstr * dst;
- const char * src;
- unsigned size;
+t_tohexcstr(cstr *dst, const char *src, unsigned size)
{
cstr_set_length(dst, 2 * size + 1);
return t_tohex(dst->data, src, size);
@@ -119,9 +110,7 @@ static char b64table[] =
* Convert a base64 string into raw byte array representation.
*/
_TYPE( int )
-t_fromb64(dst, src)
- char * dst;
- const char * src;
+t_fromb64(char *dst, const char *src)
{
unsigned char *a;
char *loc;
@@ -179,9 +168,7 @@ t_fromb64(dst, src)
}
_TYPE( int )
-t_cstrfromb64(dst, src)
- cstr * dst;
- const char * src;
+t_cstrfromb64(cstr *dst, const char *src)
{
int len;
cstr_set_length(dst, (strlen(src) * 6 + 7) / 8);
@@ -194,10 +181,7 @@ t_cstrfromb64(dst, src)
* Convert a raw byte string into a null-terminated base64 ASCII string.
*/
_TYPE( char * )
-t_tob64(dst, src, size)
- char * dst;
- const char * src;
- unsigned size;
+t_tob64(char *dst, const char *src, unsigned size)
{
int c, pos = size % 3;
unsigned char b0 = 0, b1 = 0, b2 = 0, notleading = 0;
@@ -248,10 +232,7 @@ t_tob64(dst, src, size)
}
_TYPE( char * )
-t_tob64cstr(dst, src, sz)
- cstr * dst;
- const char * src;
- unsigned int sz;
+t_tob64cstr(cstr *dst, const char *src, unsigned int sz)
{
cstr_set_length(dst, (sz * 8 + 5) / 6 + 1);
return t_tob64(dst->data, src, sz);
diff --git a/3rd_party/libsrp6a-sha512/t_math.c b/3rd_party/libsrp6a-sha512/t_math.c
index e655daa..037650e 100644
--- a/3rd_party/libsrp6a-sha512/t_math.c
+++ b/3rd_party/libsrp6a-sha512/t_math.c
@@ -39,11 +39,13 @@ typedef BIGNUM * BigInteger;
typedef BN_CTX * BigIntegerCtx;
typedef BN_MONT_CTX * BigIntegerModAccel;
#include <limits.h>
+#if OPENSSL_VERSION_NUMBER < 0x30000000L
# ifndef OPENSSL_NO_ENGINE
# define OPENSSL_ENGINE
# include "openssl/engine.h"
static ENGINE * default_engine = NULL;
# endif /* OPENSSL_ENGINE */
+#endif
typedef int (*modexp_meth)(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *mctx);
static modexp_meth default_modexp = NULL;
@@ -99,8 +101,7 @@ typedef void * BigIntegerModAccel;
/* Math library interface stubs */
BigInteger
-BigIntegerFromInt(n)
- unsigned int n;
+BigIntegerFromInt(unsigned int n)
{
#ifdef OPENSSL
BIGNUM * a = BN_new();
@@ -136,9 +137,7 @@ BigIntegerFromInt(n)
}
BigInteger
-BigIntegerFromBytes(bytes, length)
- const unsigned char * bytes;
- int length;
+BigIntegerFromBytes(const unsigned char *bytes, int length)
{
#ifdef OPENSSL
BIGNUM * a = BN_new();
@@ -206,10 +205,7 @@ BigIntegerFromBytes(bytes, length)
}
int
-BigIntegerToBytes(src, dest, destlen)
- BigInteger src;
- unsigned char * dest;
- int destlen;
+BigIntegerToBytes(BigInteger src, unsigned char *dest, int destlen)
{
#ifdef OPENSSL
return BN_bn2bin(src, dest);
@@ -290,10 +286,7 @@ BigIntegerToCstrEx(BigInteger x, cstr * out, int len)
}
BigIntegerResult
-BigIntegerToHex(src, dest, destlen)
- BigInteger src;
- char * dest;
- int destlen;
+BigIntegerToHex(BigInteger src, char *dest, int destlen)
{
#ifdef OPENSSL
strncpy(dest, BN_bn2hex(src), destlen);
@@ -317,11 +310,7 @@ static char b64table[] =
"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz./";
BigIntegerResult
-BigIntegerToString(src, dest, destlen, radix)
- BigInteger src;
- char * dest;
- int destlen;
- unsigned int radix;
+BigIntegerToString(BigInteger src, char *dest, int destlen, unsigned int radix)
{
BigInteger t = BigIntegerFromInt(0);
char * p = dest;
@@ -345,8 +334,7 @@ BigIntegerToString(src, dest, destlen, radix)
}
int
-BigIntegerBitLen(b)
- BigInteger b;
+BigIntegerBitLen(BigInteger b)
{
#ifdef OPENSSL
return BN_num_bits(b);
@@ -364,8 +352,7 @@ BigIntegerBitLen(b)
}
int
-BigIntegerCmp(c1, c2)
- BigInteger c1, c2;
+BigIntegerCmp(BigInteger c1, BigInteger c2)
{
#ifdef OPENSSL
return BN_cmp(c1, c2);
@@ -383,9 +370,7 @@ BigIntegerCmp(c1, c2)
}
int
-BigIntegerCmpInt(c1, c2)
- BigInteger c1;
- unsigned int c2;
+BigIntegerCmpInt(BigInteger c1, unsigned int c2)
{
#ifdef OPENSSL
BigInteger bc2 = BigIntegerFromInt(c2);
@@ -414,9 +399,7 @@ BigIntegerCmpInt(c1, c2)
}
BigIntegerResult
-BigIntegerLShift(result, x, bits)
- BigInteger result, x;
- unsigned int bits;
+BigIntegerLShift(BigInteger result, BigInteger x, unsigned int bits)
{
#ifdef OPENSSL
BN_lshift(result, x, bits);
@@ -436,8 +419,7 @@ BigIntegerLShift(result, x, bits)
}
BigIntegerResult
-BigIntegerAdd(result, a1, a2)
- BigInteger result, a1, a2;
+BigIntegerAdd(BigInteger result, BigInteger a1, BigInteger a2)
{
#ifdef OPENSSL
BN_add(result, a1, a2);
@@ -456,9 +438,7 @@ BigIntegerAdd(result, a1, a2)
}
BigIntegerResult
-BigIntegerAddInt(result, a1, a2)
- BigInteger result, a1;
- unsigned int a2;
+BigIntegerAddInt(BigInteger result, BigInteger a1, unsigned int a2)
{
#ifdef OPENSSL
if(result != a1)
@@ -483,8 +463,7 @@ BigIntegerAddInt(result, a1, a2)
}
BigIntegerResult
-BigIntegerSub(result, s1, s2)
- BigInteger result, s1, s2;
+BigIntegerSub(BigInteger result, BigInteger s1, BigInteger s2)
{
#ifdef OPENSSL
BN_sub(result, s1, s2);
@@ -503,9 +482,7 @@ BigIntegerSub(result, s1, s2)
}
BigIntegerResult
-BigIntegerSubInt(result, s1, s2)
- BigInteger result, s1;
- unsigned int s2;
+BigIntegerSubInt(BigInteger result, BigInteger s1, unsigned int s2)
{
#ifdef OPENSSL
if(result != s1)
@@ -530,9 +507,7 @@ BigIntegerSubInt(result, s1, s2)
}
BigIntegerResult
-BigIntegerMul(result, m1, m2, c)
- BigInteger result, m1, m2;
- BigIntegerCtx c;
+BigIntegerMul(BigInteger result, BigInteger m1, BigInteger m2, BigIntegerCtx c)
{
#ifdef OPENSSL
BN_CTX * ctx = NULL;
@@ -556,10 +531,7 @@ BigIntegerMul(result, m1, m2, c)
}
BigIntegerResult
-BigIntegerMulInt(result, m1, m2, c)
- BigInteger result, m1;
- unsigned int m2;
- BigIntegerCtx c;
+BigIntegerMulInt(BigInteger result, BigInteger m1, unsigned int m2, BigIntegerCtx c)
{
#ifdef OPENSSL
if(result != m1)
@@ -584,10 +556,7 @@ BigIntegerMulInt(result, m1, m2, c)
}
BigIntegerResult
-BigIntegerDivInt(result, d, m, c)
- BigInteger result, d;
- unsigned int m;
- BigIntegerCtx c;
+BigIntegerDivInt(BigInteger result, BigInteger d, unsigned int m, BigIntegerCtx c)
{
#ifdef OPENSSL
if(result != d)
@@ -624,9 +593,7 @@ BigIntegerDivInt(result, d, m, c)
}
BigIntegerResult
-BigIntegerMod(result, d, m, c)
- BigInteger result, d, m;
- BigIntegerCtx c;
+BigIntegerMod(BigInteger result, BigInteger d, BigInteger m, BigIntegerCtx c)
{
#ifdef OPENSSL
BN_CTX * ctx = NULL;
@@ -650,10 +617,7 @@ BigIntegerMod(result, d, m, c)
}
unsigned int
-BigIntegerModInt(d, m, c)
- BigInteger d;
- unsigned int m;
- BigIntegerCtx c;
+BigIntegerModInt(BigInteger d, unsigned int m, BigIntegerCtx c)
{
#ifdef OPENSSL
return BN_mod_word(d, m);
@@ -711,9 +675,7 @@ BigIntegerModInt(d, m, c)
}
BigIntegerResult
-BigIntegerModMul(r, m1, m2, modulus, c)
- BigInteger r, m1, m2, modulus;
- BigIntegerCtx c;
+BigIntegerModMul(BigInteger r, BigInteger m1, BigInteger m2, BigInteger modulus, BigIntegerCtx c)
{
#ifdef OPENSSL
BN_CTX * ctx = NULL;
@@ -743,10 +705,7 @@ BigIntegerModMul(r, m1, m2, modulus, c)
}
BigIntegerResult
-BigIntegerModExp(r, b, e, m, c, a)
- BigInteger r, b, e, m;
- BigIntegerCtx c;
- BigIntegerModAccel a;
+BigIntegerModExp(BigInteger r, BigInteger b, BigInteger e, BigInteger m, BigIntegerCtx c, BigIntegerModAccel a)
{
#ifdef OPENSSL
#if OPENSSL_VERSION_NUMBER >= 0x00906000
@@ -793,9 +752,7 @@ int _mbedtls_f_rng(void* unused, unsigned char *buf, size_t size)
#endif
int
-BigIntegerCheckPrime(n, c)
- BigInteger n;
- BigIntegerCtx c;
+BigIntegerCheckPrime(BigInteger n, BigIntegerCtx c)
{
#ifdef OPENSSL
int rv;
@@ -803,7 +760,11 @@ BigIntegerCheckPrime(n, c)
if(c == NULL)
c = ctx = BN_CTX_new();
#if OPENSSL_VERSION_NUMBER >= 0x00908000
- rv = BN_is_prime_ex(n, 25, c, NULL);
+ #if OPENSSL_VERSION_NUMBER >= 0x30000000L
+ rv = BN_check_prime(n, c, NULL);
+ #else
+ rv = BN_is_prime_ex(n, 25, c, NULL);
+ #endif
#else
rv = BN_is_prime(n, 25, NULL, c, NULL);
#endif
@@ -846,8 +807,7 @@ BigIntegerCheckPrime(n, c)
}
BigIntegerResult
-BigIntegerFree(b)
- BigInteger b;
+BigIntegerFree(BigInteger b)
{
#ifdef OPENSSL
BN_free(b);
@@ -869,8 +829,7 @@ BigIntegerFree(b)
}
BigIntegerResult
-BigIntegerClearFree(b)
- BigInteger b;
+BigIntegerClearFree(BigInteger b)
{
#ifdef OPENSSL
BN_clear_free(b);
@@ -906,8 +865,7 @@ BigIntegerCtxNew()
}
BigIntegerResult
-BigIntegerCtxFree(ctx)
- BigIntegerCtx ctx;
+BigIntegerCtxFree(BigIntegerCtx ctx)
{
#ifdef OPENSSL
if(ctx)
@@ -917,9 +875,7 @@ BigIntegerCtxFree(ctx)
}
BigIntegerModAccel
-BigIntegerModAccelNew(m, c)
- BigInteger m;
- BigIntegerCtx c;
+BigIntegerModAccelNew(BigInteger m, BigIntegerCtx c)
{
#ifdef OPENSSL
BN_CTX * ctx = NULL;
@@ -939,8 +895,7 @@ BigIntegerModAccelNew(m, c)
}
BigIntegerResult
-BigIntegerModAccelFree(accel)
- BigIntegerModAccel accel;
+BigIntegerModAccelFree(BigIntegerModAccel accel)
{
#ifdef OPENSSL
if(accel)
diff --git a/3rd_party/libsrp6a-sha512/t_misc.c b/3rd_party/libsrp6a-sha512/t_misc.c
index 3053358..3a2cda1 100644
--- a/3rd_party/libsrp6a-sha512/t_misc.c
+++ b/3rd_party/libsrp6a-sha512/t_misc.c
@@ -80,8 +80,7 @@ SHA1_CTX randctxt;
extern char ** environ;
static void
-t_envhash(out)
- unsigned char * out;
+t_envhash(unsigned char * out)
{
char ** ptr;
char ebuf[256];
@@ -115,8 +114,7 @@ t_envhash(out)
* The entire buffer is run once through SHA to obtain the final result.
*/
static void
-t_fshash(out)
- unsigned char * out;
+t_fshash(unsigned char * out)
{
char dotpath[128];
struct stat st;
@@ -317,9 +315,7 @@ t_stronginitrand()
* Each cycle generates 20 bytes of new output.
*/
_TYPE( void )
-t_random(data, size)
- unsigned char * data;
- unsigned size;
+t_random(unsigned char * data, unsigned size)
{
if(!initialized)
t_initrand();
@@ -369,10 +365,7 @@ t_random(data, size)
* single 320-bit value.
*/
_TYPE( unsigned char * )
-t_sessionkey(key, sk, sklen)
- unsigned char * key;
- unsigned char * sk;
- unsigned sklen;
+t_sessionkey(unsigned char * key, unsigned char * sk, unsigned sklen)
{
unsigned i, klen;
unsigned char * hbuf;
@@ -411,11 +404,7 @@ t_sessionkey(key, sk, sklen)
}
_TYPE( void )
-t_mgf1(mask, masklen, seed, seedlen)
- unsigned char * mask;
- unsigned masklen;
- const unsigned char * seed;
- unsigned seedlen;
+t_mgf1(unsigned char * mask, unsigned masklen, const unsigned char * seed, unsigned seedlen)
{
SHA1_CTX ctxt;
unsigned i = 0;
diff --git a/3rd_party/libsrp6a-sha512/t_sha.c b/3rd_party/libsrp6a-sha512/t_sha.c
index 4029de8..8e54cb6 100644
--- a/3rd_party/libsrp6a-sha512/t_sha.c
+++ b/3rd_party/libsrp6a-sha512/t_sha.c
@@ -107,6 +107,44 @@ SHA512Final_mbed(unsigned char digest[64], SHA512_CTX * ctx)
mbedtls_md_free(ctx);
}
+#elif defined(OPENSSL_SHA)
+#if OPENSSL_VERSION_NUMBER >= 0x30000000L
+void
+SHA1Init_openssl(SHA1_CTX *ctx)
+{
+ *ctx = EVP_MD_CTX_new();
+ EVP_DigestInit(*ctx, EVP_sha1());
+}
+
+void SHA1Update_openssl(SHA1_CTX *ctx, const void *data, unsigned int len)
+{
+ EVP_DigestUpdate(*ctx, data, (size_t)len);
+}
+
+void SHA1Final_openssl(unsigned char digest[20], SHA1_CTX *ctx)
+{
+ EVP_DigestFinal(*ctx, digest, NULL);
+ EVP_MD_CTX_destroy(*ctx);
+}
+
+void
+SHA512Init_openssl(SHA512_CTX *ctx)
+{
+ *ctx = EVP_MD_CTX_new();
+ EVP_DigestInit(*ctx, EVP_sha512());
+}
+
+void SHA512Update_openssl(SHA512_CTX *ctx, const void *data, unsigned int len)
+{
+ EVP_DigestUpdate(*ctx, data, (size_t)len);
+}
+
+void SHA512Final_openssl(unsigned char digest[64], SHA512_CTX *ctx)
+{
+ EVP_DigestFinal(*ctx, digest, NULL);
+ EVP_MD_CTX_destroy(*ctx);
+}
+#endif
#elif !defined(OPENSSL_SHA) && !defined(TOMCRYPT_SHA)
/* Use the free SHA1 if the library doesn't have it */
@@ -273,4 +311,4 @@ unsigned char finalcount[8];
SHA1Transform(context->state, context->buffer);
#endif
}
-#endif /* OPENSSL */
+#endif
diff --git a/3rd_party/libsrp6a-sha512/t_sha.h b/3rd_party/libsrp6a-sha512/t_sha.h
index 18deec5..2e38067 100644
--- a/3rd_party/libsrp6a-sha512/t_sha.h
+++ b/3rd_party/libsrp6a-sha512/t_sha.h
@@ -38,6 +38,28 @@
#endif
#ifdef OPENSSL_SHA
+#include <openssl/err.h>
+#if OPENSSL_VERSION_NUMBER >= 0x30000000L
+#include <openssl/evp.h>
+
+typedef EVP_MD_CTX* SHA1_CTX;
+#define SHA1Init SHA1Init_openssl
+#define SHA1Update SHA1Update_openssl
+#define SHA1Final SHA1Final_openssl
+
+typedef EVP_MD_CTX* SHA512_CTX;
+#define SHA512Init SHA512Init_openssl
+#define SHA512Update SHA512Update_openssl
+#define SHA512Final SHA512Final_openssl
+
+void SHA1Init_openssl(SHA1_CTX *ctx);
+void SHA1Update_openssl(SHA1_CTX *ctx, const void *data, unsigned int len);
+void SHA1Final_openssl(unsigned char digest[20], SHA1_CTX *ctx);
+
+void SHA512Init_openssl(SHA512_CTX *ctx);
+void SHA512Update_openssl(SHA512_CTX *ctx, const void *data, unsigned int len);
+void SHA512Final_openssl(unsigned char digest[64], SHA1_CTX *ctx);
+#else /* for OpenSSL < 3.0 */
#include <openssl/sha.h>
typedef SHA_CTX SHA1_CTX;
@@ -48,7 +70,7 @@ typedef SHA_CTX SHA1_CTX;
#define SHA512Init SHA512_Init
#define SHA512Update SHA512_Update
#define SHA512Final SHA512_Final
-
+#endif /* for OpenSSL < 3.0 */
#elif defined(TOMCRYPT_SHA)
/* mycrypt.h already included above */
diff --git a/3rd_party/libsrp6a-sha512/t_truerand.c b/3rd_party/libsrp6a-sha512/t_truerand.c
index 4a4c3d2..f995ed7 100644
--- a/3rd_party/libsrp6a-sha512/t_truerand.c
+++ b/3rd_party/libsrp6a-sha512/t_truerand.c
@@ -227,8 +227,7 @@ raw_truerand()
}
int
-raw_n_truerand(n)
-int n;
+raw_n_truerand(int n)
{
int slop, v;
diff --git a/common/Makefile.am b/common/Makefile.am
index 1a90571..bd09bad 100644
--- a/common/Makefile.am
+++ b/common/Makefile.am
@@ -4,22 +4,16 @@ AM_CPPFLAGS = \
AM_CFLAGS = \
$(GLOBAL_CFLAGS) \
+ $(ssl_lib_CFLAGS) \
+ $(LFS_CFLAGS) \
$(libusbmuxd_CFLAGS) \
- $(libplist_CFLAGS) \
- $(libgnutls_CFLAGS) \
- $(libtasn1_CFLAGS) \
- $(libgcrypt_CFLAGS) \
- $(openssl_CFLAGS) \
- $(LFS_CFLAGS)
+ $(libplist_CFLAGS)
AM_LDFLAGS = \
+ $(ssl_lib_LIBS) \
+ ${libpthread_LIBS} \
$(libusbmuxd_LIBS) \
- $(libplist_LIBS) \
- $(libgnutls_LIBS) \
- $(libtasn1_LIBS) \
- $(libgcrypt_LIBS) \
- $(openssl_LIBS) \
- ${libpthread_LIBS}
+ $(libplist_LIBS)
noinst_LTLIBRARIES = libinternalcommon.la
libinternalcommon_la_LIBADD =
diff --git a/common/debug.c b/common/debug.c
index 6212e71..3492eaa 100644
--- a/common/debug.c
+++ b/common/debug.c
@@ -60,7 +60,7 @@ static void debug_print_line(const char *func, const char *file, int line, const
strftime(str_time, 254, "%H:%M:%S", localtime (&the_time));
/* generate header text */
- (void)asprintf(&header, "%s %s:%d %s()", str_time, file, line, func);
+ if(asprintf(&header, "%s %s:%d %s()", str_time, file, line, func)<0){}
free (str_time);
/* trim ending newlines */
@@ -86,7 +86,7 @@ void debug_info_real(const char *func, const char *file, int line, const char *f
/* run the real fprintf */
va_start(args, format);
- (void)vasprintf(&buffer, format, args);
+ if(vasprintf(&buffer, format, args)<0){}
va_end(args);
debug_print_line(func, file, line, buffer);
diff --git a/common/userpref.c b/common/userpref.c
index ddd380a..b64c703 100644
--- a/common/userpref.c
+++ b/common/userpref.c
@@ -338,7 +338,7 @@ userpref_error_t userpref_read_pair_record(const char *udid, plist_t *pair_recor
}
*pair_record = NULL;
- plist_from_memory(record_data, record_size, pair_record);
+ plist_from_memory(record_data, record_size, pair_record, NULL);
free(record_data);
if (!*pair_record) {
@@ -435,6 +435,10 @@ userpref_error_t pair_record_generate_keys_and_certs(plist_t pair_record, key_da
debug_info("Generating keys and certificates...");
#if defined(HAVE_OPENSSL)
+#if OPENSSL_VERSION_NUMBER >= 0x30000000L
+ EVP_PKEY* root_pkey = EVP_RSA_gen(2048);
+ EVP_PKEY* host_pkey = EVP_RSA_gen(2048);
+#else
BIGNUM *e = BN_new();
RSA* root_keypair = RSA_new();
RSA* host_keypair = RSA_new();
@@ -451,6 +455,7 @@ userpref_error_t pair_record_generate_keys_and_certs(plist_t pair_record, key_da
EVP_PKEY* host_pkey = EVP_PKEY_new();
EVP_PKEY_assign_RSA(host_pkey, host_keypair);
+#endif
/* generate root certificate */
X509* root_cert = X509_new();
@@ -561,12 +566,22 @@ userpref_error_t pair_record_generate_keys_and_certs(plist_t pair_record, key_da
}
}
- RSA *pubkey = NULL;
+ EVP_PKEY *pubkey = NULL;
{
BIO *membp = BIO_new_mem_buf(public_key.data, public_key.size);
- if (!PEM_read_bio_RSAPublicKey(membp, &pubkey, NULL, NULL)) {
+#if OPENSSL_VERSION_NUMBER >= 0x30000000L
+ if (!PEM_read_bio_PUBKEY(membp, &pubkey, NULL, NULL)) {
debug_info("WARNING: Could not read public key");
}
+#else
+ RSA *rsa_pubkey = NULL;
+ if (!PEM_read_bio_RSAPublicKey(membp, &rsa_pubkey, NULL, NULL)) {
+ debug_info("WARNING: Could not read public key");
+ } else {
+ pubkey = EVP_PKEY_new();
+ EVP_PKEY_assign_RSA(pubkey, rsa_pubkey);
+ }
+#endif
BIO_free(membp);
}
@@ -588,10 +603,7 @@ userpref_error_t pair_record_generate_keys_and_certs(plist_t pair_record, key_da
X509_set1_notAfter(dev_cert, asn1time);
ASN1_TIME_free(asn1time);
- EVP_PKEY* pkey = EVP_PKEY_new();
- EVP_PKEY_assign_RSA(pkey, pubkey);
- X509_set_pubkey(dev_cert, pkey);
- EVP_PKEY_free(pkey);
+ X509_set_pubkey(dev_cert, pubkey);
X509_add_ext_helper(dev_cert, NID_subject_key_identifier, (char*)"hash");
X509_add_ext_helper(dev_cert, NID_key_usage, (char*)"critical,digitalSignature,keyEncipherment");
@@ -618,6 +630,7 @@ userpref_error_t pair_record_generate_keys_and_certs(plist_t pair_record, key_da
X509V3_EXT_cleanup();
X509_free(dev_cert);
+ EVP_PKEY_free(pubkey);
EVP_PKEY_free(root_pkey);
EVP_PKEY_free(host_pkey);
diff --git a/configure.ac b/configure.ac
index 503051f..8ba094a 100644
--- a/configure.ac
+++ b/configure.ac
@@ -26,7 +26,7 @@ fi
dnl Minimum package versions
LIBUSBMUXD_VERSION=2.0.2
-LIBPLIST_VERSION=2.2.0
+LIBPLIST_VERSION=2.3.0
LIMD_GLUE_VERSION=1.0.0
AC_SUBST(LIBUSBMUXD_VERSION)
diff --git a/cython/Makefile.am b/cython/Makefile.am
index 3577c4e..93ea6ed 100644
--- a/cython/Makefile.am
+++ b/cython/Makefile.am
@@ -3,19 +3,15 @@ AM_CPPFLAGS = \
AM_CFLAGS = \
$(GLOBAL_CFLAGS) \
- $(libgnutls_CFLAGS) \
- $(libtasn1_CFLAGS) \
- $(openssl_CFLAGS) \
- $(libplist_CFLAGS) \
+ $(ssl_lib_CFLAGS) \
$(LFS_CFLAGS) \
- $(PTHREAD_CFLAGS)
+ $(PTHREAD_CFLAGS) \
+ $(libplist_CFLAGS)
AM_LIBS = \
- $(libgnutls_LIBS) \
- $(libtasn1_LIBS) \
- $(openssl_LIBS) \
- $(libplist_LIBS) \
- $(PTHREAD_LIBS)
+ $(ssl_lib_LIBS) \
+ $(PTHREAD_LIBS) \
+ $(libplist_LIBS)
if HAVE_CYTHON
diff --git a/docs/Makefile.am b/docs/Makefile.am
index 9cdf82e..4a4c56f 100644
--- a/docs/Makefile.am
+++ b/docs/Makefile.am
@@ -16,6 +16,7 @@ man_MANS = \
idevicecrashreport.1 \
idevicename.1 \
idevicedebug.1 \
+ idevicedevmodectl.1 \
idevicenotificationproxy.1 \
idevicesetlocation.1
diff --git a/docs/idevicedevmodectl.1 b/docs/idevicedevmodectl.1
new file mode 100644
index 0000000..5edaa80
--- /dev/null
+++ b/docs/idevicedevmodectl.1
@@ -0,0 +1,58 @@
+.TH "idevicedevmodectl" 1
+.SH NAME
+idevicedevmodectl \- Enable Developer Mode on iOS 16+ devices or print the current status.
+.SH SYNOPSIS
+.B idevicedevmodectl
+COMMAND
+[OPTIONS]
+
+.SH DESCRIPTION
+
+Enable Developer Mode on iOS 16+ devices or print the current status.
+
+.SH NOTE
+Passcode-protected devices will NOT allow enabling of Developer Mode from the command line. It has to be enabled on the device itself under Settings -> Privacy & Security -> Developer Mode.
+The \f[B]enable\f[] command will try to enable it, and tell you if that's the case.
+If the menu is not shown, you may use the \f[B]reveal\f[] command to reveal it.
+
+.SH COMMANDS
+.TP
+.B list
+Prints the Developer Mode status of all connected devices, or for a specific one if \f[B]\-\-udid\f[] is given.
+.TP
+.B enable
+Enable Developer Mode (device will reboot), and confirm it after device booted up again.
+.TP
+.B arm
+Arm the Developer Mode (device will reboot)
+.TP
+.B confirm
+Confirm enabling of Developer Mode
+.TP
+.B reveal
+Reveal the Developer Mode menu on the device under Settings -> Privacy & Security
+
+.SH OPTIONS
+.TP
+.B \-u, \-\-udid UDID
+target specific device by UDID
+.TP
+.B \-n, \-\-network
+connect to network device
+.TP
+.B \-d, \-\-debug
+enable communication debugging
+.TP
+.B \-h, \-\-help
+print usage information
+.TP
+.B \-v, \-\-version
+print version information
+
+.SH AUTHORS
+Nikias Bassen
+
+.SH ON THE WEB
+https://libimobiledevice.org
+
+https://github.com/libimobiledevice/libimobiledevice
diff --git a/git-version-gen b/git-version-gen
index f6cb31c..d868952 100755
--- a/git-version-gen
+++ b/git-version-gen
@@ -16,4 +16,5 @@ else
fi
fi
fi
+VER=`printf %s "$VER" | head -n1`
printf %s "$VER"
diff --git a/src/Makefile.am b/src/Makefile.am
index 1c80ed6..58cf07c 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -6,19 +6,19 @@ AM_CPPFLAGS = \
AM_CFLAGS = \
$(GLOBAL_CFLAGS) \
- $(libusbmuxd_CFLAGS) \
- $(libplist_CFLAGS) \
- $(limd_glue_CFLAGS) \
$(ssl_lib_CFLAGS) \
$(LFS_CFLAGS) \
- $(PTHREAD_CFLAGS)
+ $(PTHREAD_CFLAGS) \
+ $(libusbmuxd_CFLAGS) \
+ $(libplist_CFLAGS) \
+ $(limd_glue_CFLAGS)
AM_LDFLAGS = \
+ $(ssl_lib_LIBS) \
+ $(PTHREAD_LIBS) \
$(libusbmuxd_LIBS) \
$(libplist_LIBS) \
- $(limd_glue_LIBS) \
- $(ssl_lib_LIBS) \
- $(PTHREAD_LIBS)
+ $(limd_glue_LIBS)
lib_LTLIBRARIES = libimobiledevice-1.0.la
libimobiledevice_1_0_la_LIBADD = $(top_builddir)/common/libinternalcommon.la
diff --git a/src/idevice.c b/src/idevice.c
index 5930db9..719cd28 100644
--- a/src/idevice.c
+++ b/src/idevice.c
@@ -32,7 +32,11 @@
#ifdef WIN32
#include <winsock2.h>
+#include <ws2tcpip.h>
#include <windows.h>
+#else
+#include <sys/socket.h>
+#include <netinet/in.h>
#endif
#include <usbmuxd.h>
@@ -324,7 +328,21 @@ LIBIMOBILEDEVICE_API idevice_error_t idevice_get_device_list_extended(idevice_in
newlist[newcount]->conn_data = NULL;
} else if (dev_list[i].conn_type == CONNECTION_TYPE_NETWORK) {
newlist[newcount]->conn_type = CONNECTION_NETWORK;
- size_t addrlen = ((uint8_t*)dev_list[i].conn_data)[0];
+ struct sockaddr* saddr = (struct sockaddr*)(dev_list[i].conn_data);
+ size_t addrlen = 0;
+ switch (saddr->sa_family) {
+ case AF_INET:
+ addrlen = sizeof(struct sockaddr_in);
+ break;
+#ifdef AF_INET6
+ case AF_INET6:
+ addrlen = sizeof(struct sockaddr_in6);
+ break;
+#endif
+ default:
+ debug_info("Unsupported address family 0x%02x\n", saddr->sa_family);
+ continue;
+ }
newlist[newcount]->conn_data = malloc(addrlen);
memcpy(newlist[newcount]->conn_data, dev_list[i].conn_data, addrlen);
}
@@ -426,9 +444,25 @@ static idevice_t idevice_from_mux_device(usbmuxd_device_info_t *muxdev)
break;
case CONNECTION_TYPE_NETWORK:
device->conn_type = CONNECTION_NETWORK;
- size_t len = ((uint8_t*)muxdev->conn_data)[0];
- device->conn_data = malloc(len);
- memcpy(device->conn_data, muxdev->conn_data, len);
+ struct sockaddr* saddr = (struct sockaddr*)(muxdev->conn_data);
+ size_t addrlen = 0;
+ switch (saddr->sa_family) {
+ case AF_INET:
+ addrlen = sizeof(struct sockaddr_in);
+ break;
+#ifdef AF_INET6
+ case AF_INET6:
+ addrlen = sizeof(struct sockaddr_in6);
+ break;
+#endif
+ default:
+ debug_info("Unsupported address family 0x%02x\n", saddr->sa_family);
+ free(device->udid);
+ free(device);
+ return NULL;
+ }
+ device->conn_data = malloc(addrlen);
+ memcpy(device->conn_data, muxdev->conn_data, addrlen);
break;
default:
device->conn_type = 0;
@@ -515,27 +549,16 @@ LIBIMOBILEDEVICE_API idevice_error_t idevice_connect(idevice_t device, uint16_t
return IDEVICE_E_SUCCESS;
}
if (device->conn_type == CONNECTION_NETWORK) {
- struct sockaddr_storage saddr_storage;
- struct sockaddr* saddr = (struct sockaddr*)&saddr_storage;
-
- /* FIXME: Improve handling of this platform/host dependent connection data */
- if (((char*)device->conn_data)[1] == 0x02) { // AF_INET
- saddr->sa_family = AF_INET;
- memcpy(&saddr->sa_data[0], (char*)device->conn_data + 2, 14);
- }
- else if (((char*)device->conn_data)[1] == 0x1E) { // AF_INET6 (bsd)
+ struct sockaddr* saddr = (struct sockaddr*)(device->conn_data);
+ switch (saddr->sa_family) {
+ case AF_INET:
#ifdef AF_INET6
- saddr->sa_family = AF_INET6;
- /* copy the address and the host dependent scope id */
- memcpy(&saddr->sa_data[0], (char*)device->conn_data + 2, 26);
-#else
- debug_info("ERROR: Got an IPv6 address but this system doesn't support IPv6");
- return IDEVICE_E_UNKNOWN_ERROR;
+ case AF_INET6:
#endif
- }
- else {
- debug_info("Unsupported address family 0x%02x", ((char*)device->conn_data)[1]);
- return IDEVICE_E_UNKNOWN_ERROR;
+ break;
+ default:
+ debug_info("Unsupported address family 0x%02x", saddr->sa_family);
+ return IDEVICE_E_UNKNOWN_ERROR;
}
char addrtxt[48];
@@ -1034,18 +1057,33 @@ static void internal_ssl_cleanup(ssl_data_t ssl_data)
}
#ifdef HAVE_OPENSSL
+#if OPENSSL_VERSION_NUMBER >= 0x30000000L
+static long ssl_idevice_bio_callback(BIO *b, int oper, const char *argp, size_t len, int argi, long argl, int retvalue, size_t *processed)
+#else
static long ssl_idevice_bio_callback(BIO *b, int oper, const char *argp, int argi, long argl, long retvalue)
+#endif
{
+ ssize_t bytes = 0;
idevice_connection_t conn = (idevice_connection_t)BIO_get_callback_arg(b);
+#if OPENSSL_VERSION_NUMBER < 0x30000000L
size_t len = (size_t)argi;
+ size_t *processed = (size_t*)&bytes;
+#endif
switch (oper) {
case (BIO_CB_READ|BIO_CB_RETURN):
- return argp ? (long)internal_ssl_read(conn, (char *)argp, len) : 0;
+ if (argp) {
+ bytes = internal_ssl_read(conn, (char *)argp, len);
+ *processed = bytes;
+ return (long)bytes;
+ }
+ return 0;
case (BIO_CB_PUTS|BIO_CB_RETURN):
len = strlen(argp);
// fallthrough
case (BIO_CB_WRITE|BIO_CB_RETURN):
- return (long)internal_ssl_write(conn, argp, len);
+ bytes = internal_ssl_write(conn, argp, len);
+ *processed = bytes;
+ return (long)bytes;
default:
return retvalue;
}
@@ -1056,7 +1094,11 @@ static BIO *ssl_idevice_bio_new(idevice_connection_t conn)
BIO *b = BIO_new(BIO_s_null());
if (!b) return NULL;
BIO_set_callback_arg(b, (char *)conn);
+#if OPENSSL_VERSION_NUMBER >= 0x30000000L
+ BIO_set_callback_ex(b, ssl_idevice_bio_callback);
+#else
BIO_set_callback(b, ssl_idevice_bio_callback);
+#endif
return b;
}
@@ -1190,15 +1232,13 @@ LIBIMOBILEDEVICE_API idevice_error_t idevice_connection_enable_ssl(idevice_conne
/* force use of TLSv1 for older devices */
if (connection->device->version < DEVICE_VERSION(10,0,0)) {
#ifdef SSL_OP_NO_TLSv1_1
- long opts = SSL_CTX_get_options(ssl_ctx);
- opts |= SSL_OP_NO_TLSv1_1;
+ SSL_CTX_set_options(ssl_ctx, SSL_OP_NO_TLSv1_1);
+#endif
#ifdef SSL_OP_NO_TLSv1_2
- opts |= SSL_OP_NO_TLSv1_2;
+ SSL_CTX_set_options(ssl_ctx, SSL_OP_NO_TLSv1_2);
#endif
#ifdef SSL_OP_NO_TLSv1_3
- opts |= SSL_OP_NO_TLSv1_3;
-#endif
- SSL_CTX_set_options(ssl_ctx, opts);
+ SSL_CTX_set_options(ssl_ctx, SSL_OP_NO_TLSv1_3);
#endif
}
#else
@@ -1207,7 +1247,8 @@ LIBIMOBILEDEVICE_API idevice_error_t idevice_connection_enable_ssl(idevice_conne
SSL_CTX_set_max_proto_version(ssl_ctx, TLS1_VERSION);
}
#endif
-#if (OPENSSL_VERSION_MAJOR >= 3) && defined(SSL_OP_IGNORE_UNEXPECTED_EOF)
+#if OPENSSL_VERSION_NUMBER >= 0x30000000L
+#if defined(SSL_OP_IGNORE_UNEXPECTED_EOF)
/*
* For OpenSSL 3 and later, mark close_notify alerts as optional.
* For prior versions of OpenSSL we check for SSL_ERROR_SYSCALL when
@@ -1215,6 +1256,14 @@ LIBIMOBILEDEVICE_API idevice_error_t idevice_connection_enable_ssl(idevice_conne
*/
SSL_CTX_set_options(ssl_ctx, SSL_OP_IGNORE_UNEXPECTED_EOF);
#endif
+#if defined(SSL_OP_LEGACY_SERVER_CONNECT)
+ /*
+ * Without setting SSL_OP_LEGACY_SERVER_CONNECT, OpenSSL 3 fails with
+ * error "unsafe legacy renegotiation disabled" when talking to iOS 5
+ */
+ SSL_CTX_set_options(ssl_ctx, SSL_OP_LEGACY_SERVER_CONNECT);
+#endif
+#endif
BIO* membp;
X509* rootCert = NULL;
@@ -1227,6 +1276,16 @@ LIBIMOBILEDEVICE_API idevice_error_t idevice_connection_enable_ssl(idevice_conne
X509_free(rootCert);
free(root_cert.data);
+#if OPENSSL_VERSION_NUMBER >= 0x30000000L
+ EVP_PKEY* rootPrivKey = NULL;
+ membp = BIO_new_mem_buf(root_privkey.data, root_privkey.size);
+ PEM_read_bio_PrivateKey(membp, &rootPrivKey, NULL, NULL);
+ BIO_free(membp);
+ if (SSL_CTX_use_PrivateKey(ssl_ctx, rootPrivKey) != 1) {
+ debug_info("WARNING: Could not load RootPrivateKey");
+ }
+ EVP_PKEY_free(rootPrivKey);
+#else
RSA* rootPrivKey = NULL;
membp = BIO_new_mem_buf(root_privkey.data, root_privkey.size);
PEM_read_bio_RSAPrivateKey(membp, &rootPrivKey, NULL, NULL);
@@ -1235,6 +1294,7 @@ LIBIMOBILEDEVICE_API idevice_error_t idevice_connection_enable_ssl(idevice_conne
debug_info("WARNING: Could not load RootPrivateKey");
}
RSA_free(rootPrivKey);
+#endif
free(root_privkey.data);
SSL *ssl = SSL_new(ssl_ctx);
diff --git a/src/installation_proxy.c b/src/installation_proxy.c
index b13abf9..9602876 100644
--- a/src/installation_proxy.c
+++ b/src/installation_proxy.c
@@ -934,7 +934,7 @@ LIBIMOBILEDEVICE_API void instproxy_client_options_add(plist_t client_options, .
if (!strcmp(key, "SkipUninstall")) {
int intval = va_arg(args, int);
plist_dict_set_item(client_options, key, plist_new_bool(intval));
- } else if (!strcmp(key, "ApplicationSINF") || !strcmp(key, "iTunesMetadata") || !strcmp(key, "ReturnAttributes")) {
+ } else if (!strcmp(key, "ApplicationSINF") || !strcmp(key, "iTunesMetadata") || !strcmp(key, "ReturnAttributes") || !strcmp(key, "BundleIDs")) {
plist_t plistval = va_arg(args, plist_t);
if (!plistval) {
free(key);
diff --git a/src/lockdown-cu.c b/src/lockdown-cu.c
index 61a1c03..d8d7f42 100644
--- a/src/lockdown-cu.c
+++ b/src/lockdown-cu.c
@@ -1032,7 +1032,7 @@ LIBIMOBILEDEVICE_API lockdownd_error_t lockdownd_cu_send_request_and_get_reply(l
plist_free(dict);
dict = NULL;
- plist_from_memory((const char*)decrypted, decrypted_len, &dict);
+ plist_from_memory((const char*)decrypted, decrypted_len, &dict, NULL);
if (!dict) {
ret = LOCKDOWN_E_PLIST_ERROR;
debug_info("Failed to parse PLIST from decrypted payload:");
diff --git a/src/lockdown.c b/src/lockdown.c
index 505b13e..92af186 100644
--- a/src/lockdown.c
+++ b/src/lockdown.c
@@ -165,51 +165,38 @@ lockdownd_error_t lockdown_check_result(plist_t dict, const char *query_match)
return ret;
}
- char *query_value = NULL;
-
- plist_get_string_val(query_node, &query_value);
+ const char *query_value = plist_get_string_ptr(query_node, NULL);
if (!query_value) {
return ret;
}
if (query_match && (strcmp(query_value, query_match) != 0)) {
- free(query_value);
return ret;
}
- free(query_value);
-
- plist_t result_node = plist_dict_get_item(dict, "Result");
- if (!result_node) {
- /* iOS 5: the 'Result' key is not present anymore.
- But we need to check for the 'Error' key. */
- plist_t err_node = plist_dict_get_item(dict, "Error");
- if (err_node) {
- if (plist_get_node_type(err_node) == PLIST_STRING) {
- char *err_value = NULL;
-
- plist_get_string_val(err_node, &err_value);
- if (err_value) {
- debug_info("ERROR: %s", err_value);
- ret = lockdownd_strtoerr(err_value);
- free(err_value);
- } else {
- debug_info("ERROR: unknown error occurred");
- }
+ /* Check for 'Error' in reply */
+ plist_t err_node = plist_dict_get_item(dict, "Error");
+ if (err_node) {
+ if (plist_get_node_type(err_node) == PLIST_STRING) {
+ const char *err_value = plist_get_string_ptr(err_node, NULL);
+ if (err_value) {
+ debug_info("ERROR: %s", err_value);
+ ret = lockdownd_strtoerr(err_value);
+ } else {
+ debug_info("ERROR: unknown error occurred");
}
- return ret;
}
-
- ret = LOCKDOWN_E_SUCCESS;
-
return ret;
}
- plist_type result_type = plist_get_node_type(result_node);
- if (result_type == PLIST_STRING) {
- char *result_value = NULL;
-
- plist_get_string_val(result_node, &result_value);
+ plist_t result_node = plist_dict_get_item(dict, "Result");
+ if (!result_node) {
+ /* With iOS 5+ 'Result' is not present anymore.
+ If there is no 'Error', we can just assume success. */
+ return LOCKDOWN_E_SUCCESS;
+ }
+ if (plist_get_node_type(result_node) == PLIST_STRING) {
+ const char *result_value = plist_get_string_ptr(result_node, NULL);
if (result_value) {
if (!strcmp(result_value, "Success")) {
ret = LOCKDOWN_E_SUCCESS;
@@ -219,9 +206,6 @@ lockdownd_error_t lockdown_check_result(plist_t dict, const char *query_match)
debug_info("ERROR: unknown result value '%s'", result_value);
}
}
-
- if (result_value)
- free(result_value);
}
return ret;
diff --git a/src/mobilebackup.c b/src/mobilebackup.c
index aa29277..1505623 100644
--- a/src/mobilebackup.c
+++ b/src/mobilebackup.c
@@ -279,7 +279,15 @@ LIBIMOBILEDEVICE_API mobilebackup_error_t mobilebackup_request_backup(mobileback
char *str = NULL;
plist_get_string_val(node, &str);
if (str) {
- if (strcmp(str, proto_version) != 0) {
+ int maj = 0;
+ int min = 0;
+ sscanf(str, "%u.%u", &maj, &min);
+ uint32_t this_ver = ((maj & 0xFF) << 8) | (min & 0xFF);
+ maj = 0;
+ min = 0;
+ sscanf(proto_version, "%u.%u", &maj, &min);
+ uint32_t proto_ver = ((maj & 0xFF) << 8) | (min & 0xFF);
+ if (this_ver > proto_ver) {
err = MOBILEBACKUP_E_BAD_VERSION;
}
free(str);
@@ -346,7 +354,15 @@ LIBIMOBILEDEVICE_API mobilebackup_error_t mobilebackup_request_restore(mobilebac
char *str = NULL;
plist_get_string_val(node, &str);
if (str) {
- if (strcmp(str, proto_version) != 0) {
+ int maj = 0;
+ int min = 0;
+ sscanf(str, "%u.%u", &maj, &min);
+ uint32_t this_ver = ((maj & 0xFF) << 8) | (min & 0xFF);
+ maj = 0;
+ min = 0;
+ sscanf(proto_version, "%u.%u", &maj, &min);
+ uint32_t proto_ver = ((maj & 0xFF) << 8) | (min & 0xFF);
+ if (this_ver > proto_ver) {
err = MOBILEBACKUP_E_BAD_VERSION;
}
free(str);
diff --git a/src/restore.c b/src/restore.c
index 591fd16..41bfb9d 100644
--- a/src/restore.c
+++ b/src/restore.c
@@ -287,7 +287,7 @@ LIBIMOBILEDEVICE_API restored_error_t restored_get_value(restored_client_t clien
}
*value = plist_copy(item);
- free(item);
+
return RESTORE_E_SUCCESS;
}
diff --git a/src/reverse_proxy.c b/src/reverse_proxy.c
index 3f0a839..bca0a13 100644
--- a/src/reverse_proxy.c
+++ b/src/reverse_proxy.c
@@ -25,6 +25,9 @@
#endif
#include <string.h>
#include <stdlib.h>
+#define _GNU_SOURCE 1
+#define __USE_GNU 1
+#include <stdio.h>
#include <errno.h>
#include <plist/plist.h>
@@ -91,7 +94,7 @@ static void _reverse_proxy_log(reverse_proxy_client_t client, const char* format
va_list args;
va_start(args, format);
char* buffer = NULL;
- (void)vasprintf(&buffer, format, args);
+ if(vasprintf(&buffer, format, args)<0){}
va_end(args);
client->log_cb(client, buffer, client->log_cb_user_data);
free(buffer);
@@ -113,7 +116,7 @@ static void _reverse_proxy_status(reverse_proxy_client_t client, int status, con
va_list args;
va_start(args, format);
char* buffer = NULL;
- (void)vasprintf(&buffer, format, args);
+ if(vasprintf(&buffer, format, args)<0){}
va_end(args);
client->status_cb(client, status, buffer, client->status_cb_user_data);
free(buffer);
@@ -186,10 +189,10 @@ static int _reverse_proxy_handle_proxy_cmd(reverse_proxy_client_t client)
/* else wait for messages and forward them */
int sockfd = socket_connect(host, port);
- free(host);
if (sockfd < 0) {
free(buf);
_reverse_proxy_log(client, "ERROR: Connection to %s:%u failed: %s", host, port, strerror(errno));
+ free(host);
return -1;
}
@@ -259,6 +262,7 @@ static int _reverse_proxy_handle_proxy_cmd(reverse_proxy_client_t client)
}
}
socket_close(sockfd);
+ free(host);
free(buf);
_reverse_proxy_status(client, RP_STATUS_DISCONNECTED, "Disconnected (out: %u / in: %u)", sent_total, recv_total);
diff --git a/tools/Makefile.am b/tools/Makefile.am
index e8ef3ab..bd93631 100644
--- a/tools/Makefile.am
+++ b/tools/Makefile.am
@@ -4,6 +4,7 @@ AM_CPPFLAGS = \
AM_CFLAGS = \
$(GLOBAL_CFLAGS) \
+ $(ssl_lib_CFLAGS) \
$(libplist_CFLAGS) \
$(LFS_CFLAGS)
@@ -27,6 +28,7 @@ bin_PROGRAMS = \
idevicedebugserverproxy \
idevicediagnostics \
idevicedebug \
+ idevicedevmodectl \
idevicenotificationproxy \
idevicecrashreport \
idevicesetlocation
@@ -47,7 +49,7 @@ idevicename_LDFLAGS = $(AM_LDFLAGS)
idevicename_LDADD = $(top_builddir)/src/libimobiledevice-1.0.la
idevicepair_SOURCES = idevicepair.c
-idevicepair_CFLAGS = $(AM_CFLAGS) $(ssl_lib_CFLAGS)
+idevicepair_CFLAGS = $(AM_CFLAGS)
idevicepair_LDFLAGS = $(AM_LDFLAGS) $(libusbmuxd_LIBS) $(ssl_lib_LIBS)
idevicepair_LDADD = $(top_builddir)/src/libimobiledevice-1.0.la $(top_builddir)/common/libinternalcommon.la $(limd_glue_LIBS)
@@ -62,7 +64,7 @@ idevice_id_LDFLAGS = $(AM_LDFLAGS)
idevice_id_LDADD = $(top_builddir)/src/libimobiledevice-1.0.la
idevicebackup_SOURCES = idevicebackup.c
-idevicebackup_CFLAGS = $(AM_CFLAGS) $(ssl_lib_CFLAGS) $(limd_glue_CFLAGS)
+idevicebackup_CFLAGS = $(AM_CFLAGS) $(limd_glue_CFLAGS)
idevicebackup_LDFLAGS = $(AM_LDFLAGS) $(ssl_lib_LIBS) $(limd_glue_LIBS)
idevicebackup_LDADD = $(top_builddir)/src/libimobiledevice-1.0.la
@@ -111,6 +113,11 @@ idevicedebug_CFLAGS = $(AM_CFLAGS) $(limd_glue_CFLAGS)
idevicedebug_LDFLAGS = $(AM_LDFLAGS) $(limd_glue_LIBS)
idevicedebug_LDADD = $(top_builddir)/src/libimobiledevice-1.0.la $(top_builddir)/common/libinternalcommon.la
+idevicedevmodectl_SOURCES = idevicedevmodectl.c
+idevicedevmodectl_CFLAGS = $(AM_CFLAGS) $(limd_glue_CFLAGS)
+idevicedevmodectl_LDFLAGS = $(AM_LDFLAGS) $(limd_glue_LIBS)
+idevicedevmodectl_LDADD = $(top_builddir)/src/libimobiledevice-1.0.la $(top_builddir)/common/libinternalcommon.la
+
idevicenotificationproxy_SOURCES = idevicenotificationproxy.c
idevicenotificationproxy_CFLAGS = $(AM_CFLAGS)
idevicenotificationproxy_LDFLAGS = $(AM_LDFLAGS)
diff --git a/tools/idevicebackup.c b/tools/idevicebackup.c
index 2856fda..5694c12 100644
--- a/tools/idevicebackup.c
+++ b/tools/idevicebackup.c
@@ -34,6 +34,9 @@
#include <getopt.h>
#if defined(HAVE_OPENSSL)
#include <openssl/sha.h>
+#if OPENSSL_VERSION_NUMBER >= 0x30000000L
+#include <openssl/evp.h>
+#endif
#elif defined(HAVE_GNUTLS)
#include <gcrypt.h>
#elif defined(HAVE_MBEDTLS)
@@ -57,6 +60,7 @@
#include <libimobiledevice/notification_proxy.h>
#include <libimobiledevice/afc.h>
#include <libimobiledevice-glue/utils.h>
+#include <plist/plist.h>
#define MOBILEBACKUP_SERVICE_NAME "com.apple.mobilebackup"
#define NP_SERVICE_NAME "com.apple.mobile.notification_proxy"
@@ -112,7 +116,11 @@ static int compare_hash(const unsigned char *hash1, const unsigned char *hash2,
static void _sha1_update(void* context, const char* data, size_t len)
{
#if defined(HAVE_OPENSSL)
+#if OPENSSL_VERSION_NUMBER >= 0x30000000L
+ EVP_DigestUpdate(context, data, len);
+#else
SHA1_Update(context, data, len);
+#endif
#elif defined(HAVE_GNUTLS)
gcry_md_write(context, data, len);
#elif defined(HAVE_MBEDTLS)
@@ -123,9 +131,15 @@ static void _sha1_update(void* context, const char* data, size_t len)
static void compute_datahash(const char *path, const char *destpath, uint8_t greylist, const char *domain, const char *appid, const char *version, unsigned char *hash_out)
{
#if defined(HAVE_OPENSSL)
+#if OPENSSL_VERSION_NUMBER >= 0x30000000L
+ EVP_MD_CTX* sha1 = EVP_MD_CTX_new();
+ EVP_DigestInit(sha1, EVP_sha1());
+ void* psha1 = sha1;
+#else
SHA_CTX sha1;
SHA1_Init(&sha1);
void* psha1 = &sha1;
+#endif
#elif defined(HAVE_GNUTLS)
gcry_md_hd_t hd = NULL;
gcry_md_open(&hd, GCRY_MD_SHA1, 0);
@@ -179,7 +193,12 @@ static void compute_datahash(const char *path, const char *destpath, uint8_t gre
_sha1_update(psha1, "(null)", 6);
}
#if defined(HAVE_OPENSSL)
+#if OPENSSL_VERSION_NUMBER >= 0x30000000L
+ EVP_DigestFinal(sha1, hash_out, NULL);
+ EVP_MD_CTX_destroy(sha1);
+#else
SHA1_Final(hash_out, &sha1);
+#endif
#elif defined(HAVE_GNUTLS)
unsigned char *newhash = gcry_md_read(hd, GCRY_MD_SHA1);
memcpy(hash_out, newhash, 20);
@@ -317,7 +336,7 @@ static void mobilebackup_write_status(const char *path, int status)
if (stat(file_path, &st) == 0)
remove(file_path);
- plist_write_to_filename(status_plist, file_path, PLIST_FORMAT_XML);
+ plist_write_to_file(status_plist, file_path, PLIST_FORMAT_XML, 0);
plist_free(status_plist);
status_plist = NULL;
@@ -331,7 +350,7 @@ static int mobilebackup_read_status(const char *path)
plist_t status_plist = NULL;
char *file_path = mobilebackup_build_path(path, "Status", ".plist");
- plist_read_from_filename(&status_plist, file_path);
+ plist_read_from_file(file_path, &status_plist, NULL);
free(file_path);
if (!status_plist) {
printf("Could not read Status.plist!\n");
@@ -454,7 +473,7 @@ static int mobilebackup_check_file_integrity(const char *backup_directory, const
}
infopath = mobilebackup_build_path(backup_directory, hash, ".mdinfo");
- plist_read_from_filename(&mdinfo, infopath);
+ plist_read_from_file(infopath, &mdinfo, NULL);
free(infopath);
if (!mdinfo) {
printf("\r\n");
@@ -882,7 +901,7 @@ int main(int argc, char *argv[])
/* verify existing Info.plist */
if (stat(info_path, &st) == 0) {
printf("Reading Info.plist from backup.\n");
- plist_read_from_filename(&info_plist, info_path);
+ plist_read_from_file(info_path, &info_plist, NULL);
if (!info_plist) {
printf("Could not read Info.plist\n");
@@ -893,7 +912,7 @@ int main(int argc, char *argv[])
/* update the last backup time within Info.plist */
mobilebackup_info_update_last_backup_date(info_plist);
remove(info_path);
- plist_write_to_filename(info_plist, info_path, PLIST_FORMAT_XML);
+ plist_write_to_file(info_plist, info_path, PLIST_FORMAT_XML, 0);
} else {
printf("Aborting backup. Backup is not compatible with the current device.\n");
cmd = CMD_LEAVE;
@@ -959,7 +978,7 @@ int main(int argc, char *argv[])
/* read the last Manifest.plist */
if (!is_full_backup) {
printf("Reading existing Manifest.\n");
- plist_read_from_filename(&manifest_plist, manifest_path);
+ plist_read_from_file(manifest_path, &manifest_plist, NULL);
if (!manifest_plist) {
printf("Could not read Manifest.plist, switching to full backup mode.\n");
is_full_backup = 1;
@@ -977,7 +996,7 @@ int main(int argc, char *argv[])
remove(info_path);
printf("Creating Info.plist for new backup.\n");
info_plist = mobilebackup_factory_info_plist_new(udid);
- plist_write_to_filename(info_plist, info_path, PLIST_FORMAT_XML);
+ plist_write_to_file(info_plist, info_path, PLIST_FORMAT_XML, 0);
}
free(info_path);
@@ -1116,7 +1135,7 @@ int main(int argc, char *argv[])
remove(filename_mdinfo);
node = plist_dict_get_item(node_tmp, "BackupFileInfo");
- plist_write_to_filename(node, filename_mdinfo, PLIST_FORMAT_BINARY);
+ plist_write_to_file(node, filename_mdinfo, PLIST_FORMAT_BINARY, 0);
free(filename_mdinfo);
}
@@ -1228,7 +1247,7 @@ files_out:
if (manifest_plist) {
remove(manifest_path);
printf("Storing Manifest.plist...\n");
- plist_write_to_filename(manifest_plist, manifest_path, PLIST_FORMAT_XML);
+ plist_write_to_file(manifest_plist, manifest_path, PLIST_FORMAT_XML, 0);
}
backup_ok = 1;
@@ -1259,7 +1278,7 @@ files_out:
}
/* now make sure backup integrity is ok! verify all files */
printf("Reading existing Manifest.\n");
- plist_read_from_filename(&manifest_plist, manifest_path);
+ plist_read_from_file(manifest_path, &manifest_plist, NULL);
if (!manifest_plist) {
printf("Could not read Manifest.plist. Aborting.\n");
break;
@@ -1386,7 +1405,7 @@ files_out:
while (node) {
/* TODO: read mddata/mdinfo files and send to device using DLSendFile */
file_info_path = mobilebackup_build_path(backup_directory, hash, ".mdinfo");
- plist_read_from_filename(&file_info, file_info_path);
+ plist_read_from_file(file_info_path, &file_info, NULL);
/* get encryption state */
tmp_node = plist_dict_get_item(file_info, "IsEncrypted");
diff --git a/tools/idevicebackup2.c b/tools/idevicebackup2.c
index f2242d2..c73b269 100644
--- a/tools/idevicebackup2.c
+++ b/tools/idevicebackup2.c
@@ -47,6 +47,7 @@
#include <libimobiledevice/sbservices.h>
#include <libimobiledevice/diagnostics_relay.h>
#include <libimobiledevice-glue/utils.h>
+#include <plist/plist.h>
#include <endianness.h>
@@ -606,7 +607,7 @@ static int mb2_status_check_snapshot_state(const char *path, const char *udid, c
plist_t status_plist = NULL;
char *file_path = string_build_path(path, udid, "Status.plist", NULL);
- plist_read_from_filename(&status_plist, file_path);
+ plist_read_from_file(file_path, &status_plist, NULL);
free(file_path);
if (!status_plist) {
printf("Could not read Status.plist!\n");
@@ -1555,6 +1556,7 @@ int main(int argc, char *argv[])
return 2;
}
source_udid = strdup(optarg);
+ break;
case 'i':
interactive_mode = 1;
break;
@@ -1779,7 +1781,7 @@ int main(int argc, char *argv[])
free(info_path);
}
plist_t manifest_plist = NULL;
- plist_read_from_filename(&manifest_plist, manifest_path);
+ plist_read_from_file(manifest_path, &manifest_plist, NULL);
if (!manifest_plist) {
idevice_free(device);
free(info_path);
@@ -1935,7 +1937,7 @@ int main(int argc, char *argv[])
/* verify existing Info.plist */
if (info_path && (stat(info_path, &st) == 0) && cmd != CMD_CLOUD) {
PRINT_VERBOSE(1, "Reading Info.plist from backup.\n");
- plist_read_from_filename(&info_plist, info_path);
+ plist_read_from_file(info_path, &info_plist, NULL);
if (!info_plist) {
printf("Could not read Info.plist\n");
@@ -2029,7 +2031,7 @@ checkpoint:
cmd = CMD_LEAVE;
}
remove_file(info_path);
- plist_write_to_filename(info_plist, info_path, PLIST_FORMAT_XML);
+ plist_write_to_file(info_plist, info_path, PLIST_FORMAT_XML, 0);
free(info_path);
plist_free(info_plist);
diff --git a/tools/idevicecrashreport.c b/tools/idevicecrashreport.c
index d0d2147..09bd537 100644
--- a/tools/idevicecrashreport.c
+++ b/tools/idevicecrashreport.c
@@ -81,7 +81,7 @@ static int extract_raw_crash_report(const char* filename)
strcpy(p, ".crash");
/* read plist crash report */
- if (plist_read_from_filename(&report, filename)) {
+ if (plist_read_from_file(filename, &report, NULL)) {
plist_t description_node = plist_dict_get_item(report, "description");
if (description_node && plist_get_node_type(description_node) == PLIST_STRING) {
plist_get_string_val(description_node, &raw);
@@ -163,7 +163,7 @@ static int afc_client_copy_and_remove_crash_reports(afc_client_t afc, const char
char* p = strrchr(list[k], '.');
if (p != NULL && !strncmp(p, ".synced", 7)) {
/* make sure to strip ".synced" extension as seen on iOS 5 */
- int newlen = strlen(list[k]) - 7;
+ size_t newlen = p - list[k];
strncpy(((char*)target_filename) + host_directory_length, list[k], newlen);
target_filename[host_directory_length + newlen] = '\0';
} else {
diff --git a/tools/idevicedebug.c b/tools/idevicedebug.c
index fbb6c3e..36c594e 100644
--- a/tools/idevicedebug.c
+++ b/tools/idevicedebug.c
@@ -291,6 +291,11 @@ int main(int argc, char *argv[])
res = 0;
goto cleanup;
break;
+ default:
+ print_usage(argc, argv, 1);
+ res = 2;
+ goto cleanup;
+ break;
}
}
argc -= optind;
diff --git a/tools/idevicedevmodectl.c b/tools/idevicedevmodectl.c
new file mode 100644
index 0000000..ba9b935
--- /dev/null
+++ b/tools/idevicedevmodectl.c
@@ -0,0 +1,452 @@
+/*
+ * idevicedevmodectl.c
+ * List or enable Developer Mode on iOS 16+ devices
+ *
+ * Copyright (c) 2022 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
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#define TOOL_NAME "idevicedevmodectl"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <getopt.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include <errno.h>
+#ifndef WIN32
+#include <signal.h>
+#endif
+
+#ifdef WIN32
+#include <windows.h>
+#define __usleep(x) Sleep(x/1000)
+#else
+#include <arpa/inet.h>
+#define __usleep(x) usleep(x)
+#endif
+
+#include <libimobiledevice/libimobiledevice.h>
+#include <libimobiledevice/lockdown.h>
+#include <libimobiledevice/property_list_service.h>
+#include <libimobiledevice-glue/utils.h>
+
+#define AMFI_LOCKDOWN_SERVICE_NAME "com.apple.amfi.lockdown"
+
+static char* udid = NULL;
+static int use_network = 0;
+
+static void print_usage(int argc, char **argv, int is_error)
+{
+ char *name = strrchr(argv[0], '/');
+ fprintf(is_error ? stderr : stdout, "Usage: %s [OPTIONS] COMMAND\n", (name ? name + 1: argv[0]));
+ fprintf(is_error ? stderr : stdout,
+ "\n"
+ "Enable Developer Mode on iOS 16+ devices or print the current status.\n"
+ "\n"
+ "Where COMMAND is one of:\n"
+ " list Print the Developer Mode status of all connected devices\n"
+ " or for a specific one if --udid is given.\n"
+ " enable Enable Developer Mode (device will reboot),\n"
+ " and confirm it after device booted up again.\n"
+ "\n"
+ " arm Arm the Developer Mode (device will reboot)\n"
+ " confirm Confirm enabling of Developer Mode\n"
+ " reveal Reveal the Developer Mode menu on the device\n"
+ "\n"
+ "The following OPTIONS are accepted:\n"
+ " -u, --udid UDID target specific device by UDID\n"
+ " -n, --network connect to network device\n"
+ " -d, --debug enable communication debugging\n"
+ " -h, --help print usage information\n"
+ " -v, --version print version information\n"
+ "\n"
+ "Homepage: <" PACKAGE_URL ">\n"
+ "Bug Reports: <" PACKAGE_BUGREPORT ">\n"
+ );
+}
+
+enum {
+ OP_LIST,
+ OP_ENABLE,
+ OP_ARM,
+ OP_CONFIRM,
+ OP_REVEAL,
+ NUM_OPS
+};
+#define DEV_MODE_REVEAL 0
+#define DEV_MODE_ARM 1
+#define DEV_MODE_ENABLE 2
+
+static int get_developer_mode_status(const char* device_udid, int _use_network)
+{
+ idevice_error_t ret;
+ idevice_t device = NULL;
+ lockdownd_client_t lockdown = NULL;
+ lockdownd_error_t lerr = LOCKDOWN_E_UNKNOWN_ERROR;
+ plist_t val = NULL;
+
+ ret = idevice_new_with_options(&device, device_udid, (_use_network) ? IDEVICE_LOOKUP_NETWORK : IDEVICE_LOOKUP_USBMUX);
+ if (ret != IDEVICE_E_SUCCESS) {
+ return -1;
+ }
+
+ if (LOCKDOWN_E_SUCCESS != (lerr = lockdownd_client_new_with_handshake(device, &lockdown, TOOL_NAME))) {
+ idevice_free(device);
+ return -1;
+ }
+
+ lerr = lockdownd_get_value(lockdown, "com.apple.security.mac.amfi", "DeveloperModeStatus", &val);
+ if (lerr != LOCKDOWN_E_SUCCESS) {
+ fprintf(stderr, "ERROR: Could not get DeveloperModeStatus: %s\nPlease note that this feature is only available on iOS 16+.\n", lockdownd_strerror(lerr));
+ lockdownd_client_free(lockdown);
+ idevice_free(device);
+ return -2;
+ }
+
+ uint8_t dev_mode_status = 0;
+ plist_get_bool_val(val, &dev_mode_status);
+ plist_free(val);
+
+ lockdownd_client_free(lockdown);
+ idevice_free(device);
+
+ return dev_mode_status;
+}
+
+static int amfi_service_send_msg(property_list_service_client_t amfi, plist_t msg)
+{
+ int res;
+ property_list_service_error_t perr;
+
+ perr = property_list_service_send_xml_plist(amfi, plist_copy(msg));
+ if (perr != PROPERTY_LIST_SERVICE_E_SUCCESS) {
+ fprintf(stderr, "Could not send request to device: %d\n", perr);
+ res = 2;
+ } else {
+ plist_t reply = NULL;
+ perr = property_list_service_receive_plist(amfi, &reply);
+ if (perr == PROPERTY_LIST_SERVICE_E_SUCCESS) {
+ uint8_t success = 0;
+ plist_t val = plist_dict_get_item(reply, "Error");
+ if (val) {
+ const char* err = plist_get_string_ptr(val, NULL);
+ fprintf(stderr, "Request failed: %s\n", err);
+ if (strstr(err, "passcode")) {
+ res = 2;
+ } else {
+ res = 1;
+ }
+ } else {
+ val = plist_dict_get_item(reply, "success");
+ if (val) {
+ plist_get_bool_val(val, &success);
+ }
+ if (success) {
+ res = 0;
+ } else {
+ res = 1;
+ }
+ }
+ } else {
+ fprintf(stderr, "Could not receive reply from device: %d\n", perr);
+ res = 2;
+ }
+ plist_free(reply);
+ }
+ return res;
+}
+
+static int amfi_send_action(idevice_t device, unsigned int action)
+{
+ lockdownd_client_t lockdown = NULL;
+ lockdownd_service_descriptor_t service = NULL;
+ lockdownd_error_t lerr;
+
+ if (LOCKDOWN_E_SUCCESS != (lerr = lockdownd_client_new_with_handshake(device, &lockdown, TOOL_NAME))) {
+ fprintf(stderr, "ERROR: Could not connect to lockdownd, error code %d\n", lerr);
+ return 1;
+ }
+
+ lerr = lockdownd_start_service(lockdown, AMFI_LOCKDOWN_SERVICE_NAME, &service);
+ if (lerr != LOCKDOWN_E_SUCCESS) {
+ fprintf(stderr, "Could not start service %s: %s\nPlease note that this feature is only available on iOS 16+.\n", AMFI_LOCKDOWN_SERVICE_NAME, lockdownd_strerror(lerr));
+ lockdownd_client_free(lockdown);
+ return 1;
+ }
+ lockdownd_client_free(lockdown);
+ lockdown = NULL;
+
+ property_list_service_client_t amfi = NULL;
+ if (property_list_service_client_new(device, service, &amfi) != PROPERTY_LIST_SERVICE_E_SUCCESS) {
+ fprintf(stderr, "Could not connect to %s on device\n", AMFI_LOCKDOWN_SERVICE_NAME);
+ if (service)
+ lockdownd_service_descriptor_free(service);
+ idevice_free(device);
+ return 1;
+ }
+ lockdownd_service_descriptor_free(service);
+
+ plist_t dict = plist_new_dict();
+ plist_dict_set_item(dict, "action", plist_new_uint(action));
+
+ int result = amfi_service_send_msg(amfi, dict);
+ plist_free(dict);
+
+ property_list_service_client_free(amfi);
+ amfi = NULL;
+
+ return result;
+}
+
+static int device_connected = 0;
+
+static void device_event_cb(const idevice_event_t* event, void* userdata)
+{
+ if (use_network && event->conn_type != CONNECTION_NETWORK) {
+ return;
+ }
+ if (!use_network && event->conn_type != CONNECTION_USBMUXD) {
+ return;
+ }
+ if (event->event == IDEVICE_DEVICE_ADD) {
+ if (!udid) {
+ udid = strdup(event->udid);
+ }
+ if (strcmp(udid, event->udid) == 0) {
+ device_connected = 1;
+ }
+ } else if (event->event == IDEVICE_DEVICE_REMOVE) {
+ if (strcmp(udid, event->udid) == 0) {
+ device_connected = 0;
+ }
+ }
+}
+
+
+#define WAIT_INTERVAL 200000
+#define WAIT_MAX(x) (x * (1000000 / WAIT_INTERVAL))
+#define WAIT_FOR(cond, timeout) { int __repeat = WAIT_MAX(timeout); while (!(cond) && __repeat-- > 0) { __usleep(WAIT_INTERVAL); } }
+
+int main(int argc, char *argv[])
+{
+ idevice_t device = NULL;
+ idevice_error_t ret = IDEVICE_E_UNKNOWN_ERROR;
+ lockdownd_client_t lockdown = NULL;
+ lockdownd_error_t lerr = LOCKDOWN_E_UNKNOWN_ERROR;
+ int res = 0;
+ int i;
+ int op = -1;
+ plist_t val = NULL;
+
+ int c = 0;
+ const struct option longopts[] = {
+ { "debug", no_argument, NULL, 'd' },
+ { "help", no_argument, NULL, 'h' },
+ { "udid", required_argument, NULL, 'u' },
+ { "network", no_argument, NULL, 'n' },
+ { "version", no_argument, NULL, 'v' },
+ { NULL, 0, NULL, 0}
+ };
+
+#ifndef WIN32
+ signal(SIGPIPE, SIG_IGN);
+#endif
+ /* parse cmdline args */
+ while ((c = getopt_long(argc, argv, "dhu:nv", longopts, NULL)) != -1) {
+ switch (c) {
+ case 'd':
+ idevice_set_debug_level(1);
+ break;
+ case 'u':
+ if (!*optarg) {
+ fprintf(stderr, "ERROR: UDID argument must not be empty!\n");
+ print_usage(argc, argv, 1);
+ return 2;
+ }
+ udid = optarg;
+ break;
+ case 'n':
+ use_network = 1;
+ break;
+ case 'h':
+ print_usage(argc, argv, 0);
+ return 0;
+ case 'v':
+ printf("%s %s\n", TOOL_NAME, PACKAGE_VERSION);
+ return 0;
+ default:
+ print_usage(argc, argv, 1);
+ return 2;
+ }
+ }
+ argc -= optind;
+ argv += optind;
+
+ if (!argv[0]) {
+ fprintf(stderr, "ERROR: Missing command.\n");
+ print_usage(argc+optind, argv-optind, 1);
+ return 2;
+ }
+
+ i = 0;
+ if (!strcmp(argv[i], "list")) {
+ op = OP_LIST;
+ }
+ else if (!strcmp(argv[i], "enable")) {
+ op = OP_ENABLE;
+ }
+ else if (!strcmp(argv[i], "arm")) {
+ op = OP_ARM;
+ }
+ else if (!strcmp(argv[i], "confirm")) {
+ op = OP_CONFIRM;
+ }
+ else if (!strcmp(argv[i], "reveal")) {
+ op = OP_REVEAL;
+ }
+
+ if ((op == -1) || (op >= NUM_OPS)) {
+ fprintf(stderr, "ERROR: Unsupported command '%s'\n", argv[i]);
+ print_usage(argc+optind, argv-optind, 1);
+ return 2;
+ }
+
+ if (op == OP_LIST) {
+ idevice_info_t *dev_list = NULL;
+
+ if (idevice_get_device_list_extended(&dev_list, &i) < 0) {
+ fprintf(stderr, "ERROR: Unable to retrieve device list!\n");
+ return -1;
+ }
+ if (i > 0) {
+ printf("%-40s %s\n", "Device", "DeveloperMode");
+ }
+ for (i = 0; dev_list[i] != NULL; i++) {
+ if (dev_list[i]->conn_type == CONNECTION_USBMUXD && use_network) continue;
+ if (dev_list[i]->conn_type == CONNECTION_NETWORK && !use_network) continue;
+ if (udid && (strcmp(dev_list[i]->udid, udid) != 0)) continue;
+ int mode = get_developer_mode_status(dev_list[i]->udid, use_network);
+ const char *mode_str = "N/A";
+ if (mode == 1) {
+ mode_str = "enabled";
+ } else if (mode == 0) {
+ mode_str = "disabled";
+ }
+ printf("%-40s %s\n", dev_list[i]->udid, mode_str);
+ }
+ idevice_device_list_extended_free(dev_list);
+
+ return 0;
+ }
+
+ idevice_subscription_context_t context = NULL;
+ idevice_events_subscribe(&context, device_event_cb, NULL);
+
+ WAIT_FOR(device_connected, 10);
+
+ ret = idevice_new_with_options(&device, udid, (use_network) ? IDEVICE_LOOKUP_NETWORK : IDEVICE_LOOKUP_USBMUX);
+ if (ret != IDEVICE_E_SUCCESS) {
+ if (udid) {
+ printf("No device found with udid %s.\n", udid);
+ } else {
+ printf("No device found.\n");
+ }
+ return 1;
+ }
+
+ if (!udid) {
+ idevice_get_udid(device, &udid);
+ }
+
+ if (LOCKDOWN_E_SUCCESS != (lerr = lockdownd_client_new_with_handshake(device, &lockdown, TOOL_NAME))) {
+ fprintf(stderr, "ERROR: Could not connect to lockdownd, error code %d\n", lerr);
+ idevice_free(device);
+ return 1;
+ }
+
+ lerr = lockdownd_get_value(lockdown, "com.apple.security.mac.amfi", "DeveloperModeStatus", &val);
+ lockdownd_client_free(lockdown);
+ lockdown = NULL;
+ if (lerr != LOCKDOWN_E_SUCCESS) {
+ fprintf(stderr, "ERROR: Could not get DeveloperModeStatus: %s\nPlease note that this feature is only available on iOS 16+.\n", lockdownd_strerror(lerr));
+ idevice_free(device);
+ return 1;
+ }
+
+ uint8_t dev_mode_status = 0;
+ plist_get_bool_val(val, &dev_mode_status);
+
+ if ((op == OP_ENABLE || op == OP_ARM) && dev_mode_status) {
+ if (dev_mode_status) {
+ printf("DeveloperMode is already enabled.\n");
+ return 0;
+ }
+ res = 0;
+ } else {
+ if (op == OP_ENABLE || op == OP_ARM) {
+ res = amfi_send_action(device, DEV_MODE_ARM);
+ if (res == 0) {
+ if (op == OP_ARM) {
+ printf("%s: Developer Mode armed, device will reboot now.\n", udid);
+ } else {
+ printf("%s: Developer Mode armed, waiting for reboot...\n", udid);
+
+ // waiting for device to disconnect...
+ WAIT_FOR(!device_connected, 20);
+
+ // waiting for device to reconnect...
+ WAIT_FOR(device_connected, 60);
+
+ res = amfi_send_action(device, DEV_MODE_ENABLE);
+ if (res == 0) {
+ printf("%s: Developer Mode successfully enabled.\n", udid);
+ } else {
+ printf("%s: Failed to enable developer mode (%d)\n", udid, res);
+ }
+ }
+ } else if (res == 2) {
+ amfi_send_action(device, DEV_MODE_REVEAL);
+ printf("%s: Developer Mode could not be enabled because the device has a passcode set. You have to enable it on the device itself under Settings -> Privacy & Security -> Developer Mode.\n", udid);
+ } else {
+ printf("%s: Failed to arm Developer Mode (%d)\n", udid, res);
+ }
+ } else if (op == OP_CONFIRM) {
+ res = amfi_send_action(device, DEV_MODE_ENABLE);
+ if (res == 0) {
+ printf("%s: Developer Mode successfully enabled.\n", udid);
+ } else {
+ printf("%s: Failed to enable Developer Mode (%d)\n", udid, res);
+ }
+ } else if (op == OP_REVEAL) {
+ res = amfi_send_action(device, DEV_MODE_REVEAL);
+ if (res == 0) {
+ printf("%s: Developer Mode menu revealed successfully.\n", udid);
+ } else {
+ printf("%s: Failed to reveal Developer Mode menu (%d)\n", udid, res);
+ }
+ }
+ }
+
+ idevice_free(device);
+
+ return res;
+}
diff --git a/tools/ideviceimagemounter.c b/tools/ideviceimagemounter.c
index b854d5d..f551b6c 100644
--- a/tools/ideviceimagemounter.c
+++ b/tools/ideviceimagemounter.c
@@ -46,7 +46,7 @@
#include <libimobiledevice/notification_proxy.h>
#include <libimobiledevice/mobile_image_mounter.h>
#include <asprintf.h>
-#include <libimobiledevice-glue/utils.h>
+#include <plist/plist.h>
static int list_mode = 0;
static int use_network = 0;
@@ -143,15 +143,6 @@ static void parse_opts(int argc, char **argv)
}
}
-static void print_xml(plist_t node)
-{
- char *xml = NULL;
- uint32_t len = 0;
- plist_to_xml(node, &xml, &len);
- if (xml)
- puts(xml);
-}
-
static ssize_t mim_upload_cb(void* buf, size_t size, void* userdata)
{
return fread(buf, 1, size, (FILE*)userdata);
@@ -224,6 +215,20 @@ int main(int argc, char **argv)
}
}
+ if (product_version_major == 16) {
+ uint8_t dev_mode_status = 0;
+ plist_t val = NULL;
+ ldret = lockdownd_get_value(lckd, "com.apple.security.mac.amfi", "DeveloperModeStatus", &val);
+ if (ldret == LOCKDOWN_E_SUCCESS) {
+ plist_get_bool_val(val, &dev_mode_status);
+ plist_free(val);
+ }
+ if (!dev_mode_status) {
+ printf("ERROR: You have to enable Developer Mode on the given device in order to allowing mounting a developer disk image.\n");
+ goto leave;
+ }
+ }
+
lockdownd_start_service(lckd, "com.apple.mobile.mobile_image_mounter", &service);
if (!service || service->port == 0) {
@@ -283,11 +288,7 @@ int main(int argc, char **argv)
err = mobile_image_mounter_lookup_image(mim, imagetype, &result);
if (err == MOBILE_IMAGE_MOUNTER_E_SUCCESS) {
res = 0;
- if (xml_mode) {
- print_xml(result);
- } else {
- plist_print_to_stream(result, stdout);
- }
+ plist_write_to_stream(result, stdout, (xml_mode) ? PLIST_FORMAT_XML : PLIST_FORMAT_LIMD, 0);
} else {
printf("Error: lookup_image returned %d\n", err);
}
@@ -415,20 +416,12 @@ int main(int argc, char **argv)
res = 0;
} else {
printf("unexpected status value:\n");
- if (xml_mode) {
- print_xml(result);
- } else {
- plist_print_to_stream(result, stdout);
- }
+ plist_write_to_stream(result, stdout, (xml_mode) ? PLIST_FORMAT_XML : PLIST_FORMAT_LIMD, 0);
}
free(status);
} else {
printf("unexpected result:\n");
- if (xml_mode) {
- print_xml(result);
- } else {
- plist_print_to_stream(result, stdout);
- }
+ plist_write_to_stream(result, stdout, (xml_mode) ? PLIST_FORMAT_XML : PLIST_FORMAT_LIMD, 0);
}
}
node = plist_dict_get_item(result, "Error");
@@ -440,19 +433,11 @@ int main(int argc, char **argv)
free(error);
} else {
printf("unexpected result:\n");
- if (xml_mode) {
- print_xml(result);
- } else {
- plist_print_to_stream(result, stdout);
- }
+ plist_write_to_stream(result, stdout, (xml_mode) ? PLIST_FORMAT_XML : PLIST_FORMAT_LIMD, 0);
}
} else {
- if (xml_mode) {
- print_xml(result);
- } else {
- plist_print_to_stream(result, stdout);
- }
+ plist_write_to_stream(result, stdout, (xml_mode) ? PLIST_FORMAT_XML : PLIST_FORMAT_LIMD, 0);
}
}
} else {
diff --git a/tools/ideviceinfo.c b/tools/ideviceinfo.c
index fc0527d..fd45763 100644
--- a/tools/ideviceinfo.c
+++ b/tools/ideviceinfo.c
@@ -37,7 +37,7 @@
#include <libimobiledevice/libimobiledevice.h>
#include <libimobiledevice/lockdown.h>
-#include <libimobiledevice-glue/utils.h>
+#include <plist/plist.h>
#define FORMAT_KEY_VALUE 1
#define FORMAT_XML 2
@@ -241,11 +241,11 @@ int main(int argc, char *argv[])
free(xml_doc);
break;
case FORMAT_KEY_VALUE:
- plist_print_to_stream(node, stdout);
+ plist_write_to_stream(node, stdout, PLIST_FORMAT_LIMD, 0);
break;
default:
if (key != NULL)
- plist_print_to_stream(node, stdout);
+ plist_write_to_stream(node, stdout, PLIST_FORMAT_LIMD, 0);
break;
}
plist_free(node);
diff --git a/tools/idevicepair.c b/tools/idevicepair.c
index dda02ec..94d3f04 100644
--- a/tools/idevicepair.c
+++ b/tools/idevicepair.c
@@ -41,7 +41,6 @@
#endif
#include "common/userpref.h"
-#include <libimobiledevice-glue/utils.h>
#include <libimobiledevice/libimobiledevice.h>
#include <libimobiledevice/lockdown.h>
@@ -104,7 +103,7 @@ static void pairing_cb(lockdownd_cu_pairing_cb_type_t cb_type, void *user_data,
printf("\n");
} else if (cb_type == LOCKDOWN_CU_PAIRING_DEVICE_INFO) {
printf("Device info:\n");
- plist_print_to_stream_with_indentation((plist_t)data_ptr, stdout, 2);
+ plist_write_to_stream((plist_t)data_ptr, stdout, PLIST_FORMAT_LIMD, PLIST_OPT_INDENT | PLIST_OPT_INDENT_BY(2));
} else if (cb_type == LOCKDOWN_CU_PAIRING_ERROR) {
printf("ERROR: %s\n", (data_ptr) ? (char*)data_ptr : "(unknown)");
}
@@ -257,7 +256,7 @@ int main(int argc, char **argv)
goto leave;
}
if (*optarg == '@') {
- plist_read_from_filename(&host_info_plist, optarg+1);
+ plist_read_from_file(optarg+1, &host_info_plist, NULL);
if (!host_info_plist) {
fprintf(stderr, "ERROR: Could not read from file '%s'\n", optarg+1);
result = EXIT_FAILURE;
diff --git a/tools/ideviceprovision.c b/tools/ideviceprovision.c
index 7cd4f3f..4080a28 100644
--- a/tools/ideviceprovision.c
+++ b/tools/ideviceprovision.c
@@ -45,7 +45,7 @@
#include <libimobiledevice/libimobiledevice.h>
#include <libimobiledevice/lockdown.h>
#include <libimobiledevice/misagent.h>
-#include <libimobiledevice-glue/utils.h>
+#include <plist/plist.h>
static void print_usage(int argc, char **argv, int is_error)
{
@@ -436,7 +436,7 @@ int main(int argc, char *argv[])
}
} else {
if (pl && (plist_get_node_type(pl) == PLIST_DICT)) {
- plist_print_to_stream(pl, stdout);
+ plist_write_to_stream(pl, stdout, PLIST_FORMAT_LIMD, 0);
} else {
fprintf(stderr, "ERROR: unexpected node type in profile plist (not PLIST_DICT)\n");
res = -1;