From 0f63670409661f068ac597ccaa66490ac0f7ddd8 Mon Sep 17 00:00:00 2001 From: "Joe Richey joerichey@google.com" Date: Mon, 17 Jul 2017 17:19:37 -0700 Subject: 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(). --- pam/pam.c | 49 +++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 39 insertions(+), 10 deletions(-) (limited to 'pam/pam.c') diff --git a/pam/pam.c b/pam/pam.c index ce640e8..e32770f 100644 --- a/pam/pam.c +++ b/pam/pam.c @@ -21,13 +21,15 @@ #include #include +#include -#include "_cgo_export.h" // for pamInput callback +#include +#include // 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 -- cgit v1.2.3