]> git.saurik.com Git - apple/security.git/blobdiff - OSX/sec/Security/SecItemBackup.c
Security-58286.1.32.tar.gz
[apple/security.git] / OSX / sec / Security / SecItemBackup.c
index d11bdee03576cfa3b632faa22429dff2a71eeddb..c55d70f0c80c20dd6f162b36aef094db49935ccd 100644 (file)
@@ -199,7 +199,7 @@ _SecKeychainRestoreBackupFromFileDescriptor(int fd, CFDataRef backupKeybag, CFDa
 CFStringRef
 _SecKeychainCopyKeybagUUIDFromFileDescriptor(int fd, CFErrorRef *error)
 {
-    __block CFStringRef result;
+    __block CFStringRef result = NULL;
     os_activity_initiate("_SecKeychainCopyKeybagUUID", OS_ACTIVITY_FLAG_DEFAULT, ^{
         securityd_send_sync_and_do(sec_keychain_backup_keybag_uuid_id, error, ^bool(xpc_object_t message, CFErrorRef *error) {
             return SecXPCDictionarySetFileDescriptor(message, kSecXPCKeyFileDescriptor, fd, error);
@@ -280,21 +280,40 @@ static bool SecKeychainWithBackupFile(CFStringRef backupName, CFErrorRef *error,
     }
 
     // Rewind file to start
-    lseek(fd, 0, SEEK_SET);
+    if (lseek(fd, 0, SEEK_SET)) {
+        secdebug("backup", "Could not seek in fd %d for %@", fd, backupName);
+        return SecCheckErrno(true, error, CFSTR("lseek"));
+    }
 
     FILE *backup = fdopen(fd, "r");
     if (!backup) {
-        close(fd);
         secdebug("backup", "Receiving file for %@ failed, %d", backupName, errno);
-        return SecCheckErrno(!backup, error, CFSTR("fdopen"));
+        SecCheckErrno(!backup, error, CFSTR("fdopen"));
+        if (close(fd)) {
+            secdebug("backup", "Encountered error closing file %@: %d", backupName, errno);
+            SecCheckErrno(true, error, CFSTR("close"));
+        }
+        return false;
     } else {
         struct stat sb;
-        fstat(fd, &sb);
+        if (fstat(fd, &sb)) {
+            secdebug("backup", "Unable to get file metadata for %@, fd %d", backupName, fd);
+            SecCheckErrno(true, error, CFSTR("fstat"));
+            if (fclose(backup)) {
+                secdebug("backup", "Encountered error closing file %@: %d", backupName, errno);
+                SecCheckErrno(true, error, CFSTR("fclose"));
+            }
+            return false;
+        }
         secdebug("backup", "Receiving file for %@ with fd %d of size %llu", backupName, fd, sb.st_size);
     }
 
     with(backup);
-    fclose(backup);
+    if (fclose(backup)) {
+        secdebug("backup", "Encountered error %d closing file %@ after backup handler", errno, backupName);
+        SecCheckErrno(true, error, CFSTR("fclose"));
+        // read only file and block has its own error handling for IO failure, no need to return false
+    }
     return true;
 }
 
@@ -566,4 +585,32 @@ CFDictionaryRef SecItemBackupCopyMatching(CFDataRef keybag, CFDataRef secret, CF
     return NULL;
 }
 
+bool SecBackupKeybagAdd(CFDataRef passcode, CFDataRef *identifier, CFURLRef *pathinfo, CFErrorRef *error) {
+    __block bool result = false;
+    os_activity_initiate("_SecServerBackupKeybagAdd", OS_ACTIVITY_FLAG_DEFAULT, ^{
+        securityd_send_sync_and_do(kSecXPCOpBackupKeybagAdd, error, ^bool(xpc_object_t message, CFErrorRef *error) {
+            return SecXPCDictionarySetDataOptional(message, kSecXPCKeyUserPassword, passcode, error);
+        }, ^bool(xpc_object_t response, CFErrorRef *error) {
+            result = SecXPCDictionaryCopyDataOptional(response, kSecXPCKeyBackupKeybagIdentifier, identifier, error) &&
+            SecXPCDictionaryCopyURLOptional(response, kSecXPCKeyBackupKeybagPath, pathinfo, error) &&
+            SecXPCDictionaryGetBool(response, kSecXPCKeyResult, error);
+            return result;
+        });
+    });
+    return result;
+}
+
+bool SecBackupKeybagDelete(CFDictionaryRef query, CFErrorRef *error) {
+    __block bool result = false;
+    os_activity_initiate("_SecBackupKeybagDelete", OS_ACTIVITY_FLAG_DEFAULT, ^{
+        securityd_send_sync_and_do(kSecXPCOpBackupKeybagDelete, error, ^bool(xpc_object_t message, CFErrorRef *error) {
+            return SecXPCDictionarySetPList(message, kSecXPCKeyQuery, query, error);
+        }, ^bool(xpc_object_t response, CFErrorRef *error) {
+            result = SecXPCDictionaryGetBool(response, kSecXPCKeyResult, error);
+            return result;
+        });
+    });
+    return result;
+}
+