hacks/dump-imessages/iphone-dataprotection/ramdisk_tools/plist_server.c

160 lines
4.4 KiB
C

#include <stdio.h>
#include <stdlib.h>
#include <netinet/in.h>
#include <sys/socket.h>
#include <signal.h>
#include <unistd.h>
#include <CoreFoundation/CoreFoundation.h>
#include "plist_server.h"
#include "util.h"
#define TCP_PORT 1999
int send_progress_message(int socket, int progress, int total)
{
const void* keys[3] = {CFSTR("MessageType"), CFSTR("Progress"), CFSTR("Total")};
const void* values[3] = {CFSTR("Progress"), NULL, NULL};
CFNumberRef number = CFNumberCreate(kCFAllocatorDefault, kCFNumberIntType, &progress);
CFNumberRef number2 = CFNumberCreate(kCFAllocatorDefault, kCFNumberIntType, &total);
values[1] = number;
values[2] = number2;
CFDictionaryRef msg = CFDictionaryCreate(kCFAllocatorDefault, keys, values, 3, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
CFRelease(number);
CFRelease(number2);
int res = send_object(socket, msg);
CFRelease(msg);
return res;
}
int send_object(int socket, CFTypeRef obj)
{
uint32_t len = 0;
int res = -1;
if(obj == NULL)
return res;
CFDataRef outdata = CFPropertyListCreateData(kCFAllocatorDefault, obj, kCFPropertyListXMLFormat_v1_0, 0, NULL);
if (outdata != NULL)
{
len = CFDataGetLength(outdata);
write(socket, &len, 4);
res = write(socket, CFDataGetBytePtr(outdata), CFDataGetLength(outdata));
CFRelease(outdata);
}
return res;
}
int handle_client(int socket, CFDictionaryRef handlers)
{
uint32_t len=0;
uint32_t received,i;
CFDataRef data;
CFDictionaryRef plist;
CFTypeRef out = NULL;
uint8_t* buffer;
CFTypeRef (*handler)(int, CFDictionaryRef dict) = NULL;
while(1)
{
if(recv(socket, &len, 4, 0) != 4)
break;
//printf("len=%x\n", len);
if (len > PLIST_MAX_SIZE)
break;
buffer = malloc(len);
if(buffer == NULL)
break;
for(i=0; i < len; )
{
received = recv(socket, &buffer[i], len - i, 0);
if (received == -1)
break;
i += received;
}
data = CFDataCreateWithBytesNoCopy(kCFAllocatorDefault, buffer, len, kCFAllocatorNull);
if(data == NULL)
{
free(buffer);
continue;
}
plist = (CFDictionaryRef) CFPropertyListCreateWithData (kCFAllocatorDefault, data, kCFPropertyListImmutable, NULL, NULL);
if(plist == NULL || CFGetTypeID(plist) != CFDictionaryGetTypeID())
{
CFRelease(data);
free(buffer);
send_object(socket, CFSTR("invalid XML plist dictionary"));
continue;
}
if (CFDictionaryContainsKey(plist, CFSTR("Request")))
{
CFStringRef request = CFDictionaryGetValue(plist, CFSTR("Request"));
handler = CFDictionaryGetValue(handlers, request);
if (handler != NULL)
{
out = handler(socket, plist);
if (out == NULL)
out = CFSTR("Request did not return any result");
}
else
{
out = CFSTR("No handler defined for Request");
}
}
else
{
out = CFSTR("request dictionary needs to contain Request key");
}
if(out == NULL)
out = CFSTR("no response");
send_object(socket, out);
CFRelease(out);
CFRelease(plist);
CFRelease(data);
free(buffer);
}
send_object(socket, CFSTR("kthxbye"));
return 0;
}
void serve_plist_rpc(int port, CFDictionaryRef handlers)
{
int quit = 0;
int one=1;
printf("plist_rpc: listening on port %d\n", port);
int sl = create_listening_socket(port);
while(!quit)
{
int s = accept(sl, NULL, NULL);
setsockopt(s, SOL_SOCKET, SO_NOSIGPIPE, (void *)&one, sizeof(int));
handle_client(s, handlers);
shutdown(s, SHUT_RDWR);
close(s);
}
close(sl);
}
CFStringRef testHandler(int s, CFDictionaryRef dict)
{
printf("lol\n");
return CFSTR("Hello, World!");
}