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

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

Issue 6484002: Authenticate user/password with PAM in BeginSessionRequest() (Closed) Base URL: http://git.chromium.org/git/chromium.git@trunk
Patch Set: Fixes for review comments 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_auth_pam.h"
6
7 #include <security/pam_appl.h>
8 #include <stdlib.h>
9 #include <string>
10
11 namespace remoting {
12
13 // Private Implementation pattern to avoid leaking PAM types, and the
14 // conversation function, into the header file.
15 class UserAuthPamPimpl {
16 public:
17 explicit UserAuthPamPimpl(UserAuthPam* user_auth_pam);
18 ~UserAuthPamPimpl();
19 bool Authenticate(const std::string& username,
20 const std::string& password);
21
22 private:
23 // Conversation function passed to PAM as a callback.
24 static int convFunction(int num_msg,
Sergey Ulanov 2011/02/11 19:35:20 Capital C. Function names and class names must alw
25 const struct pam_message** msg,
26 struct pam_response** resp,
27 void* appdata_ptr);
28
29 UserAuthPam* user_auth_pam_;
30 pam_handle_t* pam_handle_;
31
32 // Store these for the PAM conversation function.
33 std::string username_;
34 std::string password_;
35 };
36
37 UserAuthPamPimpl::UserAuthPamPimpl(UserAuthPam* user_auth_pam)
38 : user_auth_pam_(user_auth_pam) {
39 }
40
41 UserAuthPamPimpl::~UserAuthPamPimpl() {
42 }
43
44 bool UserAuthPamPimpl::Authenticate(const std::string& username,
45 const std::string& password) {
46 username_ = username;
47 password_ = password;
48 struct pam_conv c;
49 c.conv = convFunction;
50 c.appdata_ptr = static_cast<void*>(this);
51 // TODO(lambroslambrou): Allow PAM service name to be configurable.
52 if (pam_start("chromoting", username_.c_str(), &c, &pam_handle_) !=
53 PAM_SUCCESS) {
54 return false;
55 }
56
57 // TODO(lambroslambrou): Move to separate thread.
58 int pam_status = pam_authenticate(pam_handle_, 0);
59 pam_end(pam_handle_, pam_status);
60 return pam_status == PAM_SUCCESS;
61 }
62
63 // static
64 int UserAuthPamPimpl::convFunction(int num_msg,
65 const struct pam_message** msg,
66 struct pam_response** resp,
67 void* appdata_ptr) {
68 if (num_msg <= 0)
69 return PAM_CONV_ERR;
70 UserAuthPamPimpl* user_auth =
71 reinterpret_cast<UserAuthPamPimpl*>(appdata_ptr);
72 // Must allocate with malloc(), as the calling PAM module will
73 // release the memory with free().
74 struct pam_response* resp_tmp = reinterpret_cast<struct pam_response*>(
75 malloc(num_msg * sizeof(struct pam_response)));
76 if (resp_tmp == NULL)
77 return PAM_CONV_ERR;
78 bool raise_error = false;
79 // On exit from the loop, 'count' will hold the number of initialised items
80 // that the cleanup code needs to look at, in case of error.
81 int count;
82 for (count = 0; count < num_msg; count++) {
83 // Alias for readability.
84 struct pam_response& r = resp_tmp[count];
85 r.resp_retcode = 0;
86 r.resp = NULL;
87 switch (msg[count]->msg_style) {
88 case PAM_PROMPT_ECHO_ON:
89 r.resp = strdup(user_auth->username_.c_str());
90 if (r.resp == NULL)
91 raise_error = true;
92 break;
93 case PAM_PROMPT_ECHO_OFF:
94 r.resp = strdup(user_auth->password_.c_str());
95 if (r.resp == NULL)
96 raise_error = true;
97 break;
98 case PAM_TEXT_INFO:
99 // No response needed, continue with next prompt.
100 break;
101 default:
102 // Unexpected style code, so abort.
103 raise_error = true;
104 }
105 if (raise_error)
106 break;
107 }
108
109 if (raise_error) {
110 // Not passing the response back, so free up any memory used.
111 for (int n = 0; n < count; n++) {
112 if (resp_tmp[n].resp) {
113 free(resp_tmp[n].resp);
114 }
115 }
116 free(resp_tmp);
117 return PAM_CONV_ERR;
118 } else {
119 *resp = resp_tmp;
120 return PAM_SUCCESS;
121 }
122 }
123
124 UserAuthPam::UserAuthPam()
125 : pimpl_(new UserAuthPamPimpl(this)) {
126 }
127
128 UserAuthPam::~UserAuthPam() {
129 }
130
131 bool UserAuthPam::Authenticate(const std::string& username,
132 const std::string& password) {
133 return pimpl_->Authenticate(username, password);
134 }
135
136 } // namespace remoting
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698