It is useful to segregate OS-specific code where appropriate for better
readability and easier debugging.  Logic regarding the macOS keychain is
macOS-specific (obviously), and is currently intermixed with the
ensure_password() function.

Move the logic relating to searching the macOS keychain into a
self-contained search_macos_keychain() function, adding a clearer
separation between macOS-specific and OS-agnostic code in the
ensure_password() function (since the macOS-specific code is just a
single function call).
---
 src/drv_imap.c | 65 +++++++++++++++++++++++++++++++++-----------------
 1 file changed, 43 insertions(+), 22 deletions(-)

diff --git a/src/drv_imap.c b/src/drv_imap.c
index 21daae41c166..410d6d616c50 100644
--- a/src/drv_imap.c
+++ b/src/drv_imap.c
@@ -2331,6 +2331,48 @@ ensure_user( imap_server_conf_t *srvc )
        return srvc->user;
 }
 
+#ifdef HAVE_MACOS_KEYCHAIN
+/*
+ * Searches the macOS file-based keychain for an appropriate password.  If
+ * found, returns a newly allocated copy of the password (which should later be
+ * freed).  Otherwise, returns NULL.
+ *
+ * A password is deemed appropriate if its protocol is IMAP, and its server 
name
+ * and account name match the given host and user, respectively.  If multiple
+ * such passwords exist, the first found by the Security framework is returned.
+ */
+static char *
+search_macos_keychain( const char *host, const char *user )
+{
+       void *password_data;
+       char *password_copy;
+       UInt32 password_length;
+       OSStatus ret;
+
+       ret = SecKeychainFindInternetPassword(
+                       NULL,  // keychainOrArray
+                       strlen( host ), host,
+                       0, NULL,  // securityDomain
+                       strlen( user ), user,
+                       0, NULL,  // path
+                       0,  // port - we could use it, but it seems pointless
+                       kSecProtocolTypeIMAP,
+                       kSecAuthenticationTypeDefault,
+                       &password_length, &password_data,
+                       NULL );  // itemRef
+       if (ret != errSecSuccess) {
+               CFStringRef errmsg = SecCopyErrorMessageString( ret, NULL );
+               error( "Looking up Keychain failed: %s\n",
+                      CFStringGetCStringPtr( errmsg, kCFStringEncodingUTF8 ) );
+               CFRelease( errmsg );
+               return NULL;
+       }
+       password_copy = nfstrndup( password_data, password_length );
+       SecKeychainItemFreeContent( NULL, password_data );
+       return password_copy;
+}
+#endif /* HAVE_MACOS_KEYCHAIN */
+
 static const char *
 ensure_password( imap_server_conf_t *srvc )
 {
@@ -2340,28 +2382,7 @@ ensure_password( imap_server_conf_t *srvc )
                srvc->pass = cred_from_cmd( "PassCmd", srvc->pass_cmd, 
srvc->name );
 #ifdef HAVE_MACOS_KEYCHAIN
        } else if (srvc->use_keychain) {
-               void *password_data;
-               UInt32 password_length;
-               OSStatus ret = SecKeychainFindInternetPassword(
-                               NULL,  // keychainOrArray
-                               strlen( srvc->sconf.host ), srvc->sconf.host,
-                               0, NULL,  // securityDomain
-                               strlen( srvc->user ), srvc->user,
-                               0, NULL,  // path
-                               0,  // port - we could use it, but it seems 
pointless
-                               kSecProtocolTypeIMAP,
-                               kSecAuthenticationTypeDefault,
-                               &password_length, &password_data,
-                               NULL );  // itemRef
-               if (ret != errSecSuccess) {
-                       CFStringRef errmsg = SecCopyErrorMessageString( ret, 
NULL );
-                       error( "Looking up Keychain failed: %s\n",
-                              CFStringGetCStringPtr( errmsg, 
kCFStringEncodingUTF8 ) );
-                       CFRelease( errmsg );
-                       return NULL;
-               }
-               srvc->pass = nfstrndup( password_data, password_length );
-               SecKeychainItemFreeContent( NULL, password_data );
+               srvc->pass = search_macos_keychain( srvc->sconf.host, 
srvc->user );
 #endif /* HAVE_MACOS_KEYCHAIN */
        } else {
                flushn();
-- 
2.50.1 (Apple Git-155)



_______________________________________________
isync-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/isync-devel

Reply via email to