//
// SOSSysdiagnose.c
// sec
//
// Created by Richard Murphy on 1/27/16.
//
//
#include "SOSCloudCircleInternal.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/utsname.h>
#include <sys/stat.h>
#include <time.h>
#include <notify.h>
#include <pwd.h>
#include <Security/SecItem.h>
#include <CoreFoundation/CoreFoundation.h>
#include <CoreFoundation/CFPriv.h>
#include <Security/SecureObjectSync/SOSCloudCircle.h>
#include <Security/SecureObjectSync/SOSCloudCircleInternal.h>
#include <Security/SecureObjectSync/SOSPeerInfo.h>
#include <Security/SecureObjectSync/SOSPeerInfoPriv.h>
#include <Security/SecureObjectSync/SOSPeerInfoV2.h>
#include <Security/SecureObjectSync/SOSUserKeygen.h>
#include <Security/SecureObjectSync/SOSKVSKeys.h>
#include <securityd/SOSCloudCircleServer.h>
#include <Security/SecOTRSession.h>
#include <SOSCircle/CKBridge/SOSCloudKeychainClient.h>
#include <utilities/SecCFWrappers.h>
#include <utilities/debugging.h>
#include <SecurityTool/readline.h>
#include "SOSSysdiagnose.h"
#include "keychain_log.h"
#include "secToolFileIO.h"
#include "secViewDisplay.h"
#include "accountCirclesViewsPrint.h"
#include <Security/SecPasswordGenerate.h>
static char *CFDictionaryCopyCStringWithDefault(CFDictionaryRef dict, const void *key, char *defaultString) {
char *retval = NULL;
require_quiet(dict, use_default);
CFStringRef val = CFDictionaryGetValue(dict, key);
retval = CFStringToCString(val);
use_default:
if(!retval) retval = strdup(defaultString);
return retval;
}
static char *createDateStrNow() {
char *retval = NULL;
time_t clock;
struct tm *tmstruct;
time(&clock);
tmstruct = localtime(&clock);
retval = malloc(15);
sprintf(retval, " return retval;
}
#if !TARGET_OS_EMBEDDED
static char *assemblePath(char *dir, char *fname) {
size_t length = strlen(dir) + strlen(fname) + 2;
char *outputDir = malloc(length);
int status = snprintf(outputDir, length, " if(status < 0) {
if(outputDir) free(outputDir);
return NULL;
}
return outputDir;
}
static char *homedirPath() {
char *homeDir = "";
struct passwd* pwd = getpwuid(getuid());
if (pwd) homeDir = pwd->pw_dir;
return homeDir;
}
#endif
static char *sysdiagnose_dir(const char *passedIn, const char *hostname, const char *productVersion, const char *now) {
if(passedIn) return (char *) passedIn;
// OUTPUTBASE=ckcdiagnose_snapshot_${HOSTNAME}_${PRODUCT_VERSION}_${NOW}
char *outputParent = NULL;
size_t length = strlen("ckcdiagnose_snapshot___") + strlen(hostname) + strlen(productVersion) + strlen(now) + 1;
char *outputBase = malloc(length);
int status = snprintf(outputBase, length, "ckcdiagnose_snapshot_ if(status < 0) outputBase = "";
#if TARGET_OS_EMBEDDED
outputParent = "/Library/Logs/CrashReporter";
#else
outputParent = "/var/tmp";
#endif
length = strlen(outputParent) + strlen(outputBase) + 2;
char *outputDir = malloc(length);
status = snprintf(outputDir, length, " if(status < 0) {
if(outputDir) free(outputDir);
return NULL;
}
return outputDir;
}
static char *sysdiagnose_dump(const char *dirname) {
char *outputDir = NULL;
char hostname[80];
char *productName = NULL;
char *productVersion = NULL;
char *buildVersion = NULL;
char *keysToRegister = NULL;
char *cloudkeychainproxy3 = NULL;
char *now = createDateStrNow();
CFDictionaryRef sysfdef = _CFCopySystemVersionDictionary();
productName = CFDictionaryCopyCStringWithDefault(sysfdef, _kCFSystemVersionProductNameKey, "unknownProduct");
productVersion = CFDictionaryCopyCStringWithDefault(sysfdef, _kCFSystemVersionProductVersionKey, "unknownProductVersion");
buildVersion = CFDictionaryCopyCStringWithDefault(sysfdef, _kCFSystemVersionBuildVersionKey, "unknownVersion");
if(gethostname(hostname, 80)) {
strcpy(hostname, "unknownhost");
}
#if TARGET_OS_EMBEDDED
keysToRegister = "/private/var/preferences/com.apple.security.cloudkeychainproxy3.keysToRegister.plist";
cloudkeychainproxy3 = "/var/mobile/Library/SyncedPreferences/com.apple.security.cloudkeychainproxy3.plist";
#else
char *homeDir = homedirPath();
keysToRegister = assemblePath(homeDir, "Library/Preferences/com.apple.security.cloudkeychainproxy3.keysToRegister.plist");
cloudkeychainproxy3 = assemblePath(homeDir, "Library/SyncedPreferences/com.apple.security.cloudkeychainproxy3.plist");
#endif
outputDir = sysdiagnose_dir(dirname, hostname, productVersion, now);
if(!outputDir) goto errOut;
mkdir(outputDir, 0700);
SOSLogSetOutputTo(outputDir, "sw_vers.log");
// report uname stuff + hostname
fprintf(outFile, "HostName: fprintf(outFile, "ProductName: fprintf(outFile, "ProductVersion: fprintf(outFile, "BuildVersion: closeOutput();
SOSLogSetOutputTo(outputDir, "syncD.log");
// do sync -D
SOSCCDumpCircleKVSInformation(optarg);
closeOutput();
SOSLogSetOutputTo(outputDir, "synci.log");
// do sync -i
SOSCCDumpCircleInformation();
closeOutput();
SOSLogSetOutputTo(outputDir, "syncL.log");
// do sync -L
listviewcmd(NULL);
closeOutput();
copyFileToOutputDir(outputDir, keysToRegister);
copyFileToOutputDir(outputDir, cloudkeychainproxy3);
errOut:
if(now) free(now);
CFReleaseNull(sysfdef);
#if ! TARGET_OS_EMBEDDED
free(keysToRegister);
free(cloudkeychainproxy3);
#endif
if(productName) free(productName);
if(productVersion) free(productVersion);
if(buildVersion) free(buildVersion);
return outputDir;
}
char *SOSCCSysdiagnose(const char *directoryname) {
sysdiagnose_dump(directoryname);
return NULL;
}