diff options
| author | Joe Richey joerichey@google.com <joerichey@google.com> | 2017-07-17 17:19:37 -0700 |
|---|---|---|
| committer | Joe Richey joerichey@google.com <joerichey@google.com> | 2017-07-17 17:19:37 -0700 |
| commit | 0f63670409661f068ac597ccaa66490ac0f7ddd8 (patch) | |
| tree | 759eb2515b4fa560a2e10360621dfb8d841a03da | |
| parent | 46da5280eb7fe9fafabaee5c7202732fa15a034a (diff) | |
pam: C implementation for conversation and cleanup
This commit adds in a C implementation for the pam_conv we will use in
login.go as well as adding three CleanupFuncs that will be used with
pam_set_data(). It also adds copyInfoSecret() which should be paired
with freeSecret().
| -rw-r--r-- | pam/pam.c | 49 | ||||
| -rw-r--r-- | pam/pam.h | 23 |
2 files changed, 57 insertions, 15 deletions
@@ -21,13 +21,15 @@ #include <stdio.h> #include <stdlib.h> +#include <string.h> -#include "_cgo_export.h" // for pamInput callback +#include <security/pam_appl.h> +#include <sys/mman.h> // mlock/munlock -const char* fscrypt_service = "fscrypt"; +#include "_cgo_export.h" // for input callbacks -static int pam_conv(int num_msg, const struct pam_message** msg, - struct pam_response** resp, void* appdata_ptr) { +static int conversation(int num_msg, const struct pam_message** msg, + struct pam_response** resp, void* appdata_ptr) { if (num_msg <= 0 || num_msg > PAM_MAX_NUM_MSG) { return PAM_CONV_ERR; } @@ -49,16 +51,14 @@ static int pam_conv(int num_msg, const struct pam_message** msg, // we just print the error messages or text info to standard output. switch (msg[i]->msg_style) { case PAM_PROMPT_ECHO_OFF: - callback_resp = pamInput(callback_msg); + callback_resp = passphraseInput(callback_msg); break; case PAM_PROMPT_ECHO_ON: - // We should never have a request for non-secret data - unexpectedMessage(callback_msg); - callback_resp = NULL; + callback_resp = userInput(callback_msg); break; case PAM_ERROR_MSG: case PAM_TEXT_INFO: - printf("%s\n", callback_msg); + fprintf(stderr, "%s\n", callback_msg); continue; } @@ -69,12 +69,41 @@ static int pam_conv(int num_msg, const struct pam_message** msg, free((*resp)[i].resp); } free(*resp); + *resp = NULL; return PAM_CONV_ERR; } (*resp)[i].resp = callback_resp; } + return PAM_SUCCESS; } -void pam_init(struct pam_conv* conv) { conv->conv = pam_conv; } +const struct pam_conv conv = {conversation, NULL}; + +void freeData(pam_handle_t* pamh, void* data, int error_status) { free(data); } + +void freeArray(pam_handle_t* pamh, void** array, int error_status) { + int i; + for (i = 0; array[i]; ++i) { + free(array[i]); + } + free(array); +} + +void* copyIntoSecret(void* data) { + size_t size = strlen(data) + 1; // include null terminator + void* copy = malloc(size); + mlock(copy, size); + memcpy(copy, data, size); + return copy; +} + +void freeSecret(pam_handle_t* pamh, char* data, int error_status) { + size_t size = strlen(data) + 1; // Include null terminator + // Use volitile function pointer to actually clear the memory. + static void* (*const volatile memset_sec)(void*, int, size_t) = &memset; + memset_sec(data, 0, size); + munlock(data, size); + free(data); +}
\ No newline at end of file @@ -22,10 +22,23 @@ #include <security/pam_appl.h> -// fscrypt_service is the display name of the service requesting the passphrase. -const char* fscrypt_service; +// Conversation that will call back into Go code when appropriate. +const struct pam_conv conv; -// pam_init initializes the pam_conv structure for use with our Go callbacks. -void pam_init(struct pam_conv* conv); +// CleaupFuncs are used to cleanup specific PAM data. +typedef void (*CleanupFunc)(pam_handle_t *pamh, void *data, int error_status); -#endif +// CleaupFunc that calls free() on data. +void freeData(pam_handle_t *pamh, void *data, int error_status); + +// CleaupFunc that frees each item in a null terminated array of pointers and +// then frees the array itself. +void freeArray(pam_handle_t *pamh, void **array, int error_status); + +// Creates a copy of a C string, which resides in an locked buffer. +void *copyIntoSecret(void *data); + +// CleaupFunc that Zeros wipes a C string and unlocks and frees its memory. +void freeSecret(pam_handle_t *pamh, char *data, int error_status); + +#endif // FSCRYPT_PAM_H |