blob: 5b4b454ab4fb2b277d79ad0ec119482ae9553eb2 [file] [log] [blame]
Ed Tanous911ac312017-08-15 09:37:42 -07001#pragma once
2
Ed Tanousf3d847c2017-06-12 16:01:42 -07003#include <security/pam_appl.h>
Ed Tanousbabedfe2018-01-12 10:50:26 -08004#include <memory>
Ed Tanous911ac312017-08-15 09:37:42 -07005#include <cstring>
Ed Tanousf3d847c2017-06-12 16:01:42 -07006
7// function used to get user input
8inline int pam_function_conversation(int num_msg,
9 const struct pam_message** msg,
10 struct pam_response** resp,
11 void* appdata_ptr) {
Ed Tanous911ac312017-08-15 09:37:42 -070012 if (appdata_ptr == nullptr) {
13 return PAM_AUTH_ERR;
14 }
15 auto* pass = reinterpret_cast<char*>(
16 malloc(std::strlen(reinterpret_cast<char*>(appdata_ptr)) + 1));
17 std::strcpy(pass, reinterpret_cast<char*>(appdata_ptr));
Ed Tanousf3d847c2017-06-12 16:01:42 -070018
Ed Tanous911ac312017-08-15 09:37:42 -070019 *resp = reinterpret_cast<pam_response*>(
20 calloc(num_msg, sizeof(struct pam_response)));
Ed Tanousf3d847c2017-06-12 16:01:42 -070021
Ed Tanous911ac312017-08-15 09:37:42 -070022 for (int i = 0; i < num_msg; ++i) {
Ed Tanousf3d847c2017-06-12 16:01:42 -070023 /* Ignore all PAM messages except prompting for hidden input */
Ed Tanous911ac312017-08-15 09:37:42 -070024 if (msg[i]->msg_style != PAM_PROMPT_ECHO_OFF) {
25 continue;
26 }
Ed Tanousf3d847c2017-06-12 16:01:42 -070027
28 /* Assume PAM is only prompting for the password as hidden input */
29 resp[i]->resp = pass;
30 }
31
32 return PAM_SUCCESS;
33}
34
Ed Tanous911ac312017-08-15 09:37:42 -070035inline bool pam_authenticate_user(const std::string& username,
36 const std::string& password) {
37 const struct pam_conv local_conversation = {
38 pam_function_conversation, const_cast<char*>(password.c_str())};
39 pam_handle_t* local_auth_handle = NULL; // this gets set by pam_start
Ed Tanousf3d847c2017-06-12 16:01:42 -070040
Ed Tanousba9f9a62017-10-11 16:40:35 -070041 if (pam_start("dropbear", username.c_str(), &local_conversation,
Ed Tanous911ac312017-08-15 09:37:42 -070042 &local_auth_handle) != PAM_SUCCESS) {
43 return false;
Ed Tanousf3d847c2017-06-12 16:01:42 -070044 }
Ed Tanous911ac312017-08-15 09:37:42 -070045 int retval = pam_authenticate(local_auth_handle,
46 PAM_SILENT | PAM_DISALLOW_NULL_AUTHTOK);
47
48 if (retval != PAM_SUCCESS) {
49 if (retval == PAM_AUTH_ERR) {
50 // printf("Authentication failure.\n");
51 } else {
52 // printf("pam_authenticate returned %d\n", retval);
53 }
54 pam_end(local_auth_handle, PAM_SUCCESS);
55 return false;
56 }
57
58 /* check that the account is healthy */
59 if (pam_acct_mgmt(local_auth_handle, PAM_DISALLOW_NULL_AUTHTOK) !=
60 PAM_SUCCESS) {
61 pam_end(local_auth_handle, PAM_SUCCESS);
62 return false;
63 }
64
65 if (pam_end(local_auth_handle, PAM_SUCCESS) != PAM_SUCCESS) {
66 return false;
67 }
68
69 return true;
70}