--- smbpwman-0.5.orig/smbpw.h 2002-05-02 11:44:30.000000000 +1000 +++ smbpwman-0.5.orig/smbpw.h 2004-08-20 17:58:02.000000000 +1000 @@ -46,5 +46,8 @@ int store(char *username, char *password); char *retrieve(char *username); int shutdown_server(void); +#ifdef DEBUG +void dump(void); +#endif /* DEBUG */ #endif --- smbpwman-0.5.orig/smbpwcommon.c 2002-05-02 11:44:30.000000000 +1000 +++ smbpwman-0.5.orig/smbpwcommon.c 2004-08-20 17:58:02.000000000 +1000 @@ -249,6 +249,19 @@ return 0; } +#ifdef DEBUG +void dump(void) +{ + int cs; + char command = 0x03; + + cs = unix_connect(SOCKET_NAME); + + write(cs, &command, sizeof(command)); + close(cs); +} +#endif /* DEBUG */ + char *retrieve(char *username) { int cs; --- smbpwman-0.5.orig/smbpwman.c 2004-08-20 17:57:50.000000000 +1000 +++ smbpwman-0.5.orig/smbpwman.c 2004-08-20 17:58:02.000000000 +1000 @@ -45,6 +45,10 @@ * Overwrite and free all passwords on server shutdown * Add --verbose option to prevent disconnection from terminal * and print debugging + * Patched by Chris Jensen - 20 Aug 2004 + * Fix race condition in clearing passwords after 1 use + * Add dump for server debugging + * Free records completely when the password is cleared */ #include "version.h" @@ -52,11 +56,17 @@ #include #include +/* Reference counter is necissary otherwise + * the sequence store, store, retrieve, retrieve + * results in the password being cleared from the + * cache before the last retrieve command + */ struct entry_t { struct entry_t *next; char *key; char *value; + int ref; /* reference counter */ } *root = 0; /* clean_free_str @@ -84,6 +94,7 @@ { if(strcmp((*entry)->key, key) == 0) { + (*entry)->ref++; //printf("Already an entry for key %s\n", key); clean_free_str(&((*entry)->value)); @@ -96,6 +107,7 @@ // not already exist new = malloc(sizeof(struct entry_t)); new->next = 0; + new->ref=1; new->key = strdup(key); new->value = strdup(value); *entry = new; @@ -119,10 +131,36 @@ } } +#ifdef DEBUG +/* cache_dump + * Dump all cached users and passwords to + * the console. + * For obvious security reasons, this is only enabled if DEBUG is defined. + */ +void cache_dump(void) +{ + struct entry_t *entry = root; + int count = 0; + + while (entry) + { + count++; + printf("%i, User: %s, Password: %s, Ref: %i\n", + count, entry->key, entry->value, + entry->ref); + + entry = entry->next; + } + + printf("Total: %i\n", count); +} +#endif + char *cache_retrieve_entry(char *key) { struct entry_t *entry = root; char *password = NULL; + struct entry_t **prev = &root; while(entry) { @@ -133,10 +171,17 @@ { password = strdup(entry->value); - clean_free_str(&(entry->value)); + if ((--(entry->ref)) < 1) + { + clean_free_str(&(entry->value)); + + *prev=entry->next; + free(entry); + } } return password; } + prev = &entry->next; entry = entry->next; } return 0; @@ -318,6 +363,16 @@ scrub_memory(); return 0; break; +#ifdef DEBUG + case 0x03: + if(verbose) + { + printf("DUMP\n"); + log(LOG_WARNING, "smbpwman: performing dump of all users and passwords to terminal."); + cache_dump(); + } + break; +#endif /* DEBUG */ default: break; --- smbpwman-0.5.orig/smbpwtest.c 2002-05-23 19:26:14.000000000 +1000 +++ smbpwman-0.5.orig/smbpwtest.c 2004-08-20 17:58:02.000000000 +1000 @@ -35,11 +35,28 @@ } } +#ifdef DEBUG + else if(argc == 2 && strcmp(argv[1], "--dump") == 0) + { + printf("Requesting dump.\n"); + dump(); + } +#endif /* DEBUG */ else if(argc == 3 && strcmp(argv[1], "--store") == 0) { password = getpass("Password: "); store(argv[2], password); } + else + { + printf("Usage:\n"); + printf("%s --store \n", argv[0]); + printf("%s --retrieve \n", argv[0]); + printf("%s --shutdown\n", argv[0]); +#ifdef DEBUG + printf("%s --dump\n", argv[0]); +#endif /* DEBUG */ + } return 0;