Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(320)

Side by Side Diff: remoting/host/user_authenticator_pam.cc

Issue 6484002: Authenticate user/password with PAM in BeginSessionRequest() (Closed) Base URL: http://git.chromium.org/git/chromium.git@trunk
Patch Set: Some nits fixed Created 9 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
(Empty)
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "remoting/host/user_authenticator_pam.h"
6
7 #include <stdlib.h>
8
9 #include <string>
10
11 #include <security/pam_appl.h>
12
13 namespace remoting {
14
15 namespace {
16 const char kPamServiceName[] = "chromoting";
17 }
18
19 UserAuthenticatorPam::UserAuthenticatorPam() {
20 }
21
22 UserAuthenticatorPam::~UserAuthenticatorPam() {
23 }
24
25 bool UserAuthenticatorPam::Authenticate(const std::string& username,
26 const std::string& password) {
27 username_ = username;
28 password_ = password;
29 pam_conv conversation;
30 conversation.conv = ConvFunction;
31 conversation.appdata_ptr = static_cast<void*>(this);
32 // TODO(lambroslambrou): Allow PAM service name to be configurable.
33 pam_handle_t* pam_handle;
34 if (pam_start(kPamServiceName, username_.c_str(),
35 &conversation, &pam_handle) != PAM_SUCCESS) {
36 return false;
37 }
38
39 // TODO(lambroslambrou): Move to separate thread.
40 int pam_status = pam_authenticate(pam_handle, 0);
41 pam_end(pam_handle, pam_status);
42 return pam_status == PAM_SUCCESS;
43 }
44
45 // static
46 int UserAuthenticatorPam::ConvFunction(int num_msg,
47 const pam_message** msg,
48 pam_response** resp,
49 void* appdata_ptr) {
50 if (num_msg <= 0)
51 return PAM_CONV_ERR;
52 UserAuthenticatorPam* user_auth =
53 static_cast<UserAuthenticatorPam*>(appdata_ptr);
54 // Must allocate with malloc(), as the calling PAM module will
55 // release the memory with free().
56 pam_response* resp_tmp = static_cast<pam_response*>(
57 malloc(num_msg * sizeof(pam_response)));
58 if (resp_tmp == NULL)
59 return PAM_CONV_ERR;
60
61 bool raise_error = false;
62 // On exit from the loop, 'count' will hold the number of initialised items
63 // that the cleanup code needs to look at, in case of error.
64 int count;
65 for (count = 0; count < num_msg; count++) {
66 // Alias for readability.
67 pam_response* resp_item = &resp_tmp[count];
68 resp_item->resp_retcode = 0;
69 resp_item->resp = NULL;
70 switch (msg[count]->msg_style) {
71 case PAM_PROMPT_ECHO_ON:
72 resp_item->resp = strdup(user_auth->username_.c_str());
73 if (resp_item->resp == NULL)
74 raise_error = true;
75 break;
76 case PAM_PROMPT_ECHO_OFF:
77 resp_item->resp = strdup(user_auth->password_.c_str());
78 if (resp_item->resp == NULL)
79 raise_error = true;
80 break;
81 case PAM_TEXT_INFO:
82 // No response needed, as this instructs the PAM client to display
83 // text to the user. Leave as NULL and continue with next prompt.
84 break;
85 default:
86 // Unexpected style code, so abort.
87 raise_error = true;
88 }
89 if (raise_error)
90 break;
91 }
92
93 if (raise_error) {
94 // Not passing the response back, so free up any memory used.
95 for (int n = 0; n < count; n++) {
96 if (resp_tmp[n].resp) {
97 free(resp_tmp[n].resp);
98 }
99 }
100 free(resp_tmp);
101 return PAM_CONV_ERR;
102 } else {
103 *resp = resp_tmp;
104 return PAM_SUCCESS;
105 }
106 }
107
108 } // namespace remoting
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698