rsync patch to add Apple keychain support
Dirk Theisen
d.theisen at objectpark.org
Thu Aug 23 22:00:55 GMT 2007
Hi!
In a project I'm working on, I needed a way to run rsync in daemon mode
as a regular user without having the passwords readable to everybody
accessing the console. With this chance rsync falls back to Apples
keychain access if no secrets file is given.
You need to put the passwords into the keychain like this (I do it
programmatically bit it can be done manually as well):
Servicename: rsyncd
Account name: <modulename>-<username>
Enjoy!
It would be very cool to see this as an option for the Darwin target.
Greetings,
Dirk
In the Makefile, I added:
--------------------------------------------------------------
LDFLAGS=-framework Security -framework CoreFoundation -framework
CoreServices
--------------------------------------------------------------
In authenticate.c, I added the following function:
--------------------------------------------------------------
#include <CoreFoundation/CoreFoundation.h>
#include <CoreServices/CoreServices.h>
OSStatus SecKeychainFindGenericPassword(CFTypeRef keychainOrArray,
UInt32 serviceNameLength, const char *serviceName, UInt32
accountNameLength, const char *accountName, UInt32 *passwordLength,
void **passwordData, SecKeychainItemRef *itemRef);
OSStatus SecKeychainItemFreeContent(SecKeychainAttributeList *attrList,
void *data);
static int get_secret_from_keychain(int module, char *user, char
*secret, unsigned secretmaxlen)
{
char accountname[100] = "";
char* modulename = lp_name(module);
strcat(accountname, modulename);
strcat(accountname, "-");
strcat(accountname, user);
OSStatus status = noErr;
UInt32 passwordLength = 0;
void* passwordData = nil; // will be allocated and filled in by
SecKeychainFindGenericPassword
SecKeychainItemRef* itemRef = NULL;
status = SecKeychainFindGenericPassword (
NULL, // default keychain
strlen("rsyncd"), // length of service name
"rsyncd", // service name
strlen(accountname), // length of account name
accountname, // account name
&passwordLength, // length of password
&passwordData, // pointer to password data
itemRef // the item reference
);
if (status != noErr) return 0;
passwordLength = MIN(passwordLength, secretmaxlen);
strncpy(secret, (char*)passwordData, passwordLength);
secret[passwordLength] = 0; // terminate.
SecKeychainItemFreeContent(NULL, passwordData);
return 1;
}
-----------------------------------------------------------------
In In authenticate.c, I changed the following function to call
get_secret_from_keychain as fallback:
-----------------------------------------------------------------
/* Return the secret for a user from the secret file, null terminated.
* Maximum length is len (not counting the null). */
static int get_secret(int module, char *user, char *secret, int len)
{
char *fname = lp_secrets_file(module);
STRUCT_STAT st;
int fd, ok = 1;
char ch, *p;
if (!fname || !*fname)
return get_secret_from_keychain(module, user, secret, len);
----------------------------------------------------------------
Greetings,
Dirk
--
A: No.
Q: Should I include e-mail quotations after my reply?
More information about the rsync
mailing list