@ -41,6 +41,10 @@
# include <sasl / saslutil.h>
# endif
# ifdef HAVE_MACOS_KEYCHAIN
# include <Security / Security.h>
# endif
# ifdef HAVE_LIBSSL
enum { SSL_None , SSL_STARTTLS , SSL_IMAPS } ;
# endif
@ -58,6 +62,9 @@ typedef struct imap_server_conf {
string_list_t * auth_mechs ;
# ifdef HAVE_LIBSSL
char ssl_type ;
# endif
# ifdef HAVE_MACOS_KEYCHAIN
char use_keychain ;
# endif
char failed ;
} imap_server_conf_t ;
@ -1991,6 +1998,31 @@ ensure_password( imap_server_conf_t *srvc )
if ( ! srvc - > pass ) {
if ( srvc - > pass_cmd ) {
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 ) ;
# endif /* HAVE_MACOS_KEYCHAIN */
} else {
flushn ( ) ;
char prompt [ 80 ] ;
@ -3293,6 +3325,10 @@ imap_parse_store( conffile_t *cfg, store_conf_t **storep )
server - > pass = nfstrdup ( cfg - > val ) ;
else if ( ! strcasecmp ( " PassCmd " , cfg - > cmd ) )
server - > pass_cmd = nfstrdup ( cfg - > val ) ;
# ifdef HAVE_MACOS_KEYCHAIN
else if ( ! strcasecmp ( " UseKeychain " , cfg - > cmd ) )
server - > use_keychain = parse_bool ( cfg ) ;
# endif
else if ( ! strcasecmp ( " Port " , cfg - > cmd ) ) {
int port = parse_int ( cfg ) ;
if ( ( unsigned ) port > 0xffff ) {
@ -3462,6 +3498,13 @@ imap_parse_store( conffile_t *cfg, store_conf_t **storep )
cfg - > err = 1 ;
return 1 ;
}
# ifdef HAVE_MACOS_KEYCHAIN
if ( server - > use_keychain & & ( server - > pass | | server - > pass_cmd ) ) {
error ( " %s '%s' has UseKeychain enabled despite specifying Pass/PassCmd \n " , type , name ) ;
cfg - > err = 1 ;
return 1 ;
}
# endif
# ifdef HAVE_LIBSSL
if ( ( use_tlsv1 & use_tlsv11 & use_tlsv12 & use_tlsv13 ) ! = - 1 | | use_imaps > = 0 | | require_ssl > = 0 ) {
if ( server - > ssl_type > = 0 | | server - > sconf . ssl_versions > = 0 ) {