Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Contribute to GitLab
Sign in / Register
Toggle navigation
L
libplist
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
1
Issues
1
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
pwn
libplist
Commits
86f61988
Commit
86f61988
authored
Aug 31, 2008
by
Jonathan Beck
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
make all functions return an error code.
parent
dc89741f
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
197 additions
and
146 deletions
+197
-146
libiphone.h
include/libiphone/libiphone.h
+29
-27
AFC.c
src/AFC.c
+70
-60
iphone.c
src/iphone.c
+16
-9
lockdown.c
src/lockdown.c
+52
-32
usbmux.c
src/usbmux.c
+30
-18
No files found.
include/libiphone/libiphone.h
View file @
86f61988
...
@@ -46,6 +46,8 @@ extern "C" {
...
@@ -46,6 +46,8 @@ extern "C" {
//afc specific error
//afc specific error
#define IPHONE_E_NO_SUCH_FILE -10
#define IPHONE_E_NO_SUCH_FILE -10
typedef
short
iphone_error_t
;
enum
{
enum
{
AFC_FILE_READ
=
0x00000002
,
// seems to be able to read and write files
AFC_FILE_READ
=
0x00000002
,
// seems to be able to read and write files
AFC_FILE_WRITE
=
0x00000003
,
// writes and creates a file, blanks it out, etc.
AFC_FILE_WRITE
=
0x00000003
,
// writes and creates a file, blanks it out, etc.
...
@@ -73,44 +75,44 @@ struct iphone_afc_file_int;
...
@@ -73,44 +75,44 @@ struct iphone_afc_file_int;
typedef
struct
iphone_afc_file_int
*
iphone_afc_file_t
;
typedef
struct
iphone_afc_file_int
*
iphone_afc_file_t
;
//device related functions
//device related functions
i
nt
iphone_get_device
(
iphone_device_t
*
device
);
i
phone_error_t
iphone_get_device
(
iphone_device_t
*
device
);
void
iphone_free_device
(
iphone_device_t
device
);
iphone_error_t
iphone_free_device
(
iphone_device_t
device
);
//lockdownd related functions
//lockdownd related functions
i
n
t
iphone_lckd_new_client
(
iphone_device_t
device
,
iphone_lckd_client_t
*
client
);
i
phone_error_
t
iphone_lckd_new_client
(
iphone_device_t
device
,
iphone_lckd_client_t
*
client
);
void
iphone_lckd_free_client
(
iphone_lckd_client_t
client
);
iphone_error_t
iphone_lckd_free_client
(
iphone_lckd_client_t
client
);
i
nt
iphone_lckd_start_service
(
iphone_lckd_client_t
client
,
const
char
*
service
);
i
phone_error_t
iphone_lckd_start_service
(
iphone_lckd_client_t
client
,
const
char
*
service
,
int
*
port
);
i
nt
iphone_lckd_recv
(
iphone_lckd_client_t
client
,
char
**
dump_data
);
i
phone_error_t
iphone_lckd_recv
(
iphone_lckd_client_t
client
,
char
**
dump_data
,
uint32_t
*
recv_bytes
);
i
nt
iphone_lckd_send
(
iphone_lckd_client_t
client
,
char
*
raw_data
,
uint32_t
length
);
i
phone_error_t
iphone_lckd_send
(
iphone_lckd_client_t
client
,
char
*
raw_data
,
uint32_t
length
,
uint32_t
*
recv_bytes
);
//usbmux related functions
//usbmux related functions
i
n
t
iphone_mux_new_client
(
iphone_device_t
device
,
uint16_t
src_port
,
uint16_t
dst_port
,
iphone_umux_client_t
*
client
);
i
phone_error_
t
iphone_mux_new_client
(
iphone_device_t
device
,
uint16_t
src_port
,
uint16_t
dst_port
,
iphone_umux_client_t
*
client
);
void
iphone_mux_free_client
(
iphone_umux_client_t
client
);
iphone_error_t
iphone_mux_free_client
(
iphone_umux_client_t
client
);
i
nt
iphone_mux_send
(
iphone_umux_client_t
client
,
const
char
*
data
,
uint32_t
datalen
);
i
phone_error_t
iphone_mux_send
(
iphone_umux_client_t
client
,
const
char
*
data
,
uint32_t
datalen
,
uint32_t
*
sent_bytes
);
i
nt
iphone_mux_recv
(
iphone_umux_client_t
client
,
char
*
data
,
uint32_t
datalen
);
i
phone_error_t
iphone_mux_recv
(
iphone_umux_client_t
client
,
char
*
data
,
uint32_t
datalen
,
uint32_t
*
recv_bytes
);
//afc related functions
//afc related functions
i
n
t
iphone_afc_new_client
(
iphone_device_t
device
,
int
src_port
,
int
dst_port
,
iphone_afc_client_t
*
client
);
i
phone_error_
t
iphone_afc_new_client
(
iphone_device_t
device
,
int
src_port
,
int
dst_port
,
iphone_afc_client_t
*
client
);
void
iphone_afc_free_client
(
iphone_afc_client_t
client
);
iphone_error_t
iphone_afc_free_client
(
iphone_afc_client_t
client
);
char
**
iphone_afc_get_devinfo
(
iphone_afc_client_t
client
);
iphone_error_t
iphone_afc_get_devinfo
(
iphone_afc_client_t
client
,
char
***
infos
);
char
**
iphone_afc_get_dir_list
(
iphone_afc_client_t
client
,
const
char
*
dir
);
iphone_error_t
iphone_afc_get_dir_list
(
iphone_afc_client_t
client
,
const
char
*
dir
,
char
***
list
);
i
n
t
iphone_afc_get_file_attr
(
iphone_afc_client_t
client
,
const
char
*
filename
,
struct
stat
*
stbuf
);
i
phone_error_
t
iphone_afc_get_file_attr
(
iphone_afc_client_t
client
,
const
char
*
filename
,
struct
stat
*
stbuf
);
i
n
t
iphone_afc_open_file
(
iphone_afc_client_t
client
,
const
char
*
filename
,
uint32_t
file_mode
,
iphone_afc_file_t
*
file
);
i
phone_error_
t
iphone_afc_open_file
(
iphone_afc_client_t
client
,
const
char
*
filename
,
uint32_t
file_mode
,
iphone_afc_file_t
*
file
);
void
iphone_afc_close_file
(
iphone_afc_client_t
client
,
iphone_afc_file_t
file
);
iphone_error_t
iphone_afc_close_file
(
iphone_afc_client_t
client
,
iphone_afc_file_t
file
);
i
nt
iphone_afc_read_file
(
iphone_afc_client_t
client
,
iphone_afc_file_t
file
,
char
*
data
,
int
length
);
i
phone_error_t
iphone_afc_read_file
(
iphone_afc_client_t
client
,
iphone_afc_file_t
file
,
char
*
data
,
int
length
,
uint32_t
*
bytes
);
i
nt
iphone_afc_write_file
(
iphone_afc_client_t
client
,
iphone_afc_file_t
file
,
const
char
*
data
,
int
length
);
i
phone_error_t
iphone_afc_write_file
(
iphone_afc_client_t
client
,
iphone_afc_file_t
file
,
const
char
*
data
,
int
length
,
uint32_t
*
bytes
);
i
n
t
iphone_afc_seek_file
(
iphone_afc_client_t
client
,
iphone_afc_file_t
file
,
int
seekpos
);
i
phone_error_
t
iphone_afc_seek_file
(
iphone_afc_client_t
client
,
iphone_afc_file_t
file
,
int
seekpos
);
i
n
t
iphone_afc_truncate_file
(
iphone_afc_client_t
client
,
iphone_afc_file_t
file
,
uint32_t
newsize
);
i
phone_error_
t
iphone_afc_truncate_file
(
iphone_afc_client_t
client
,
iphone_afc_file_t
file
,
uint32_t
newsize
);
i
n
t
iphone_afc_delete_file
(
iphone_afc_client_t
client
,
const
char
*
path
);
i
phone_error_
t
iphone_afc_delete_file
(
iphone_afc_client_t
client
,
const
char
*
path
);
i
n
t
iphone_afc_rename_file
(
iphone_afc_client_t
client
,
const
char
*
from
,
const
char
*
to
);
i
phone_error_
t
iphone_afc_rename_file
(
iphone_afc_client_t
client
,
const
char
*
from
,
const
char
*
to
);
i
n
t
iphone_afc_mkdir
(
iphone_afc_client_t
client
,
const
char
*
dir
);
i
phone_error_
t
iphone_afc_mkdir
(
iphone_afc_client_t
client
,
const
char
*
dir
);
#ifdef __cplusplus
#ifdef __cplusplus
...
...
src/AFC.c
View file @
86f61988
...
@@ -58,7 +58,7 @@ static void afc_unlock(iphone_afc_client_t client) { // just to be pretty
...
@@ -58,7 +58,7 @@ static void afc_unlock(iphone_afc_client_t client) { // just to be pretty
*
*
* @return A handle to the newly-connected client or NULL upon error.
* @return A handle to the newly-connected client or NULL upon error.
*/
*/
i
n
t
iphone_afc_new_client
(
iphone_device_t
device
,
int
src_port
,
int
dst_port
,
iphone_afc_client_t
*
client
)
{
i
phone_error_
t
iphone_afc_new_client
(
iphone_device_t
device
,
int
src_port
,
int
dst_port
,
iphone_afc_client_t
*
client
)
{
int
ret
=
IPHONE_E_SUCCESS
;
int
ret
=
IPHONE_E_SUCCESS
;
iphone_afc_client_t
client_loc
=
(
iphone_afc_client_t
)
malloc
(
sizeof
(
struct
iphone_afc_client_int
));
iphone_afc_client_t
client_loc
=
(
iphone_afc_client_t
)
malloc
(
sizeof
(
struct
iphone_afc_client_int
));
...
@@ -100,12 +100,14 @@ int iphone_afc_new_client ( iphone_device_t device, int src_port, int dst_port,
...
@@ -100,12 +100,14 @@ int iphone_afc_new_client ( iphone_device_t device, int src_port, int dst_port,
*
*
* @param client The client to disconnect.
* @param client The client to disconnect.
*/
*/
void
iphone_afc_free_client
(
iphone_afc_client_t
client
)
{
iphone_error_t
iphone_afc_free_client
(
iphone_afc_client_t
client
)
{
if
(
!
client
||
!
client
->
connection
||
!
client
->
afc_packet
)
return
;
if
(
!
client
||
!
client
->
connection
||
!
client
->
afc_packet
)
return
IPHONE_E_INVALID_ARG
;
iphone_mux_free_client
(
client
->
connection
);
iphone_mux_free_client
(
client
->
connection
);
free
(
client
->
afc_packet
);
free
(
client
->
afc_packet
);
free
(
client
);
free
(
client
);
return
IPHONE_E_SUCCESS
;
}
}
...
@@ -324,11 +326,12 @@ static char **make_strings_list(char *tokens, int true_length) {
...
@@ -324,11 +326,12 @@ static char **make_strings_list(char *tokens, int true_length) {
* @return A char ** list of files in that directory, terminated by an empty
* @return A char ** list of files in that directory, terminated by an empty
* string for now or NULL if there was an error.
* string for now or NULL if there was an error.
*/
*/
char
**
iphone_afc_get_dir_list
(
iphone_afc_client_t
client
,
const
char
*
dir
)
{
iphone_error_t
iphone_afc_get_dir_list
(
iphone_afc_client_t
client
,
const
char
*
dir
,
char
***
list
)
{
int
bytes
=
0
;
int
bytes
=
0
;
char
*
data
=
NULL
,
**
list
=
NULL
;
char
*
data
=
NULL
,
**
list_loc
=
NULL
;
iphone_error_t
ret
=
IPHONE_E_UNKNOWN_ERROR
;
if
(
!
client
||
!
dir
)
return
NULL
;
if
(
!
client
||
!
dir
||
!
list
)
return
IPHONE_E_INVALID_ARG
;
afc_lock
(
client
);
afc_lock
(
client
);
...
@@ -339,23 +342,25 @@ char **iphone_afc_get_dir_list ( iphone_afc_client_t client, const char *dir) {
...
@@ -339,23 +342,25 @@ char **iphone_afc_get_dir_list ( iphone_afc_client_t client, const char *dir) {
bytes
=
dispatch_AFC_packet
(
client
,
dir
,
strlen
(
dir
));
bytes
=
dispatch_AFC_packet
(
client
,
dir
,
strlen
(
dir
));
if
(
bytes
<=
0
)
{
if
(
bytes
<=
0
)
{
afc_unlock
(
client
);
afc_unlock
(
client
);
return
NULL
;
return
IPHONE_E_NOT_ENOUGH_DATA
;
}
}
// Receive the data
// Receive the data
bytes
=
receive_AFC_data
(
client
,
&
data
);
bytes
=
receive_AFC_data
(
client
,
&
data
);
if
(
bytes
<
0
&&
!
data
)
{
if
(
bytes
<
0
&&
!
data
)
{
afc_unlock
(
client
);
afc_unlock
(
client
);
return
NULL
;
return
IPHONE_E_NOT_ENOUGH_DATA
;
}
}
// Parse the data
// Parse the data
list
=
make_strings_list
(
data
,
bytes
);
list_loc
=
make_strings_list
(
data
,
bytes
);
if
(
list_loc
)
ret
=
IPHONE_E_SUCCESS
;
if
(
data
)
free
(
data
);
if
(
data
)
free
(
data
);
afc_unlock
(
client
);
afc_unlock
(
client
);
*
list
=
list_loc
;
return
lis
t
;
return
re
t
;
}
}
/** Get device info for a client connection to phone. (free space on disk, etc.)
/** Get device info for a client connection to phone. (free space on disk, etc.)
...
@@ -365,11 +370,11 @@ char **iphone_afc_get_dir_list ( iphone_afc_client_t client, const char *dir) {
...
@@ -365,11 +370,11 @@ char **iphone_afc_get_dir_list ( iphone_afc_client_t client, const char *dir) {
* @return A char ** list of parameters as given by AFC or NULL if there was an
* @return A char ** list of parameters as given by AFC or NULL if there was an
* error.
* error.
*/
*/
char
**
iphone_afc_get_devinfo
(
iphone_afc_client_t
client
)
{
iphone_error_t
iphone_afc_get_devinfo
(
iphone_afc_client_t
client
,
char
***
infos
)
{
int
bytes
=
0
;
int
bytes
=
0
;
char
*
data
=
NULL
,
**
list
=
NULL
;
char
*
data
=
NULL
,
**
list
=
NULL
;
if
(
!
client
)
return
NULL
;
if
(
!
client
||
!
infos
)
return
IPHONE_E_INVALID_ARG
;
afc_lock
(
client
);
afc_lock
(
client
);
...
@@ -379,14 +384,14 @@ char **iphone_afc_get_devinfo ( iphone_afc_client_t client ) {
...
@@ -379,14 +384,14 @@ char **iphone_afc_get_devinfo ( iphone_afc_client_t client ) {
bytes
=
dispatch_AFC_packet
(
client
,
NULL
,
0
);
bytes
=
dispatch_AFC_packet
(
client
,
NULL
,
0
);
if
(
bytes
<
0
)
{
if
(
bytes
<
0
)
{
afc_unlock
(
client
);
afc_unlock
(
client
);
return
NULL
;
return
IPHONE_E_NOT_ENOUGH_DATA
;
}
}
// Receive the data
// Receive the data
bytes
=
receive_AFC_data
(
client
,
&
data
);
bytes
=
receive_AFC_data
(
client
,
&
data
);
if
(
bytes
<
0
&&
!
data
)
{
if
(
bytes
<
0
&&
!
data
)
{
afc_unlock
(
client
);
afc_unlock
(
client
);
return
NULL
;
return
IPHONE_E_NOT_ENOUGH_DATA
;
}
}
// Parse the data
// Parse the data
...
@@ -394,8 +399,8 @@ char **iphone_afc_get_devinfo ( iphone_afc_client_t client ) {
...
@@ -394,8 +399,8 @@ char **iphone_afc_get_devinfo ( iphone_afc_client_t client ) {
if
(
data
)
free
(
data
);
if
(
data
)
free
(
data
);
afc_unlock
(
client
);
afc_unlock
(
client
);
*
infos
=
list
;
return
list
;
return
IPHONE_E_SUCCESS
;
}
}
/** Deletes a file.
/** Deletes a file.
...
@@ -406,7 +411,7 @@ char **iphone_afc_get_devinfo ( iphone_afc_client_t client ) {
...
@@ -406,7 +411,7 @@ char **iphone_afc_get_devinfo ( iphone_afc_client_t client ) {
* @return IPHONE_E_SUCCESS if everythong went well, IPHONE_E_INVALID_ARG
* @return IPHONE_E_SUCCESS if everythong went well, IPHONE_E_INVALID_ARG
* if arguments are NULL or invalid, IPHONE_E_NOT_ENOUGH_DATA otherwise.
* if arguments are NULL or invalid, IPHONE_E_NOT_ENOUGH_DATA otherwise.
*/
*/
i
n
t
iphone_afc_delete_file
(
iphone_afc_client_t
client
,
const
char
*
path
)
{
i
phone_error_
t
iphone_afc_delete_file
(
iphone_afc_client_t
client
,
const
char
*
path
)
{
char
*
response
=
NULL
;
char
*
response
=
NULL
;
int
bytes
;
int
bytes
;
...
@@ -445,7 +450,7 @@ int iphone_afc_delete_file ( iphone_afc_client_t client, const char *path) {
...
@@ -445,7 +450,7 @@ int iphone_afc_delete_file ( iphone_afc_client_t client, const char *path) {
* @return IPHONE_E_SUCCESS if everythong went well, IPHONE_E_INVALID_ARG
* @return IPHONE_E_SUCCESS if everythong went well, IPHONE_E_INVALID_ARG
* if arguments are NULL or invalid, IPHONE_E_NOT_ENOUGH_DATA otherwise.
* if arguments are NULL or invalid, IPHONE_E_NOT_ENOUGH_DATA otherwise.
*/
*/
i
n
t
iphone_afc_rename_file
(
iphone_afc_client_t
client
,
const
char
*
from
,
const
char
*
to
)
{
i
phone_error_
t
iphone_afc_rename_file
(
iphone_afc_client_t
client
,
const
char
*
from
,
const
char
*
to
)
{
char
*
response
=
NULL
;
char
*
response
=
NULL
;
char
*
send
=
(
char
*
)
malloc
(
sizeof
(
char
)
*
(
strlen
(
from
)
+
strlen
(
to
)
+
1
+
sizeof
(
uint32
)));
char
*
send
=
(
char
*
)
malloc
(
sizeof
(
char
)
*
(
strlen
(
from
)
+
strlen
(
to
)
+
1
+
sizeof
(
uint32
)));
int
bytes
=
0
;
int
bytes
=
0
;
...
@@ -488,7 +493,7 @@ int iphone_afc_rename_file ( iphone_afc_client_t client, const char *from, const
...
@@ -488,7 +493,7 @@ int iphone_afc_rename_file ( iphone_afc_client_t client, const char *from, const
* @return IPHONE_E_SUCCESS if everythong went well, IPHONE_E_INVALID_ARG
* @return IPHONE_E_SUCCESS if everythong went well, IPHONE_E_INVALID_ARG
* if arguments are NULL or invalid, IPHONE_E_NOT_ENOUGH_DATA otherwise.
* if arguments are NULL or invalid, IPHONE_E_NOT_ENOUGH_DATA otherwise.
*/
*/
i
n
t
iphone_afc_mkdir
(
iphone_afc_client_t
client
,
const
char
*
dir
)
{
i
phone_error_
t
iphone_afc_mkdir
(
iphone_afc_client_t
client
,
const
char
*
dir
)
{
int
bytes
=
0
;
int
bytes
=
0
;
char
*
response
=
NULL
;
char
*
response
=
NULL
;
...
@@ -586,7 +591,7 @@ iphone_afc_file_t afc_get_file_info(iphone_afc_client_t client, const char *path
...
@@ -586,7 +591,7 @@ iphone_afc_file_t afc_get_file_info(iphone_afc_client_t client, const char *path
* @return A pointer to an AFCFile struct containing the information received,
* @return A pointer to an AFCFile struct containing the information received,
* or NULL on failure.
* or NULL on failure.
*/
*/
i
n
t
iphone_afc_get_file_attr
(
iphone_afc_client_t
client
,
const
char
*
filename
,
struct
stat
*
stbuf
)
{
i
phone_error_
t
iphone_afc_get_file_attr
(
iphone_afc_client_t
client
,
const
char
*
filename
,
struct
stat
*
stbuf
)
{
int
ret
=
IPHONE_E_SUCCESS
;
int
ret
=
IPHONE_E_SUCCESS
;
if
(
!
client
||!
client
->
connection
||
!
client
->
afc_packet
||
!
stbuf
)
return
IPHONE_E_INVALID_ARG
;
if
(
!
client
||!
client
->
connection
||
!
client
->
afc_packet
||
!
stbuf
)
return
IPHONE_E_INVALID_ARG
;
...
@@ -620,7 +625,7 @@ int iphone_afc_get_file_attr ( iphone_afc_client_t client, const char *filename,
...
@@ -620,7 +625,7 @@ int iphone_afc_get_file_attr ( iphone_afc_client_t client, const char *filename,
* received by afc_get_file_info) as well as the handle to the file or
* received by afc_get_file_info) as well as the handle to the file or
* NULL in the case of failure.
* NULL in the case of failure.
*/
*/
i
n
t
iphone_afc_open_file
(
iphone_afc_client_t
client
,
const
char
*
filename
,
uint32_t
file_mode
,
iphone_afc_file_t
*
file
)
{
i
phone_error_
t
iphone_afc_open_file
(
iphone_afc_client_t
client
,
const
char
*
filename
,
uint32_t
file_mode
,
iphone_afc_file_t
*
file
)
{
iphone_afc_file_t
file_loc
=
NULL
;
iphone_afc_file_t
file_loc
=
NULL
;
uint32
ag
=
0
;
uint32
ag
=
0
;
int
bytes
=
0
,
length
=
0
;
int
bytes
=
0
,
length
=
0
;
...
@@ -677,12 +682,12 @@ int iphone_afc_open_file ( iphone_afc_client_t client, const char *filename, uin
...
@@ -677,12 +682,12 @@ int iphone_afc_open_file ( iphone_afc_client_t client, const char *filename, uin
*
*
* @return The number of bytes read if successful. If there was an error -1.
* @return The number of bytes read if successful. If there was an error -1.
*/
*/
i
nt
iphone_afc_read_file
(
iphone_afc_client_t
client
,
iphone_afc_file_t
file
,
char
*
data
,
int
length
)
{
i
phone_error_t
iphone_afc_read_file
(
iphone_afc_client_t
client
,
iphone_afc_file_t
file
,
char
*
data
,
int
length
,
uint32_t
*
bytes
)
{
char
*
input
=
NULL
;
char
*
input
=
NULL
;
int
current_count
=
0
,
bytes
=
0
;
int
current_count
=
0
,
bytes
_loc
=
0
;
const
int
MAXIMUM_READ_SIZE
=
1
<<
16
;
const
int
MAXIMUM_READ_SIZE
=
1
<<
16
;
if
(
!
client
||
!
client
->
afc_packet
||
!
client
->
connection
||
!
file
)
return
-
1
;
if
(
!
client
||
!
client
->
afc_packet
||
!
client
->
connection
||
!
file
)
return
IPHONE_E_INVALID_ARG
;
if
(
debug
)
fprintf
(
stderr
,
"afc_read_file called for length %i
\n
"
,
length
);
if
(
debug
)
fprintf
(
stderr
,
"afc_read_file called for length %i
\n
"
,
length
);
afc_lock
(
client
);
afc_lock
(
client
);
...
@@ -698,40 +703,41 @@ int iphone_afc_read_file ( iphone_afc_client_t client, iphone_afc_file_t file, c
...
@@ -698,40 +703,41 @@ int iphone_afc_read_file ( iphone_afc_client_t client, iphone_afc_file_t file, c
packet
->
size
=
((
length
-
current_count
)
<
MAXIMUM_READ_SIZE
)
?
(
length
-
current_count
)
:
MAXIMUM_READ_SIZE
;
packet
->
size
=
((
length
-
current_count
)
<
MAXIMUM_READ_SIZE
)
?
(
length
-
current_count
)
:
MAXIMUM_READ_SIZE
;
client
->
afc_packet
->
operation
=
AFC_READ
;
client
->
afc_packet
->
operation
=
AFC_READ
;
client
->
afc_packet
->
entire_length
=
client
->
afc_packet
->
this_length
=
0
;
client
->
afc_packet
->
entire_length
=
client
->
afc_packet
->
this_length
=
0
;
bytes
=
dispatch_AFC_packet
(
client
,
(
char
*
)
packet
,
sizeof
(
AFCFilePacket
));
bytes
_loc
=
dispatch_AFC_packet
(
client
,
(
char
*
)
packet
,
sizeof
(
AFCFilePacket
));
free
(
packet
);
free
(
packet
);
if
(
bytes
<=
0
)
{
if
(
bytes
_loc
<=
0
)
{
afc_unlock
(
client
);
afc_unlock
(
client
);
return
-
1
;
return
IPHONE_E_NOT_ENOUGH_DATA
;
}
}
// Receive the data
// Receive the data
bytes
=
receive_AFC_data
(
client
,
&
input
);
bytes
_loc
=
receive_AFC_data
(
client
,
&
input
);
if
(
debug
)
fprintf
(
stderr
,
"afc_read_file: bytes returned: %i
\n
"
,
bytes
);
if
(
debug
)
fprintf
(
stderr
,
"afc_read_file: bytes returned: %i
\n
"
,
bytes
_loc
);
if
(
bytes
<
0
)
{
if
(
bytes
<
0
)
{
if
(
input
)
free
(
input
);
if
(
input
)
free
(
input
);
afc_unlock
(
client
);
afc_unlock
(
client
);
return
-
1
;
return
IPHONE_E_NOT_ENOUGH_DATA
;
}
else
if
(
bytes
==
0
)
{
}
else
if
(
bytes
==
0
)
{
if
(
input
)
free
(
input
);
if
(
input
)
free
(
input
);
afc_unlock
(
client
);
afc_unlock
(
client
);
return
current_count
;
*
bytes
=
current_count
;
return
IPHONE_E_SUCCESS
;
//FIXME check that's actually a success
}
else
{
}
else
{
if
(
input
)
{
if
(
input
)
{
if
(
debug
)
fprintf
(
stderr
,
"afc_read_file: %d
\n
"
,
bytes
);
if
(
debug
)
fprintf
(
stderr
,
"afc_read_file: %d
\n
"
,
bytes
_loc
);
memcpy
(
data
+
current_count
,
input
,
(
bytes
>
length
)
?
length
:
bytes
);
memcpy
(
data
+
current_count
,
input
,
(
bytes
_loc
>
length
)
?
length
:
bytes_loc
);
free
(
input
);
free
(
input
);
input
=
NULL
;
input
=
NULL
;
current_count
+=
(
bytes
>
length
)
?
length
:
bytes
;
current_count
+=
(
bytes
_loc
>
length
)
?
length
:
bytes_loc
;
}
}
}
}
}
}
if
(
debug
)
fprintf
(
stderr
,
"afc_read_file: returning current_count as %i
\n
"
,
current_count
);
if
(
debug
)
fprintf
(
stderr
,
"afc_read_file: returning current_count as %i
\n
"
,
current_count
);
afc_unlock
(
client
);
afc_unlock
(
client
);
*
bytes
=
current_count
;
return
current_count
;
return
IPHONE_E_SUCCESS
;
}
}
/** Writes a given number of bytes to a file.
/** Writes a given number of bytes to a file.
...
@@ -744,13 +750,13 @@ int iphone_afc_read_file ( iphone_afc_client_t client, iphone_afc_file_t file, c
...
@@ -744,13 +750,13 @@ int iphone_afc_read_file ( iphone_afc_client_t client, iphone_afc_file_t file, c
* @return The number of bytes written to the file, or a value less than 0 if
* @return The number of bytes written to the file, or a value less than 0 if
* none were written...
* none were written...
*/
*/
i
nt
iphone_afc_write_file
(
iphone_afc_client_t
client
,
iphone_afc_file_t
file
,
const
char
*
data
,
int
length
)
{
i
phone_error_t
iphone_afc_write_file
(
iphone_afc_client_t
client
,
iphone_afc_file_t
file
,
const
char
*
data
,
int
length
,
uint32_t
*
bytes
)
{
char
*
acknowledgement
=
NULL
;
char
*
acknowledgement
=
NULL
;
const
int
MAXIMUM_WRITE_SIZE
=
1
<<
16
;
const
int
MAXIMUM_WRITE_SIZE
=
1
<<
16
;
uint32
zero
=
0
,
bytes
=
0
,
segments
=
(
length
/
MAXIMUM_WRITE_SIZE
),
current_count
=
0
,
i
=
0
;
uint32
zero
=
0
,
bytes
_loc
=
0
,
segments
=
(
length
/
MAXIMUM_WRITE_SIZE
),
current_count
=
0
,
i
=
0
;
char
*
out_buffer
=
NULL
;
char
*
out_buffer
=
NULL
;
if
(
!
client
||!
client
->
afc_packet
||
!
client
->
connection
||
!
file
)
return
-
1
;
if
(
!
client
||!
client
->
afc_packet
||
!
client
->
connection
||
!
file
||
!
bytes_loc
)
return
IPHONE_E_INVALID_ARG
;
afc_lock
(
client
);
afc_lock
(
client
);
...
@@ -766,19 +772,19 @@ int iphone_afc_write_file ( iphone_afc_client_t client, iphone_afc_file_t file,
...
@@ -766,19 +772,19 @@ int iphone_afc_write_file ( iphone_afc_client_t client, iphone_afc_file_t file,
memcpy
(
out_buffer
,
(
char
*
)
&
file
->
filehandle
,
sizeof
(
uint32
));
memcpy
(
out_buffer
,
(
char
*
)
&
file
->
filehandle
,
sizeof
(
uint32
));
memcpy
(
out_buffer
+
4
,
(
char
*
)
&
zero
,
sizeof
(
uint32
));
memcpy
(
out_buffer
+
4
,
(
char
*
)
&
zero
,
sizeof
(
uint32
));
memcpy
(
out_buffer
+
8
,
data
+
current_count
,
MAXIMUM_WRITE_SIZE
);
memcpy
(
out_buffer
+
8
,
data
+
current_count
,
MAXIMUM_WRITE_SIZE
);
bytes
=
dispatch_AFC_packet
(
client
,
out_buffer
,
MAXIMUM_WRITE_SIZE
+
8
);
bytes
_loc
=
dispatch_AFC_packet
(
client
,
out_buffer
,
MAXIMUM_WRITE_SIZE
+
8
);
if
(
bytes
<
0
)
{
if
(
bytes
_loc
<
0
)
{
afc_unlock
(
client
);
afc_unlock
(
client
);
return
bytes
;
return
IPHONE_E_NOT_ENOUGH_DATA
;
}
}
free
(
out_buffer
);
free
(
out_buffer
);
out_buffer
=
NULL
;
out_buffer
=
NULL
;
current_count
+=
bytes
;
current_count
+=
bytes
_loc
;
bytes
=
receive_AFC_data
(
client
,
&
acknowledgement
);
bytes
_loc
=
receive_AFC_data
(
client
,
&
acknowledgement
);
if
(
bytes
<
0
)
{
if
(
bytes
_loc
<
0
)
{
afc_unlock
(
client
);
afc_unlock
(
client
);
return
current_count
;
return
IPHONE_E_NOT_ENOUGH_DATA
;
}
}
}
}
...
@@ -786,7 +792,8 @@ int iphone_afc_write_file ( iphone_afc_client_t client, iphone_afc_file_t file,
...
@@ -786,7 +792,8 @@ int iphone_afc_write_file ( iphone_afc_client_t client, iphone_afc_file_t file,
// this length is fine because it's always sizeof(AFCPacket) + 8, but to be sure we do it again
// this length is fine because it's always sizeof(AFCPacket) + 8, but to be sure we do it again
if
(
current_count
==
length
)
{
if
(
current_count
==
length
)
{
afc_unlock
(
client
);
afc_unlock
(
client
);
return
current_count
;
*
bytes
=
current_count
;
return
IPHONE_E_SUCCESS
;
}
}
client
->
afc_packet
->
this_length
=
sizeof
(
AFCPacket
)
+
8
;
client
->
afc_packet
->
this_length
=
sizeof
(
AFCPacket
)
+
8
;
...
@@ -796,25 +803,26 @@ int iphone_afc_write_file ( iphone_afc_client_t client, iphone_afc_file_t file,
...
@@ -796,25 +803,26 @@ int iphone_afc_write_file ( iphone_afc_client_t client, iphone_afc_file_t file,
memcpy
(
out_buffer
,
(
char
*
)
&
file
->
filehandle
,
sizeof
(
uint32
));
memcpy
(
out_buffer
,
(
char
*
)
&
file
->
filehandle
,
sizeof
(
uint32
));
memcpy
(
out_buffer
+
4
,
(
char
*
)
&
zero
,
sizeof
(
uint32
));
memcpy
(
out_buffer
+
4
,
(
char
*
)
&
zero
,
sizeof
(
uint32
));
memcpy
(
out_buffer
+
8
,
data
+
current_count
,
(
length
-
current_count
));
memcpy
(
out_buffer
+
8
,
data
+
current_count
,
(
length
-
current_count
));
bytes
=
dispatch_AFC_packet
(
client
,
out_buffer
,
(
length
-
current_count
)
+
8
);
bytes
_loc
=
dispatch_AFC_packet
(
client
,
out_buffer
,
(
length
-
current_count
)
+
8
);
free
(
out_buffer
);
free
(
out_buffer
);
out_buffer
=
NULL
;
out_buffer
=
NULL
;
current_count
+=
bytes
;
current_count
+=
bytes
_loc
;
if
(
bytes
<=
0
)
{
if
(
bytes
_loc
<=
0
)
{
afc_unlock
(
client
);
afc_unlock
(
client
);
return
current_count
;
*
bytes
=
current_count
;
return
IPHONE_E_SUCCESS
;
}
}
zero
=
bytes
;
zero
=
bytes
_loc
;
bytes
=
receive_AFC_data
(
client
,
&
acknowledgement
);
bytes
_loc
=
receive_AFC_data
(
client
,
&
acknowledgement
);
afc_unlock
(
client
);
afc_unlock
(
client
);
if
(
bytes
<
0
)
{
if
(
bytes
_loc
<
0
)
{
if
(
debug
)
fprintf
(
stderr
,
"afc_write_file: uh oh?
\n
"
);
if
(
debug
)
fprintf
(
stderr
,
"afc_write_file: uh oh?
\n
"
);
}
}
return
current_count
;
return
IPHONE_E_UNKNOWN_ERROR
;
}
}
/** Closes a file on the phone.
/** Closes a file on the phone.
...
@@ -823,7 +831,8 @@ int iphone_afc_write_file ( iphone_afc_client_t client, iphone_afc_file_t file,
...
@@ -823,7 +831,8 @@ int iphone_afc_write_file ( iphone_afc_client_t client, iphone_afc_file_t file,
* @param file A pointer to an AFCFile struct containing the file handle of the
* @param file A pointer to an AFCFile struct containing the file handle of the
* file to close.
* file to close.
*/
*/
void
iphone_afc_close_file
(
iphone_afc_client_t
client
,
iphone_afc_file_t
file
)
{
iphone_error_t
iphone_afc_close_file
(
iphone_afc_client_t
client
,
iphone_afc_file_t
file
)
{
if
(
!
client
||
!
file
)
return
IPHONE_E_INVALID_ARG
;
char
*
buffer
=
malloc
(
sizeof
(
char
)
*
8
);
char
*
buffer
=
malloc
(
sizeof
(
char
)
*
8
);
uint32
zero
=
0
;
uint32
zero
=
0
;
int
bytes
=
0
;
int
bytes
=
0
;
...
@@ -846,7 +855,7 @@ void iphone_afc_close_file ( iphone_afc_client_t client, iphone_afc_file_t file)
...
@@ -846,7 +855,7 @@ void iphone_afc_close_file ( iphone_afc_client_t client, iphone_afc_file_t file)
if
(
bytes
<=
0
)
{
if
(
bytes
<=
0
)
{
afc_unlock
(
client
);
afc_unlock
(
client
);
return
;
return
IPHONE_E_UNKNOWN_ERROR
;
}
}
// Receive the response
// Receive the response
...
@@ -854,6 +863,7 @@ void iphone_afc_close_file ( iphone_afc_client_t client, iphone_afc_file_t file)
...
@@ -854,6 +863,7 @@ void iphone_afc_close_file ( iphone_afc_client_t client, iphone_afc_file_t file)
if
(
buffer
)
free
(
buffer
);
if
(
buffer
)
free
(
buffer
);
free
(
file
);
free
(
file
);
afc_unlock
(
client
);
afc_unlock
(
client
);
return
IPHONE_E_SUCCESS
;
}
}
/** Seeks to a given position of a pre-opened file on the phone.
/** Seeks to a given position of a pre-opened file on the phone.
...
@@ -865,7 +875,7 @@ void iphone_afc_close_file ( iphone_afc_client_t client, iphone_afc_file_t file)
...
@@ -865,7 +875,7 @@ void iphone_afc_close_file ( iphone_afc_client_t client, iphone_afc_file_t file)
*
*
* @return IPHONE_E_SUCCESS on success, IPHONE_E_NOT_ENOUGH_DATA on failure.
* @return IPHONE_E_SUCCESS on success, IPHONE_E_NOT_ENOUGH_DATA on failure.
*/
*/
i
n
t
iphone_afc_seek_file
(
iphone_afc_client_t
client
,
iphone_afc_file_t
file
,
int
seekpos
)
{
i
phone_error_
t
iphone_afc_seek_file
(
iphone_afc_client_t
client
,
iphone_afc_file_t
file
,
int
seekpos
)
{
char
*
buffer
=
(
char
*
)
malloc
(
sizeof
(
char
)
*
24
);
char
*
buffer
=
(
char
*
)
malloc
(
sizeof
(
char
)
*
24
);
uint32
seekto
=
0
,
bytes
=
0
,
zero
=
0
;
uint32
seekto
=
0
,
bytes
=
0
,
zero
=
0
;
...
@@ -916,7 +926,7 @@ int iphone_afc_seek_file ( iphone_afc_client_t client, iphone_afc_file_t file, i
...
@@ -916,7 +926,7 @@ int iphone_afc_seek_file ( iphone_afc_client_t client, iphone_afc_file_t file, i
* @note This function is more akin to ftruncate than truncate, and truncate
* @note This function is more akin to ftruncate than truncate, and truncate
* calls would have to open the file before calling this, sadly.
* calls would have to open the file before calling this, sadly.
*/
*/
i
n
t
iphone_afc_truncate_file
(
iphone_afc_client_t
client
,
iphone_afc_file_t
file
,
uint32_t
newsize
)
{
i
phone_error_
t
iphone_afc_truncate_file
(
iphone_afc_client_t
client
,
iphone_afc_file_t
file
,
uint32_t
newsize
)
{
char
*
buffer
=
(
char
*
)
malloc
(
sizeof
(
char
)
*
16
);
char
*
buffer
=
(
char
*
)
malloc
(
sizeof
(
char
)
*
16
);
uint32
bytes
=
0
,
zero
=
0
;
uint32
bytes
=
0
,
zero
=
0
;
...
...
src/iphone.c
View file @
86f61988
...
@@ -34,7 +34,7 @@ extern int debug;
...
@@ -34,7 +34,7 @@ extern int debug;
* @return A structure with data on the first iPhone it finds. (Or NULL, on
* @return A structure with data on the first iPhone it finds. (Or NULL, on
* error)
* error)
*/
*/
i
nt
iphone_get_device
(
iphone_device_t
*
device
){
i
phone_error_t
iphone_get_device
(
iphone_device_t
*
device
){
//check we can actually write in device
//check we can actually write in device
if
(
!
device
||
(
device
&&
*
device
))
if
(
!
device
||
(
device
&&
*
device
))
return
IPHONE_E_INVALID_ARG
;
return
IPHONE_E_INVALID_ARG
;
...
@@ -102,7 +102,7 @@ int iphone_get_device ( iphone_device_t *device ){
...
@@ -102,7 +102,7 @@ int iphone_get_device ( iphone_device_t *device ){
iphone_free_device
(
phone
);
iphone_free_device
(
phone
);
if
(
debug
)
fprintf
(
stderr
,
"get_iPhone(): Invalid version message -- header too short.
\n
"
);
if
(
debug
)
fprintf
(
stderr
,
"get_iPhone(): Invalid version message -- header too short.
\n
"
);
if
(
debug
&&
bytes
<
0
)
fprintf
(
stderr
,
"get_iPhone(): libusb error message %d: %s (%s)
\n
"
,
if
(
debug
&&
bytes
<
0
)
fprintf
(
stderr
,
"get_iPhone(): libusb error message %d: %s (%s)
\n
"
,
bytes
,
usb_strerror
(),
strerror
(
-
bytes
));
bytes
,
usb_strerror
(),
strerror
(
-
bytes
));
return
IPHONE_E_NOT_ENOUGH_DATA
;
return
IPHONE_E_NOT_ENOUGH_DATA
;
}
}
...
@@ -134,14 +134,21 @@ int iphone_get_device ( iphone_device_t *device ){
...
@@ -134,14 +134,21 @@ int iphone_get_device ( iphone_device_t *device ){
*
*
* @param phone A pointer to an iPhone structure.
* @param phone A pointer to an iPhone structure.
*/
*/
void
iphone_free_device
(
iphone_device_t
device
)
{
iphone_error_t
iphone_free_device
(
iphone_device_t
device
)
{
if
(
device
->
buffer
)
free
(
device
->
buffer
);
if
(
!
device
)
return
IPHONE_E_INVALID_ARG
;
if
(
device
->
device
)
{
iphone_error_t
ret
=
IPHONE_E_UNKNOWN_ERROR
;
usb_release_interface
(
device
->
device
,
1
);
usb_reset
(
device
->
device
);
if
(
device
->
buffer
)
{
usb_close
(
device
->
device
);
free
(
device
->
buffer
);
if
(
device
->
device
)
{
usb_release_interface
(
device
->
device
,
1
);
usb_reset
(
device
->
device
);
usb_close
(
device
->
device
);
ret
=
IPHONE_E_SUCCESS
;
}
free
(
device
);
}
}
free
(
device
)
;
return
ret
;
}
}
/** Sends data to the phone
/** Sends data to the phone
...
...
src/lockdown.c
View file @
86f61988
...
@@ -94,15 +94,18 @@ iphone_lckd_client_t new_lockdownd_client(iphone_device_t phone) {
...
@@ -94,15 +94,18 @@ iphone_lckd_client_t new_lockdownd_client(iphone_device_t phone) {
*
*
* @param control The lockdown client
* @param control The lockdown client
*/
*/
void
iphone_lckd_free_client
(
iphone_lckd_client_t
client
)
{
iphone_error_t
iphone_lckd_free_client
(
iphone_lckd_client_t
client
)
{
if
(
!
client
)
return
;
if
(
!
client
)
return
IPHONE_E_INVALID_ARG
;
iphone_error_t
ret
=
IPHONE_E_UNKNOWN_ERROR
;
if
(
client
->
connection
)
{
if
(
client
->
connection
)
{
iphone_mux_free_client
(
client
->
connection
);
ret
=
iphone_mux_free_client
(
client
->
connection
);
}
}
if
(
client
->
ssl_session
)
gnutls_deinit
(
*
client
->
ssl_session
);
if
(
client
->
ssl_session
)
gnutls_deinit
(
*
client
->
ssl_session
);
free
(
client
->
ssl_session
);
free
(
client
->
ssl_session
);
free
(
client
);
free
(
client
);
return
ret
;
}
}
/** Polls the iPhone for lockdownd data.
/** Polls the iPhone for lockdownd data.
...
@@ -113,20 +116,28 @@ void iphone_lckd_free_client( iphone_lckd_client_t client ) {
...
@@ -113,20 +116,28 @@ void iphone_lckd_free_client( iphone_lckd_client_t client ) {
*
*
* @return The number of bytes received
* @return The number of bytes received
*/
*/
int
iphone_lckd_recv
(
iphone_lckd_client_t
client
,
char
**
dump_data
)
{
iphone_error_t
iphone_lckd_recv
(
iphone_lckd_client_t
client
,
char
**
dump_data
,
uint32_t
*
recv_bytes
)
{
if
(
!
client
)
return
0
;
if
(
!
client
||
dump_data
||
!
recv_bytes
)
return
IPHONE_E_INVALID_ARG
;
iphone_error_t
ret
=
IPHONE_E_UNKNOWN_ERROR
;
char
*
receive
;
char
*
receive
;
uint32
datalen
=
0
,
bytes
=
0
;
uint32
datalen
=
0
,
bytes
=
0
;
if
(
!
client
->
in_SSL
)
bytes
=
iphone_mux_recv
(
client
->
connection
,
(
char
*
)
&
datalen
,
sizeof
(
datalen
));
if
(
!
client
->
in_SSL
)
ret
=
iphone_mux_recv
(
client
->
connection
,
(
char
*
)
&
datalen
,
sizeof
(
datalen
),
&
bytes
);
else
bytes
=
gnutls_record_recv
(
*
client
->
ssl_session
,
&
datalen
,
sizeof
(
datalen
));
else
{
bytes
=
gnutls_record_recv
(
*
client
->
ssl_session
,
&
datalen
,
sizeof
(
datalen
));
if
(
bytes
>
0
)
ret
=
IPHONE_E_SUCCESS
;
}
datalen
=
ntohl
(
datalen
);
datalen
=
ntohl
(
datalen
);
receive
=
(
char
*
)
malloc
(
sizeof
(
char
)
*
datalen
);
receive
=
(
char
*
)
malloc
(
sizeof
(
char
)
*
datalen
);
if
(
!
client
->
in_SSL
)
bytes
=
iphone_mux_recv
(
client
->
connection
,
receive
,
datalen
);
if
(
!
client
->
in_SSL
)
ret
=
iphone_mux_recv
(
client
->
connection
,
receive
,
datalen
,
&
bytes
);
else
bytes
=
gnutls_record_recv
(
*
client
->
ssl_session
,
receive
,
datalen
);
else
{
bytes
=
gnutls_record_recv
(
*
client
->
ssl_session
,
receive
,
datalen
);
if
(
bytes
>
0
)
ret
=
IPHONE_E_SUCCESS
;
}
*
dump_data
=
receive
;
*
dump_data
=
receive
;
return
bytes
;
*
recv_bytes
=
bytes
;
return
ret
;
}
}
/** Sends lockdownd data to the iPhone
/** Sends lockdownd data to the iPhone
...
@@ -140,11 +151,12 @@ int iphone_lckd_recv ( iphone_lckd_client_t client, char **dump_data ) {
...
@@ -140,11 +151,12 @@ int iphone_lckd_recv ( iphone_lckd_client_t client, char **dump_data ) {
*
*
* @return The number of bytes sent
* @return The number of bytes sent
*/
*/
i
nt
iphone_lckd_send
(
iphone_lckd_client_t
client
,
char
*
raw_data
,
uint32_t
length
)
{
i
phone_error_t
iphone_lckd_send
(
iphone_lckd_client_t
client
,
char
*
raw_data
,
uint32_t
length
,
uint32_t
*
sent_bytes
)
{
if
(
!
client
)
return
0
;
if
(
!
client
||
!
raw_data
||
length
==
0
||
!
sent_bytes
)
return
IPHONE_E_INVALID_ARG
;
char
*
real_query
;
char
*
real_query
;
int
bytes
;
int
bytes
;
iphone_error_t
ret
=
IPHONE_E_UNKNOWN_ERROR
;
real_query
=
(
char
*
)
malloc
(
sizeof
(
char
)
*
(
length
+
4
));
real_query
=
(
char
*
)
malloc
(
sizeof
(
char
)
*
(
length
+
4
));
length
=
htonl
(
length
);
length
=
htonl
(
length
);
memcpy
(
real_query
,
&
length
,
sizeof
(
length
));
memcpy
(
real_query
,
&
length
,
sizeof
(
length
));
...
@@ -157,11 +169,15 @@ int iphone_lckd_send ( iphone_lckd_client_t client, char *raw_data, uint32_t len
...
@@ -157,11 +169,15 @@ int iphone_lckd_send ( iphone_lckd_client_t client, char *raw_data, uint32_t len
packet
=
NULL
;
packet
=
NULL
;
}
}
if
(
!
client
->
in_SSL
)
bytes
=
iphone_mux_send
(
client
->
connection
,
real_query
,
ntohl
(
length
)
+
sizeof
(
length
));
if
(
!
client
->
in_SSL
)
ret
=
iphone_mux_send
(
client
->
connection
,
real_query
,
ntohl
(
length
)
+
sizeof
(
length
),
&
bytes
);
else
gnutls_record_send
(
*
client
->
ssl_session
,
real_query
,
ntohl
(
length
)
+
sizeof
(
length
));
else
{
gnutls_record_send
(
*
client
->
ssl_session
,
real_query
,
ntohl
(
length
)
+
sizeof
(
length
));
ret
=
IPHONE_E_SUCCESS
;
}
if
(
debug
)
printf
(
"lockdownd_send(): sent it!
\n
"
);
if
(
debug
)
printf
(
"lockdownd_send(): sent it!
\n
"
);
free
(
real_query
);
free
(
real_query
);
return
bytes
;
*
sent_bytes
=
bytes
;
return
ret
;
}
}
/** Initiates the handshake for the lockdown session. Part of the lockdownd handshake.
/** Initiates the handshake for the lockdown session. Part of the lockdownd handshake.
...
@@ -307,11 +323,11 @@ int lockdownd_get_device_public_key(iphone_lckd_client_t control, char **public_
...
@@ -307,11 +323,11 @@ int lockdownd_get_device_public_key(iphone_lckd_client_t control, char **public_
*
*
* @return 1 on success and 0 on failure
* @return 1 on success and 0 on failure
*/
*/
i
n
t
iphone_lckd_new_client
(
iphone_device_t
device
,
iphone_lckd_client_t
*
client
)
i
phone_error_
t
iphone_lckd_new_client
(
iphone_device_t
device
,
iphone_lckd_client_t
*
client
)
{
{
if
(
!
device
||
!
client
||
(
client
&&
*
client
)
)
if
(
!
device
||
!
client
||
(
client
&&
*
client
)
)
return
IPHONE_E_INVALID_ARG
;
return
IPHONE_E_INVALID_ARG
;
i
n
t
ret
=
IPHONE_E_SUCCESS
;
i
phone_error_
t
ret
=
IPHONE_E_SUCCESS
;
char
*
host_id
=
NULL
;
char
*
host_id
=
NULL
;
iphone_lckd_client_t
client_loc
=
new_lockdownd_client
(
device
);
iphone_lckd_client_t
client_loc
=
new_lockdownd_client
(
device
);
...
@@ -815,14 +831,15 @@ ssize_t lockdownd_securead(gnutls_transport_ptr_t transport, char *buffer, size_
...
@@ -815,14 +831,15 @@ ssize_t lockdownd_securead(gnutls_transport_ptr_t transport, char *buffer, size_
*
*
* @return The port number the service was started on or 0 on failure.
* @return The port number the service was started on or 0 on failure.
*/
*/
i
nt
iphone_lckd_start_service
(
iphone_lckd_client_t
client
,
const
char
*
service
)
{
i
phone_error_t
iphone_lckd_start_service
(
iphone_lckd_client_t
client
,
const
char
*
service
,
int
*
port
)
{
if
(
!
client
)
return
0
;
if
(
!
client
||
!
service
||
!
port
)
return
IPHONE_E_INVALID_ARG
;
char
*
host_id
=
get_host_id
();
char
*
host_id
=
get_host_id
();
if
(
host_id
&&
!
client
->
in_SSL
&&
!
lockdownd_start_SSL_session
(
client
,
host_id
))
return
0
;
if
(
!
host_id
)
return
IPHONE_E_INVALID_CONF
;
if
(
!
client
->
in_SSL
&&
!
lockdownd_start_SSL_session
(
client
,
host_id
))
return
IPHONE_E_SSL_ERROR
;
char
*
XML_query
,
**
dictionary
;
char
*
XML_query
,
**
dictionary
;
uint32
length
,
i
=
0
,
port
=
0
;
uint32
length
,
i
=
0
,
port
_loc
=
0
;
uint8
result
=
0
;
uint8
result
=
0
;
free
(
host_id
);
free
(
host_id
);
...
@@ -832,9 +849,9 @@ int iphone_lckd_start_service ( iphone_lckd_client_t client, const char *service
...
@@ -832,9 +849,9 @@ int iphone_lckd_start_service ( iphone_lckd_client_t client, const char *service
xmlNode
*
dict
=
add_child_to_plist
(
plist
,
"dict"
,
"
\n
"
,
NULL
,
0
);
xmlNode
*
dict
=
add_child_to_plist
(
plist
,
"dict"
,
"
\n
"
,
NULL
,
0
);
xmlNode
*
key
;
xmlNode
*
key
;
key
=
add_key_str_dict_element
(
plist
,
dict
,
"Request"
,
"StartService"
,
1
);
key
=
add_key_str_dict_element
(
plist
,
dict
,
"Request"
,
"StartService"
,
1
);
if
(
!
key
)
{
xmlFreeDoc
(
plist
);
return
0
;
}
if
(
!
key
)
{
xmlFreeDoc
(
plist
);
return
IPHONE_E_UNKNOWN_ERROR
;
}
key
=
add_key_str_dict_element
(
plist
,
dict
,
"Service"
,
service
,
1
);
key
=
add_key_str_dict_element
(
plist
,
dict
,
"Service"
,
service
,
1
);
if
(
!
key
)
{
xmlFreeDoc
(
plist
);
return
0
;
}
if
(
!
key
)
{
xmlFreeDoc
(
plist
);
return
IPHONE_E_UNKNOWN_ERROR
;
}
xmlDocDumpMemory
(
plist
,
(
xmlChar
**
)
&
XML_query
,
&
length
);
xmlDocDumpMemory
(
plist
,
(
xmlChar
**
)
&
XML_query
,
&
length
);
...
@@ -845,24 +862,24 @@ int iphone_lckd_start_service ( iphone_lckd_client_t client, const char *service
...
@@ -845,24 +862,24 @@ int iphone_lckd_start_service ( iphone_lckd_client_t client, const char *service
xmlFreeDoc
(
plist
);
xmlFreeDoc
(
plist
);
if
(
length
<=
0
)
return
0
;
if
(
length
<=
0
)
return
IPHONE_E_NOT_ENOUGH_DATA
;
else
{
else
{
plist
=
xmlReadMemory
(
XML_query
,
length
,
NULL
,
NULL
,
0
);
plist
=
xmlReadMemory
(
XML_query
,
length
,
NULL
,
NULL
,
0
);
if
(
!
plist
)
return
0
;
if
(
!
plist
)
return
IPHONE_E_UNKNOWN_ERROR
;
dict
=
xmlDocGetRootElement
(
plist
);
dict
=
xmlDocGetRootElement
(
plist
);
if
(
!
dict
)
return
0
;
if
(
!
dict
)
return
IPHONE_E_UNKNOWN_ERROR
;
for
(
dict
=
dict
->
children
;
dict
;
dict
=
dict
->
next
)
{
for
(
dict
=
dict
->
children
;
dict
;
dict
=
dict
->
next
)
{
if
(
!
xmlStrcmp
(
dict
->
name
,
"dict"
))
break
;
if
(
!
xmlStrcmp
(
dict
->
name
,
"dict"
))
break
;
}
}
if
(
!
dict
)
return
0
;
if
(
!
dict
)
return
IPHONE_E_UNKNOWN_ERROR
;
dictionary
=
read_dict_element_strings
(
dict
);
dictionary
=
read_dict_element_strings
(
dict
);
for
(
i
=
0
;
dictionary
[
i
];
i
+=
2
)
{
for
(
i
=
0
;
dictionary
[
i
];
i
+=
2
)
{
if
(
debug
)
printf
(
"lockdownd_start_service() dictionary %s: %s
\n
"
,
dictionary
[
i
],
dictionary
[
i
+
1
]);
if
(
debug
)
printf
(
"lockdownd_start_service() dictionary %s: %s
\n
"
,
dictionary
[
i
],
dictionary
[
i
+
1
]);
if
(
!
xmlStrcmp
(
dictionary
[
i
],
"Port"
))
{
if
(
!
xmlStrcmp
(
dictionary
[
i
],
"Port"
))
{
port
=
atoi
(
dictionary
[
i
+
1
]);
port
_loc
=
atoi
(
dictionary
[
i
+
1
]);
if
(
debug
)
printf
(
"lockdownd_start_service() atoi'd port: %i
\n
"
,
port
);
if
(
debug
)
printf
(
"lockdownd_start_service() atoi'd port: %i
\n
"
,
port
);
}
}
...
@@ -882,9 +899,12 @@ int iphone_lckd_start_service ( iphone_lckd_client_t client, const char *service
...
@@ -882,9 +899,12 @@ int iphone_lckd_start_service ( iphone_lckd_client_t client, const char *service
free
(
XML_query
);
free
(
XML_query
);
xmlFreeDoc
(
plist
);
xmlFreeDoc
(
plist
);
free_dictionary
(
dictionary
);
free_dictionary
(
dictionary
);
if
(
port
&&
result
)
return
port
;
if
(
port
&&
result
)
{
else
return
0
;
*
port
=
port_loc
;
return
IPHONE_E_SUCCESS
;
}
else
return
IPHONE_E_UNKNOWN_ERROR
;
}
}
return
0
;
return
IPHONE_E_UNKNOWN_ERROR
;
}
}
src/usbmux.c
View file @
86f61988
...
@@ -116,7 +116,7 @@ void add_connection(iphone_umux_client_t connection) {
...
@@ -116,7 +116,7 @@ void add_connection(iphone_umux_client_t connection) {
* @param client A mux TCP header for the connection which is used for tracking and data transfer.
* @param client A mux TCP header for the connection which is used for tracking and data transfer.
* @return IPHONE_E_SUCCESS on success, an error code otherwise.
* @return IPHONE_E_SUCCESS on success, an error code otherwise.
*/
*/
i
n
t
iphone_mux_new_client
(
iphone_device_t
device
,
uint16_t
src_port
,
uint16_t
dst_port
,
iphone_umux_client_t
*
client
){
i
phone_error_
t
iphone_mux_new_client
(
iphone_device_t
device
,
uint16_t
src_port
,
uint16_t
dst_port
,
iphone_umux_client_t
*
client
){
if
(
!
device
||
!
src_port
||
!
dst_port
)
if
(
!
device
||
!
src_port
||
!
dst_port
)
return
IPHONE_E_INVALID_ARG
;
return
IPHONE_E_INVALID_ARG
;
...
@@ -165,8 +165,10 @@ int iphone_mux_new_client ( iphone_device_t device, uint16_t src_port, uint16_t
...
@@ -165,8 +165,10 @@ int iphone_mux_new_client ( iphone_device_t device, uint16_t src_port, uint16_t
* @note Once a connection is closed it may not be used again.
* @note Once a connection is closed it may not be used again.
*
*
* @param connection The connection to close.
* @param connection The connection to close.
*
* @return IPHONE_E_SUCCESS on success.
*/
*/
void
iphone_mux_free_client
(
iphone_umux_client_t
client
)
{
iphone_error_t
iphone_mux_free_client
(
iphone_umux_client_t
client
)
{
if
(
!
client
||
!
client
->
phone
)
return
;
if
(
!
client
||
!
client
->
phone
)
return
;
client
->
header
->
tcp_flags
=
0x04
;
client
->
header
->
tcp_flags
=
0x04
;
...
@@ -183,6 +185,8 @@ void iphone_mux_free_client ( iphone_umux_client_t client ) {
...
@@ -183,6 +185,8 @@ void iphone_mux_free_client ( iphone_umux_client_t client ) {
printf
(
"get_iPhone(): when reading, libusb gave me the error: %s
\n
"
,
usb_strerror
());
printf
(
"get_iPhone(): when reading, libusb gave me the error: %s
\n
"
,
usb_strerror
());
delete_connection
(
client
);
delete_connection
(
client
);
return
IPHONE_E_SUCCESS
;
}
}
...
@@ -192,15 +196,16 @@ void iphone_mux_free_client ( iphone_umux_client_t client ) {
...
@@ -192,15 +196,16 @@ void iphone_mux_free_client ( iphone_umux_client_t client ) {
* @param client The client we're sending data on.
* @param client The client we're sending data on.
* @param data A pointer to the data to send.
* @param data A pointer to the data to send.
* @param datalen How much data we're sending.
* @param datalen How much data we're sending.
* @param sent_bytes The number of bytes sent, minus the header (28)
*
*
* @return
The number of bytes sent, minus the header (28), or -1 on error
.
* @return
IPHONE_E_SUCCESS on success
.
*/
*/
i
nt
iphone_mux_send
(
iphone_umux_client_t
client
,
const
char
*
data
,
uint32_t
datalen
)
{
i
phone_error_t
iphone_mux_send
(
iphone_umux_client_t
client
,
const
char
*
data
,
uint32_t
datalen
,
uint32_t
*
sent_bytes
)
{
if
(
!
client
->
phone
||
!
client
||
!
data
||
datalen
==
0
)
return
-
1
;
if
(
!
client
->
phone
||
!
client
||
!
data
||
datalen
==
0
||
!
sent_bytes
)
return
IPHONE_E_INVALID_ARG
;
// client->scnt and client->ocnt should already be in host notation...
// client->scnt and client->ocnt should already be in host notation...
// we don't need to change them juuuust yet.
// we don't need to change them juuuust yet.
int
bytes
=
0
;
*
sent_
bytes
=
0
;
if
(
debug
)
printf
(
"mux_send(): client wants to send %i bytes
\n
"
,
datalen
);
if
(
debug
)
printf
(
"mux_send(): client wants to send %i bytes
\n
"
,
datalen
);
char
*
buffer
=
(
char
*
)
malloc
(
sizeof
(
usbmux_tcp_header
)
+
datalen
+
2
);
// allow 2 bytes of safety padding
char
*
buffer
=
(
char
*
)
malloc
(
sizeof
(
usbmux_tcp_header
)
+
datalen
+
2
);
// allow 2 bytes of safety padding
// Set the length and pre-emptively htonl/htons it
// Set the length and pre-emptively htonl/htons it
...
@@ -218,12 +223,12 @@ int iphone_mux_send ( iphone_umux_client_t client, const char *data, uint32_t da
...
@@ -218,12 +223,12 @@ int iphone_mux_send ( iphone_umux_client_t client, const char *data, uint32_t da
if
(
debug
)
printf
(
"actually sending %zi bytes of data at %p
\n
"
,
sizeof
(
usbmux_tcp_header
)
+
datalen
,
buffer
);
if
(
debug
)
printf
(
"actually sending %zi bytes of data at %p
\n
"
,
sizeof
(
usbmux_tcp_header
)
+
datalen
,
buffer
);
bytes
=
send_to_phone
(
client
->
phone
,
buffer
,
sizeof
(
usbmux_tcp_header
)
+
datalen
);
*
sent_
bytes
=
send_to_phone
(
client
->
phone
,
buffer
,
sizeof
(
usbmux_tcp_header
)
+
datalen
);
if
(
debug
)
printf
(
"mux_send: sent %i bytes!
\n
"
,
bytes
);
if
(
debug
)
printf
(
"mux_send: sent %i bytes!
\n
"
,
*
sent_
bytes
);
// Now that we've sent it off, we can clean up after our sloppy selves.
// Now that we've sent it off, we can clean up after our sloppy selves.
if
(
debug
)
{
if
(
debug
)
{
FILE
*
packet
=
fopen
(
"packet"
,
"a+"
);
FILE
*
packet
=
fopen
(
"packet"
,
"a+"
);
fwrite
(
buffer
,
1
,
bytes
,
packet
);
fwrite
(
buffer
,
1
,
*
sent_
bytes
,
packet
);
fclose
(
packet
);
fclose
(
packet
);
printf
(
"
\n
"
);
printf
(
"
\n
"
);
}
}
...
@@ -238,13 +243,14 @@ int iphone_mux_send ( iphone_umux_client_t client, const char *data, uint32_t da
...
@@ -238,13 +243,14 @@ int iphone_mux_send ( iphone_umux_client_t client, const char *data, uint32_t da
client
->
header
->
length16
=
ntohs
(
client
->
header
->
length16
);
client
->
header
->
length16
=
ntohs
(
client
->
header
->
length16
);
// Now return the bytes.
// Now return the bytes.
if
(
bytes
<
sizeof
(
usbmux_tcp_header
)
+
datalen
)
{
if
(
*
sent_bytes
<
sizeof
(
usbmux_tcp_header
)
+
datalen
)
{
return
-
1
;
// blah
*
sent_bytes
=
0
;
return
IPHONE_E_NOT_ENOUGH_DATA
;
}
else
{
}
else
{
return
bytes
-
28
;
// actual length sent. :/
*
sent_bytes
=
*
sent_
bytes
-
28
;
// actual length sent. :/
}
}
return
bytes
;
// or something
return
IPHONE_E_UNKNOWN_ERROR
;
}
}
/** This is a higher-level USBMuxTCP-like function
/** This is a higher-level USBMuxTCP-like function
...
@@ -255,7 +261,10 @@ int iphone_mux_send ( iphone_umux_client_t client, const char *data, uint32_t da
...
@@ -255,7 +261,10 @@ int iphone_mux_send ( iphone_umux_client_t client, const char *data, uint32_t da
*
*
* @return How many bytes were read, or -1 if something bad happens.
* @return How many bytes were read, or -1 if something bad happens.
*/
*/
int
iphone_mux_recv
(
iphone_umux_client_t
client
,
char
*
data
,
uint32_t
datalen
)
{
iphone_error_t
iphone_mux_recv
(
iphone_umux_client_t
client
,
char
*
data
,
uint32_t
datalen
,
uint32_t
*
recv_bytes
)
{
if
(
!
client
||
!
data
||
datalen
==
0
||
!
recv_bytes
)
return
IPHONE_E_INVALID_ARG
;
/*
/*
* Order of operation:
* Order of operation:
* 1.) Check if the client has a pre-received buffer.
* 1.) Check if the client has a pre-received buffer.
...
@@ -268,6 +277,7 @@ int iphone_mux_recv ( iphone_umux_client_t client, char *data, uint32_t datalen
...
@@ -268,6 +277,7 @@ int iphone_mux_recv ( iphone_umux_client_t client, char *data, uint32_t datalen
*/
*/
if
(
debug
)
printf
(
"mux_recv: datalen == %i
\n
"
,
datalen
);
if
(
debug
)
printf
(
"mux_recv: datalen == %i
\n
"
,
datalen
);
int
bytes
=
0
,
i
=
0
,
complex
=
0
,
offset
=
0
;
int
bytes
=
0
,
i
=
0
,
complex
=
0
,
offset
=
0
;
*
recv_bytes
=
0
;
char
*
buffer
=
NULL
;
char
*
buffer
=
NULL
;
usbmux_tcp_header
*
header
=
NULL
;
usbmux_tcp_header
*
header
=
NULL
;
...
@@ -304,7 +314,7 @@ int iphone_mux_recv ( iphone_umux_client_t client, char *data, uint32_t datalen
...
@@ -304,7 +314,7 @@ int iphone_mux_recv ( iphone_umux_client_t client, char *data, uint32_t datalen
if
(
bytes
<
28
)
{
if
(
bytes
<
28
)
{
free
(
buffer
);
free
(
buffer
);
if
(
debug
)
printf
(
"mux_recv: Did not even get the header.
\n
"
);
if
(
debug
)
printf
(
"mux_recv: Did not even get the header.
\n
"
);
return
-
1
;
return
IPHONE_E_NOT_ENOUGH_DATA
;
}
}
header
=
(
usbmux_tcp_header
*
)
buffer
;
header
=
(
usbmux_tcp_header
*
)
buffer
;
...
@@ -332,7 +342,7 @@ int iphone_mux_recv ( iphone_umux_client_t client, char *data, uint32_t datalen
...
@@ -332,7 +342,7 @@ int iphone_mux_recv ( iphone_umux_client_t client, char *data, uint32_t datalen
// Free our buffer and continue.
// Free our buffer and continue.
free
(
buffer
);
free
(
buffer
);
buffer
=
NULL
;
buffer
=
NULL
;
return
iphone_mux_recv
(
client
,
data
,
datalen
);
// recurse back in to try again
return
iphone_mux_recv
(
client
,
data
,
datalen
,
recv_bytes
);
// recurse back in to try again
}
}
// The packet was absolutely meant for us if it hits this point.
// The packet was absolutely meant for us if it hits this point.
...
@@ -348,13 +358,15 @@ int iphone_mux_recv ( iphone_umux_client_t client, char *data, uint32_t datalen
...
@@ -348,13 +358,15 @@ int iphone_mux_recv ( iphone_umux_client_t client, char *data, uint32_t datalen
memcpy
(
client
->
recv_buffer
+
complex
,
buffer
+
28
+
datalen
,
(
bytes
-
28
)
-
datalen
);
memcpy
(
client
->
recv_buffer
+
complex
,
buffer
+
28
+
datalen
,
(
bytes
-
28
)
-
datalen
);
free
(
buffer
);
free
(
buffer
);
client
->
header
->
ocnt
+=
bytes
-
28
;
client
->
header
->
ocnt
+=
bytes
-
28
;
return
datalen
;
*
recv_bytes
=
datalen
;
return
IPHONE_E_SUCCESS
;
}
else
{
}
else
{
// Fill the data with what we have, and just return.
// Fill the data with what we have, and just return.
memcpy
(
data
+
offset
,
buffer
+
28
,
bytes
-
28
);
// data+offset: see #2b, above
memcpy
(
data
+
offset
,
buffer
+
28
,
bytes
-
28
);
// data+offset: see #2b, above
client
->
header
->
ocnt
+=
bytes
-
28
;
client
->
header
->
ocnt
+=
bytes
-
28
;
free
(
buffer
);
free
(
buffer
);
return
(
bytes
-
28
);
*
recv_bytes
=
bytes
-
28
;
return
IPHONE_E_SUCCESS
;
}
}
// If we get to this point, 'tis probably bad.
// If we get to this point, 'tis probably bad.
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment