--- gems/passenger-6.0.23/src/cxx_supportlib/SecurityKit/Crypto.h 2024-08-01 12:24:32.000000000 -0500 +++ gems/passenger-6.0.23/src/cxx_supportlib/SecurityKit/Crypto.h 2024-08-01 12:10:40.000000000 -0500 @@ -90,6 +90,7 @@ void logFreeErrorExtended(const StaticString &prefix, CFErrorRef &additional); CFDictionaryRef createQueryDict(const char *label); SecAccessRef createAccess(const char *cLabel); + OSStatus lookupKeychainItem(const char *label, SecIdentityRef *oIdentity); OSStatus copyIdentityFromPKCS12File(const char *cPath, const char *cPassword, const char *cLabel); CFDataRef genIV(size_t iv_size); bool getKeyBytes(SecKeyRef cryptokey, void **target, size_t &len); --- gems/passenger-6.0.23/src/cxx_supportlib/SecurityKit/Crypto.cpp 2024-05-20 04:17:15.000000000 -0500 +++ gems/passenger-6.0.23/src/cxx_supportlib/SecurityKit/Crypto.cpp 2024-05-20 05:02:18.000000000 -0500 @@ -73,6 +73,18 @@ return NULL; } +OSStatus Crypto::lookupKeychainItem(const char *label, SecIdentityRef *oIdentity) { + OSStatus status = errSecItemNotFound; + + CFDictionaryRef queryDict = createQueryDict(label); + if (queryDict) { + /* Do we have a match? */ + status = SecItemCopyMatching(queryDict, (CFTypeRef *) oIdentity); + CFRelease(queryDict); + } + return status; +} + SecAccessRef Crypto::createAccess(const char *cLabel) { SecAccessRef access = NULL; CFStringRef label = CFStringCreateWithCString(NULL, cLabel, kCFStringEncodingUTF8); @@ -150,6 +150,85 @@ return status; } +#if PRE_HIGH_SIERRA +void Crypto::killKey(const char *cLabel) { + SecIdentityRef id = NULL; + OSStatus status = lookupKeychainItem(cLabel, &id); + if (status != errSecItemNotFound) { + + CFArrayRef itemList = CFArrayCreate(NULL, (const void **) &id, 1, NULL); + CFTypeRef keys[] = { kSecClass, kSecMatchItemList, kSecMatchLimit }; + CFTypeRef values[] = { kSecClassCertificate, itemList, kSecMatchLimitOne }; + + CFDictionaryRef dict = CFDictionaryCreate(NULL, keys, values, 3L, NULL, NULL); + OSStatus oserr = SecItemDelete(dict); + if (oserr) { + CFStringRef str = SecCopyErrorMessageString(oserr, NULL); + logError(string("Removing Passenger Cert from keychain failed: ") + CFStringGetCStringPtr(str, kCFStringEncodingUTF8) + + ". Please remove the certificate labeled " + cLabel + " in your keychain."); + CFRelease(str); + } + CFRelease(dict); + CFRelease(itemList); + + if(id){ + CFTypeRef keys2[] = { kSecClass, kSecAttrSubjectKeyID, kSecMatchLimit }; + CFTypeRef values2[] = { kSecClassKey, id, kSecMatchLimitOne }; + dict = CFDictionaryCreate(NULL, keys2, values2, 3L, NULL, NULL); + oserr = SecItemDelete(dict); + if (oserr) { + CFStringRef str = SecCopyErrorMessageString(oserr, NULL); + logError(string("Removing Passenger private key from keychain failed: ") + CFStringGetCStringPtr(str, kCFStringEncodingUTF8) + + ". Please remove the private key from the certificate labeled " + cLabel + " in your keychain."); + CFRelease(str); + } + CFRelease(dict); + CFRelease(id); + id = NULL; + } + + } else { + CFStringRef str = SecCopyErrorMessageString(status, NULL); + logError(string("Finding Passenger Cert failed: ") + CFStringGetCStringPtr(str, kCFStringEncodingUTF8) ); + CFRelease(str); + } +} + +bool Crypto::preAuthKey(const char *path, const char *passwd, const char *cLabel) { + SecIdentityRef id = NULL; + if (lookupKeychainItem(cLabel, &id) == errSecItemNotFound) { + OSStatus oserr = SecKeychainSetUserInteractionAllowed(false); + if (oserr) { + CFStringRef str = SecCopyErrorMessageString(oserr, NULL); + logError(string("Disabling GUI Keychain interaction failed: ") + CFStringGetCStringPtr(str, kCFStringEncodingUTF8)); + CFRelease(str); + } + oserr = copyIdentityFromPKCS12File(path, passwd, cLabel); + bool success = (noErr == oserr); + if (!success) { + CFStringRef str = SecCopyErrorMessageString(oserr, NULL); + logError(string("Pre authorizing the Passenger client certificate failed: ") + CFStringGetCStringPtr(str, kCFStringEncodingUTF8)); + CFRelease(str); + } + oserr = SecKeychainSetUserInteractionAllowed(true); + if (oserr) { + //This is really bad, we should probably ask the user to reboot. + CFStringRef str = SecCopyErrorMessageString(oserr, NULL); + logError(string("Re-enabling GUI Keychain interaction failed with error: ") + CFStringGetCStringPtr(str, kCFStringEncodingUTF8) + + " Please reboot as soon as possible, thanks."); + CFRelease(str); + } + return success; + } else { + logError(string("Passenger client certificate was found in the keychain unexpectedly, skipping security update check. Please remove the private key from the certificate labeled ") + cLabel + " in your keychain."); + if (id) { + CFRelease(id); + } + return false; + } +} +#endif + bool Crypto::generateRandomChars(unsigned char *rndChars, int rndLen) { FILE *fPtr = fopen("/dev/random", "r"); if (fPtr == NULL) { --- gems/passenger-6.0.23/src/cxx_supportlib/SecurityKit/Crypto.h 2024-05-20 04:17:15.000000000 -0500 +++ gems/passenger-6.0.23/src/cxx_supportlib/SecurityKit/Crypto.h 2024-05-20 05:03:52.000000000 -0500 @@ -109,6 +109,13 @@ bool generateAndAppendNonce(string &nonce); #if BOOST_OS_MACOS +#if PRE_HIGH_SIERRA + /** + * sets the permissions on the certificate so that curl doesn't prompt + */ + bool preAuthKey(const char *path, const char *passwd, const char *cLabel); + void killKey(const char *cLabel); +#endif bool generateRandomChars(unsigned char *rndChars, int rndLen); #endif --- gems/passenger-6.0.23/src/cxx_supportlib/MemoryKit/mbuf.cpp.orig 2024-05-25 16:16:22.000000000 -0500 +++ gems/passenger-6.0.23/src/cxx_supportlib/MemoryKit/mbuf.cpp 2024-05-26 09:31:40.000000000 -0500 @@ -16,6 +16,7 @@ * limitations under the License. */ +#include #include #include #include @@ -141,7 +142,11 @@ return mbuf_block; } +#if PRE_HIGH_SIERRA + posix_memalign((void **) &buf, alignof(struct mbuf_block), pool->mbuf_block_chunk_size); +#else buf = (char *) aligned_alloc(alignof(struct mbuf_block), pool->mbuf_block_chunk_size); +#endif if (OXT_UNLIKELY(buf == NULL)) { return NULL; } @@ -186,7 +187,11 @@ if (OXT_UNLIKELY(block_offset % alignof(struct mbuf_block) != 0)) { return NULL; } +#if PRE_HIGH_SIERRA + posix_memalign((void **) &buf, alignof(struct mbuf_block), MBUF_BLOCK_HSIZE + block_offset); +#else buf = (char *) aligned_alloc(alignof(struct mbuf_block), MBUF_BLOCK_HSIZE + block_offset) +#endif if (OXT_UNLIKELY(buf == NULL)) { return NULL; }