diff -ur smbpwman-0.5/smbpwman.c smbpwman-0.5.comment/smbpwman.c --- smbpwman-0.5.orig/smbpwman.c 2002-05-02 11:44:30.000000000 +1000 +++ smbpwman-0.5/smbpwman.c 2004-08-20 00:40:41.000000000 +1000 @@ -38,6 +38,13 @@ * * * all str commands are 0x00 terminated string of chars. + * + * Patched by Chris Jensen - 19 Aug 2004 + * Clear passwords after first use + * Overwrite passwords with 0x00 before freeing memory + * Overwrite and free all passwords on server shutdown + * Add --verbose option to prevent disconnection from terminal + * and print debugging */ #include "version.h" @@ -52,6 +59,21 @@ char *value; } *root = 0; +/* clean_free_str + Whipes a string to all 0 before freeing it + Used to ensure passwords are not left in memory +*/ +void clean_free_str(char **ptr) +{ + if (*ptr) + { + memset(*ptr, 0x00, strlen(*ptr)); + free(*ptr); + } + + *ptr = NULL; +} + int cache_store_entry(char *key, char *value) { // search from root to the end of the list... @@ -63,7 +85,8 @@ if(strcmp((*entry)->key, key) == 0) { //printf("Already an entry for key %s\n", key); - free((*entry)->value); + clean_free_str(&((*entry)->value)); + (*entry)->value = strdup(value); return 1; } @@ -80,16 +103,39 @@ return 0; } +/* scrub_memory + Write 0x00 over all passwords stored in memory before shutting down +*/ +void scrub_memory(void) +{ + struct entry_t *entry = root; + + while (entry) + { + clean_free_str(&(entry->key)); + clean_free_str(&(entry->value)); + + entry = entry->next; + } +} + char *cache_retrieve_entry(char *key) { struct entry_t *entry = root; + char *password = NULL; while(entry) { //printf("%s, %s\n", entry->key, entry->value); if(strcmp(key, entry->key) == 0) { - return entry->value; + if (entry->value) + { + password = strdup(entry->value); + + clean_free_str(&(entry->value)); + } + return password; } entry = entry->next; } @@ -158,22 +204,35 @@ return 1; } + if ((argc > 1) && (((strcmp(argv[1], "--verbose") == 0) || + (strcmp(argv[1], "-v") == 0)))) + { + verbose = 1; + } - // detach process... - cpid=fork(); - if(cpid != 0) + if (!verbose) { - exit(0); + // detach process... + cpid=fork(); + + if(cpid != 0) + { + exit(0); + } + setsid(); + chdir("/"); } - setsid(); - chdir("/"); fprintf(lock, "%d\n", getpid()); + fclose(lock); - close(0); - close(1); - close(2); + if (!verbose) + { + close(0); + close(1); + close(2); + } log(LOG_INFO, "smbpwman daemon version %s ready\n", VERSION); while(1) @@ -241,6 +300,7 @@ result = 0x00; write(cs, &result, sizeof(result)); write(cs, password, strlen(password) + 1); + clean_free_str(&password); } else { @@ -255,6 +315,7 @@ printf("SHUTDOWN\n"); } log(LOG_INFO, "shutdown request. daemon terminating\n"); + scrub_memory(); return 0; break;