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

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: 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 convFn(int num_msg, const struct pam_message** msg,
Sergey Ulanov 2011/02/10 20:14:28 ConvFunction?
25 struct pam_response** resp, void* appdata_ptr);
26
27 UserAuthPam* user_auth_pam_;
28 pam_handle_t* pam_handle_;
29
30 // Store these for the PAM conversation function.
31 std::string username_;
32 std::string password_;
33 };
34
35 UserAuthPamPimpl::UserAuthPamPimpl(UserAuthPam* user_auth_pam)
36 : user_auth_pam_(user_auth_pam) {
37 }
38
39 UserAuthPamPimpl::~UserAuthPamPimpl() {
40 }
41
42 bool UserAuthPamPimpl::Authenticate(const std::string& username,
43 const std::string& password) {
Sergey Ulanov 2011/02/10 20:14:28 nit: wrapped arguments should be aligned with the
44 username_ = username;
45 password_ = password;
46 struct pam_conv c;
47 c.conv = convFn;
48 c.appdata_ptr = static_cast<void*>(this);
49 // TODO(lambroslambrou): allow PAM service name to be configurable
Sergey Ulanov 2011/02/10 20:14:28 nit: comments should be full sentences: start with
50 if (pam_start("chromoting", username_.c_str(), &c, &pam_handle_) !=
51 PAM_SUCCESS) {
52 return false;
53 }
54
55 // TODO(lambroslambrou): move to separate thread
Sergey Ulanov 2011/02/10 20:14:28 nit: same here
56 int pam_status = pam_authenticate(pam_handle_, 0);
57 pam_end(pam_handle_, pam_status);
58 return pam_status == PAM_SUCCESS;
59 }
60
61 // static
62 int UserAuthPamPimpl::convFn(int num_msg, const struct pam_message** msg,
63 struct pam_response** resp, void* appdata_ptr) {
Sergey Ulanov 2011/02/10 20:14:28 nit: indent properly
64 if (num_msg <= 0)
65 return PAM_CONV_ERR;
66 UserAuthPamPimpl* user_auth =
67 reinterpret_cast<UserAuthPamPimpl*>(appdata_ptr);
68 // Must allocate with malloc(), as the calling PAM module will
69 // release the memory with free().
70 struct pam_response* resp_tmp = reinterpret_cast<struct pam_response*>(
71 malloc(num_msg * sizeof(struct pam_response)));
72 if (resp_tmp == NULL)
73 return PAM_CONV_ERR;
74 bool raise_error = false;
75 int count;
Sergey Ulanov 2011/02/10 20:14:28 This can be inside of for()
76 for (count = 0; count < num_msg; count++) {
77 // Alias for readability
Sergey Ulanov 2011/02/10 20:14:28 nit: period at the end of the sentence.
78 struct pam_response &r = resp_tmp[count];
79 r.resp_retcode = 0;
80 r.resp = NULL;
81 switch (msg[count]->msg_style) {
82 case PAM_PROMPT_ECHO_ON:
83 r.resp = strdup(user_auth->username_.c_str());
84 if (r.resp == NULL)
85 raise_error = true;
86 break;
87 case PAM_PROMPT_ECHO_OFF:
88 r.resp = strdup(user_auth->password_.c_str());
89 if (r.resp == NULL)
90 raise_error = true;
91 break;
92 case PAM_TEXT_INFO:
93 // No response needed, continue with next prompt.
94 break;
95 default:
96 // Unexpected style code, so abort.
97 raise_error = true;
98 }
99 if (raise_error)
100 break;
101 }
102
103 if (raise_error) {
104 // Not passing the response back, so free up any memory used.
105 for (int n = 0; n < count; n++) {
106 if (resp_tmp[n].resp) {
107 free(resp_tmp[n].resp);
108 }
109 }
110 free(resp_tmp);
111 return PAM_CONV_ERR;
112 } else {
113 *resp = resp_tmp;
114 return PAM_SUCCESS;
115 }
116 }
117
118 UserAuthPam::UserAuthPam()
119 : pimpl_(new UserAuthPamPimpl(this)) {
120 }
121
122 UserAuthPam::~UserAuthPam() {
123 }
124
125 bool UserAuthPam::Authenticate(const std::string& username,
126 const std::string& password) {
127 return pimpl_->Authenticate(username, password);
128 }
129
130 } // namespace remoting
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698