blob: d0ca1b0398807ca2e7cf545c920fc999bf381dc5 [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 Tanous911ac312017-08-15 09:37:42 -07004#include <cstring>
Ed Tanousf3d847c2017-06-12 16:01:42 -07005
6// function used to get user input
7inline int pam_function_conversation(int num_msg,
8 const struct pam_message** msg,
9 struct pam_response** resp,
10 void* appdata_ptr) {
Ed Tanous911ac312017-08-15 09:37:42 -070011 if (appdata_ptr == nullptr) {
12 return PAM_AUTH_ERR;
13 }
14 auto* pass = reinterpret_cast<char*>(
15 malloc(std::strlen(reinterpret_cast<char*>(appdata_ptr)) + 1));
16 std::strcpy(pass, reinterpret_cast<char*>(appdata_ptr));
Ed Tanousf3d847c2017-06-12 16:01:42 -070017
Ed Tanous911ac312017-08-15 09:37:42 -070018 *resp = reinterpret_cast<pam_response*>(
19 calloc(num_msg, sizeof(struct pam_response)));
Ed Tanousf3d847c2017-06-12 16:01:42 -070020
Ed Tanous911ac312017-08-15 09:37:42 -070021 for (int i = 0; i < num_msg; ++i) {
Ed Tanousf3d847c2017-06-12 16:01:42 -070022 /* Ignore all PAM messages except prompting for hidden input */
Ed Tanous911ac312017-08-15 09:37:42 -070023 if (msg[i]->msg_style != PAM_PROMPT_ECHO_OFF) {
24 continue;
25 }
Ed Tanousf3d847c2017-06-12 16:01:42 -070026
27 /* Assume PAM is only prompting for the password as hidden input */
28 resp[i]->resp = pass;
29 }
30
31 return PAM_SUCCESS;
32}
33
Ed Tanous911ac312017-08-15 09:37:42 -070034inline bool pam_authenticate_user(const std::string& username,
35 const std::string& password) {
36 const struct pam_conv local_conversation = {
37 pam_function_conversation, const_cast<char*>(password.c_str())};
38 pam_handle_t* local_auth_handle = NULL; // this gets set by pam_start
Ed Tanousf3d847c2017-06-12 16:01:42 -070039
Ed Tanousba9f9a62017-10-11 16:40:35 -070040 if (pam_start("dropbear", username.c_str(), &local_conversation,
Ed Tanous911ac312017-08-15 09:37:42 -070041 &local_auth_handle) != PAM_SUCCESS) {
42 return false;
Ed Tanousf3d847c2017-06-12 16:01:42 -070043 }
Ed Tanous911ac312017-08-15 09:37:42 -070044 int retval = pam_authenticate(local_auth_handle,
45 PAM_SILENT | PAM_DISALLOW_NULL_AUTHTOK);
46
47 if (retval != PAM_SUCCESS) {
48 if (retval == PAM_AUTH_ERR) {
49 // printf("Authentication failure.\n");
50 } else {
51 // printf("pam_authenticate returned %d\n", retval);
52 }
53 pam_end(local_auth_handle, PAM_SUCCESS);
54 return false;
55 }
56
57 /* check that the account is healthy */
58 if (pam_acct_mgmt(local_auth_handle, PAM_DISALLOW_NULL_AUTHTOK) !=
59 PAM_SUCCESS) {
60 pam_end(local_auth_handle, PAM_SUCCESS);
61 return false;
62 }
63
64 if (pam_end(local_auth_handle, PAM_SUCCESS) != PAM_SUCCESS) {
65 return false;
66 }
67
68 return true;
69}