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
7539f5fb
Commit
7539f5fb
authored
Aug 22, 2008
by
Jonathan Beck
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Handle known device through their UniqueDeviceID and use it as name to store PEM device public key.
parent
6b706ced
Show whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
70 additions
and
123 deletions
+70
-123
lockdown.c
src/lockdown.c
+28
-16
lockdown.h
src/lockdown.h
+1
-1
userpref.c
src/userpref.c
+39
-104
userpref.h
src/userpref.h
+2
-2
No files found.
src/lockdown.c
View file @
7539f5fb
...
...
@@ -320,21 +320,21 @@ int lockdownd_init(iPhone *phone, lockdownd_client **control)
fprintf
(
stderr
,
"Hello failed in the lockdownd client.
\n
"
);
}
char
*
public_key
=
NULL
;
if
(
!
lockdownd_get_device_
public_key
(
*
control
,
&
public_key
)){
char
*
uid
=
NULL
;
if
(
!
lockdownd_get_device_
uid
(
*
control
,
&
uid
)){
fprintf
(
stderr
,
"Device refused to send public key.
\n
"
);
}
host_id
=
get_host_id
();
if
(
!
is_device_known
(
public_key
))
ret
=
lockdownd_pair_device
(
*
control
,
public_key
,
host_id
);
if
(
!
is_device_known
(
uid
))
ret
=
lockdownd_pair_device
(
*
control
,
uid
,
host_id
);
else
ret
=
1
;
if
(
public_key
)
{
free
(
public_key
);
public_key
=
NULL
;
if
(
uid
)
{
free
(
uid
);
uid
=
NULL
;
}
if
(
ret
&&
host_id
&&
lockdownd_start_SSL_session
(
*
control
,
host_id
))
{
...
...
@@ -359,7 +359,7 @@ int lockdownd_init(iPhone *phone, lockdownd_client **control)
*
* @return 1 on success and 0 on failure
*/
int
lockdownd_pair_device
(
lockdownd_client
*
control
,
char
*
public_key_b64
,
char
*
host_id
)
int
lockdownd_pair_device
(
lockdownd_client
*
control
,
char
*
uid
,
char
*
host_id
)
{
int
ret
=
0
;
xmlDocPtr
plist
=
new_plist
();
...
...
@@ -373,8 +373,16 @@ int lockdownd_pair_device(lockdownd_client *control, char *public_key_b64, char
char
*
device_cert_b64
=
NULL
;
char
*
host_cert_b64
=
NULL
;
char
*
root_cert_b64
=
NULL
;
char
*
public_key_b64
=
NULL
;
if
(
!
lockdownd_get_device_public_key
(
control
,
&
public_key_b64
)){
fprintf
(
stderr
,
"Device refused to send public key.
\n
"
);
return
0
;
}
if
(
!
lockdownd_gen_pair_cert
(
public_key_b64
,
&
device_cert_b64
,
&
host_cert_b64
,
&
root_cert_b64
)){
free
(
public_key_b64
);
return
0
;
}
...
...
@@ -408,12 +416,18 @@ int lockdownd_pair_device(lockdownd_client *control, char *public_key_b64, char
}
plist
=
xmlReadMemory
(
XML_content
,
bytes
,
NULL
,
NULL
,
0
);
if
(
!
plist
)
return
0
;
if
(
!
plist
)
{
free
(
public_key_b64
);
return
0
;
}
dict
=
xmlDocGetRootElement
(
plist
);
for
(
dict
=
dict
->
children
;
dict
;
dict
=
dict
->
next
)
{
if
(
!
xmlStrcmp
(
dict
->
name
,
"dict"
))
break
;
}
if
(
!
dict
)
return
0
;
if
(
!
dict
)
{
free
(
public_key_b64
);
return
0
;
}
/* Parse xml to check success and to find public key */
dictionary
=
read_dict_element_strings
(
dict
);
...
...
@@ -435,11 +449,12 @@ int lockdownd_pair_device(lockdownd_client *control, char *public_key_b64, char
/* store public key in config if pairing succeeded */
if
(
success
)
{
if
(
debug
)
printf
(
"lockdownd_pair_device: pair success
\n
"
);
store_device_public_key
(
public_key_b64
);
store_device_public_key
(
uid
,
public_key_b64
);
ret
=
1
;
}
else
{
if
(
debug
)
printf
(
"lockdownd_pair_device: pair failure
\n
"
);
}
free
(
public_key_b64
);
return
ret
;
}
...
...
@@ -542,12 +557,9 @@ int lockdownd_gen_pair_cert(char *public_key_b64, char **device_cert_b64, char *
if
(
!
error
)
{
/* if everything went well, export in PEM format */
gnutls_datum_t
dev_pem
=
{
NULL
,
0
};
size_t
crt_size
;
gnutls_x509_crt_export
(
dev_cert
,
GNUTLS_X509_FMT_PEM
,
NULL
,
&
crt_size
);
dev_pem
.
size
=
crt_size
;
gnutls_x509_crt_export
(
dev_cert
,
GNUTLS_X509_FMT_PEM
,
NULL
,
&
dev_pem
.
size
);
dev_pem
.
data
=
gnutls_malloc
(
dev_pem
.
size
);
gnutls_x509_crt_export
(
dev_cert
,
GNUTLS_X509_FMT_PEM
,
dev_pem
.
data
,
&
crt_size
);
dev_pem
.
size
=
crt_size
;
gnutls_x509_crt_export
(
dev_cert
,
GNUTLS_X509_FMT_PEM
,
dev_pem
.
data
,
&
dev_pem
.
size
);
/* now encode certificates for output */
*
device_cert_b64
=
g_base64_encode
(
dev_pem
.
data
,
dev_pem
.
size
);
...
...
src/lockdown.h
View file @
7539f5fb
...
...
@@ -44,7 +44,7 @@ int lockdownd_hello(lockdownd_client *control);
int
lockdownd_get_device_uid
(
lockdownd_client
*
control
,
char
**
uid
);
int
lockdownd_get_device_public_key
(
lockdownd_client
*
control
,
char
**
public_key
);
int
lockdownd_gen_pair_cert
(
char
*
public_key_b64
,
char
**
device_cert_b64
,
char
**
host_cert_b64
,
char
**
root_cert_b64
);
int
lockdownd_pair_device
(
lockdownd_client
*
control
,
char
*
public_key
,
char
*
host_id
);
int
lockdownd_pair_device
(
lockdownd_client
*
control
,
char
*
uid
,
char
*
host_id
);
int
lockdownd_recv
(
lockdownd_client
*
control
,
char
**
dump_data
);
int
lockdownd_send
(
lockdownd_client
*
control
,
char
*
raw_data
,
uint32
length
);
void
lockdownd_close
(
lockdownd_client
*
control
);
...
...
src/userpref.c
View file @
7539f5fb
...
...
@@ -25,7 +25,7 @@
#include <string.h>
#include "userpref.h"
#include <string.h>
#include <std
io
.h>
#include <std
lib
.h>
#define LIBIPHONE_CONF_DIR "libiphone"
#define LIBIPHONE_CONF_FILE "libiphonerc"
...
...
@@ -37,6 +37,18 @@
extern
int
debug
;
/** Creates a freedesktop compatible configuration directory for libiphone.
*/
inline
void
create_config_dir
()
{
gchar
*
config_dir
=
g_build_path
(
G_DIR_SEPARATOR_S
,
g_get_user_config_dir
(),
LIBIPHONE_CONF_DIR
,
NULL
);
if
(
!
g_file_test
(
config_dir
,
(
G_FILE_TEST_EXISTS
|
G_FILE_TEST_IS_DIR
)
))
g_mkdir_with_parents
(
config_dir
,
0755
);
g_free
(
config_dir
);
}
/** Reads the HostID from a previously generated configuration file.
*
* @note It is the responsibility of the calling function to free the returned host_id
...
...
@@ -68,12 +80,12 @@ char* get_host_id() {
/** Determines whether this iPhone has been connected to this system before.
*
* @param
public_key The public key
as given by the iPhone.
* @param
uid The device uid
as given by the iPhone.
*
* @return 1 if the iPhone has been connected previously to this configuration
* or 0 otherwise.
*/
int
is_device_known
(
char
*
public_key
)
{
int
is_device_known
(
char
*
uid
)
{
int
ret
=
0
;
gchar
*
config_file
;
GKeyFile
*
key_file
;
...
...
@@ -81,41 +93,12 @@ int is_device_known(char* public_key) {
GIOChannel
*
keyfile
;
/* first get config file */
config_file
=
g_build_path
(
G_DIR_SEPARATOR_S
,
g_get_user_config_dir
(),
LIBIPHONE_CONF_DIR
,
LIBIPHONE_CONF_FILE
,
NULL
);
if
(
g_file_test
(
config_file
,
(
G_FILE_TEST_EXISTS
|
G_FILE_TEST_IS_REGULAR
)))
{
/* now parse file to get knwon devices list */
key_file
=
g_key_file_new
();
if
(
g_key_file_load_from_file
(
key_file
,
config_file
,
G_KEY_FILE_KEEP_COMMENTS
,
NULL
))
{
devices_list
=
g_key_file_get_string_list
(
key_file
,
"Global"
,
"DevicesList"
,
NULL
,
NULL
);
if
(
devices_list
)
{
pcur
=
devices_list
;
while
(
*
pcur
&&
!
ret
)
{
/* open associated base64 encoded key */
keyfilepath
=
g_build_path
(
G_DIR_SEPARATOR_S
,
g_get_user_config_dir
(),
LIBIPHONE_CONF_DIR
,
*
pcur
,
NULL
);
if
(
g_file_test
(
keyfilepath
,
(
G_FILE_TEST_EXISTS
|
G_FILE_TEST_IS_REGULAR
)))
{
keyfile
=
g_io_channel_new_file
(
keyfilepath
,
"r"
,
NULL
);
stored_key
=
NULL
;
g_io_channel_read_to_end
(
keyfile
,
&
stored_key
,
NULL
,
NULL
);
/* now compare to input */
if
(
strcmp
(
public_key
,
stored_key
)
==
2
||
!
strcmp
(
public_key
,
stored_key
))
gchar
*
device_file
=
g_strconcat
(
uid
,
".pem"
,
NULL
);
config_file
=
g_build_path
(
G_DIR_SEPARATOR_S
,
g_get_user_config_dir
(),
LIBIPHONE_CONF_DIR
,
device_file
,
NULL
);
if
(
g_file_test
(
config_file
,
(
G_FILE_TEST_EXISTS
|
G_FILE_TEST_IS_REGULAR
)))
ret
=
1
;
g_free
(
stored_key
);
g_io_channel_shutdown
(
keyfile
,
FALSE
,
NULL
);
g_io_channel_unref
(
keyfile
);
pcur
++
;
}
g_free
(
keyfilepath
);
}
}
g_strfreev
(
devices_list
);
}
g_key_file_free
(
key_file
);
g_free
(
config_file
);
}
g_free
(
device_file
);
return
ret
;
}
...
...
@@ -127,65 +110,28 @@ int is_device_known(char* public_key) {
* @return 1 on success and 0 if no public key is given or if it has already
* been marked as connected previously.
*/
int
store_device_public_key
(
char
*
public_key
)
{
gchar
*
config_file
;
GKeyFile
*
key_file
;
gchar
**
devices_list
;
guint
len
=
0
;
guint
wlength
=
0
;
gchar
dev_file
[
20
];
int
i
;
const
gchar
**
new_devices_list
;
gsize
length
;
gchar
*
buf
;
GIOChannel
*
file
;
gchar
*
device_file
;
int
store_device_public_key
(
char
*
uid
,
char
*
public_key
)
{
if
(
NULL
==
public_key
||
is_device_known
(
public_key
))
if
(
NULL
==
public_key
||
is_device_known
(
uid
))
return
0
;
/* first get config file */
config_file
=
g_build_path
(
G_DIR_SEPARATOR_S
,
g_get_user_config_dir
(),
LIBIPHONE_CONF_DIR
,
LIBIPHONE_CONF_FILE
,
NULL
);
if
(
g_file_test
(
config_file
,
(
G_FILE_TEST_EXISTS
|
G_FILE_TEST_IS_REGULAR
)))
{
key_file
=
g_key_file_new
();
if
(
g_key_file_load_from_file
(
key_file
,
config_file
,
G_KEY_FILE_KEEP_COMMENTS
,
NULL
))
{
/* Determine device name */
devices_list
=
g_key_file_get_string_list
(
key_file
,
"Global"
,
"DevicesList"
,
NULL
,
NULL
);
if
(
devices_list
)
len
=
g_strv_length
(
devices_list
);
g_strfreev
(
devices_list
);
g_sprintf
(
dev_file
,
"Device%i"
,
len
);
/* Write device file to disk */
device_file
=
g_build_path
(
G_DIR_SEPARATOR_S
,
g_get_user_config_dir
(),
LIBIPHONE_CONF_DIR
,
dev_file
,
NULL
);
file
=
g_io_channel_new_file
(
device_file
,
"w"
,
NULL
);
g_free
(
device_file
);
wlength
=
strlen
(
public_key
);
// why this wasn't discovered before... ugh
g_io_channel_write_chars
(
file
,
public_key
,
wlength
,
NULL
,
NULL
);
g_io_channel_shutdown
(
file
,
TRUE
,
NULL
);
g_io_channel_unref
(
file
);
/* Append device to list */
new_devices_list
=
(
const
gchar
**
)
g_malloc
(
sizeof
(
gchar
*
)
*
(
len
+
2
));
for
(
i
=
0
;
i
<
len
;
i
++
)
new_devices_list
[
i
]
=
devices_list
[
i
];
new_devices_list
[
len
]
=
dev_file
;
new_devices_list
[
len
+
1
]
=
NULL
;
g_key_file_set_string_list
(
key_file
,
"Global"
,
"DevicesList"
,
new_devices_list
,
len
+
1
);
g_free
(
new_devices_list
);
}
/* ensure config directory exists */
create_config_dir
();
/* Write config file to disk */
buf
=
g_key_file_to_data
(
key_file
,
&
length
,
NULL
);
file
=
g_io_channel_new_file
(
config_file
,
"w"
,
NULL
);
g_io_channel_write_chars
(
file
,
buf
,
length
,
NULL
,
NULL
);
g_io_channel_shutdown
(
file
,
TRUE
,
NULL
);
g_io_channel_unref
(
file
);
g_key_file_free
(
key_file
);
}
/* build file path */
gchar
*
device_file
=
g_strconcat
(
uid
,
".pem"
,
NULL
);
gchar
*
pem
=
g_build_path
(
G_DIR_SEPARATOR_S
,
g_get_user_config_dir
(),
LIBIPHONE_CONF_DIR
,
device_file
,
NULL
);
/* decode public key for storing */
gsize
decoded_size
;
gchar
*
data
=
g_base64_decode
(
public_key
,
&
decoded_size
);
/* store file */
FILE
*
pFile
=
fopen
(
pem
,
"wb"
);
fwrite
(
data
,
1
,
decoded_size
,
pFile
);
fclose
(
pFile
);
g_free
(
pem
);
g_free
(
data
);
g_free
(
device_file
);
return
1
;
}
...
...
@@ -257,17 +203,6 @@ int get_host_certificate(gnutls_datum_t* host_cert) {
return
read_file_in_confdir
(
LIBIPHONE_HOST_CERTIF
,
host_cert
);
}
/** Creates a freedesktop compatible configuration directory for libiphone.
*/
inline
void
create_config_dir
()
{
gchar
*
config_dir
=
g_build_path
(
G_DIR_SEPARATOR_S
,
g_get_user_config_dir
(),
LIBIPHONE_CONF_DIR
,
NULL
);
if
(
!
g_file_test
(
config_dir
,
(
G_FILE_TEST_EXISTS
|
G_FILE_TEST_IS_DIR
)
))
g_mkdir_with_parents
(
config_dir
,
0755
);
g_free
(
config_dir
);
}
/** Create and save a configuration file containing the given data.
*
* @note: All fields must specified and be non-null
...
...
src/userpref.h
View file @
7539f5fb
...
...
@@ -35,12 +35,12 @@ char* get_host_id();
*
* @return 1 if device is already paired. Returns 0 otherwise.
*/
int
is_device_known
(
char
*
public_key
);
int
is_device_known
(
char
*
uid
);
/**
* @return 1 if everything went well. Returns 0 otherwise.
*/
int
store_device_public_key
(
char
*
public_key
);
int
store_device_public_key
(
char
*
uid
,
char
*
public_key
);
/**
* @return 1 if everything went well. Returns 0 otherwise.
...
...
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