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

Unified 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 side-by-side diff with in-line comments
Download patch
Index: remoting/host/user_auth_pam.cc
diff --git a/remoting/host/user_auth_pam.cc b/remoting/host/user_auth_pam.cc
new file mode 100644
index 0000000000000000000000000000000000000000..5c64f0c476a561c56e370ae726584416b8a2f1b1
--- /dev/null
+++ b/remoting/host/user_auth_pam.cc
@@ -0,0 +1,130 @@
+// Copyright (c) 2011 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "remoting/host/user_auth_pam.h"
+
+#include <security/pam_appl.h>
+#include <stdlib.h>
+#include <string>
+
+namespace remoting {
+
+// Private Implementation pattern to avoid leaking PAM types, and the
+// conversation function, into the header file.
+class UserAuthPamPimpl {
+ public:
+ explicit UserAuthPamPimpl(UserAuthPam* user_auth_pam);
+ ~UserAuthPamPimpl();
+ bool Authenticate(const std::string& username,
+ const std::string& password);
+
+ private:
+ // Conversation function passed to PAM as a callback.
+ static int convFn(int num_msg, const struct pam_message** msg,
Sergey Ulanov 2011/02/10 20:14:28 ConvFunction?
+ struct pam_response** resp, void* appdata_ptr);
+
+ UserAuthPam* user_auth_pam_;
+ pam_handle_t* pam_handle_;
+
+ // Store these for the PAM conversation function.
+ std::string username_;
+ std::string password_;
+};
+
+UserAuthPamPimpl::UserAuthPamPimpl(UserAuthPam* user_auth_pam)
+ : user_auth_pam_(user_auth_pam) {
+}
+
+UserAuthPamPimpl::~UserAuthPamPimpl() {
+}
+
+bool UserAuthPamPimpl::Authenticate(const std::string& username,
+ const std::string& password) {
Sergey Ulanov 2011/02/10 20:14:28 nit: wrapped arguments should be aligned with the
+ username_ = username;
+ password_ = password;
+ struct pam_conv c;
+ c.conv = convFn;
+ c.appdata_ptr = static_cast<void*>(this);
+ // 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
+ if (pam_start("chromoting", username_.c_str(), &c, &pam_handle_) !=
+ PAM_SUCCESS) {
+ return false;
+ }
+
+ // TODO(lambroslambrou): move to separate thread
Sergey Ulanov 2011/02/10 20:14:28 nit: same here
+ int pam_status = pam_authenticate(pam_handle_, 0);
+ pam_end(pam_handle_, pam_status);
+ return pam_status == PAM_SUCCESS;
+}
+
+// static
+int UserAuthPamPimpl::convFn(int num_msg, const struct pam_message** msg,
+ struct pam_response** resp, void* appdata_ptr) {
Sergey Ulanov 2011/02/10 20:14:28 nit: indent properly
+ if (num_msg <= 0)
+ return PAM_CONV_ERR;
+ UserAuthPamPimpl* user_auth =
+ reinterpret_cast<UserAuthPamPimpl*>(appdata_ptr);
+ // Must allocate with malloc(), as the calling PAM module will
+ // release the memory with free().
+ struct pam_response* resp_tmp = reinterpret_cast<struct pam_response*>(
+ malloc(num_msg * sizeof(struct pam_response)));
+ if (resp_tmp == NULL)
+ return PAM_CONV_ERR;
+ bool raise_error = false;
+ int count;
Sergey Ulanov 2011/02/10 20:14:28 This can be inside of for()
+ for (count = 0; count < num_msg; count++) {
+ // Alias for readability
Sergey Ulanov 2011/02/10 20:14:28 nit: period at the end of the sentence.
+ struct pam_response &r = resp_tmp[count];
+ r.resp_retcode = 0;
+ r.resp = NULL;
+ switch (msg[count]->msg_style) {
+ case PAM_PROMPT_ECHO_ON:
+ r.resp = strdup(user_auth->username_.c_str());
+ if (r.resp == NULL)
+ raise_error = true;
+ break;
+ case PAM_PROMPT_ECHO_OFF:
+ r.resp = strdup(user_auth->password_.c_str());
+ if (r.resp == NULL)
+ raise_error = true;
+ break;
+ case PAM_TEXT_INFO:
+ // No response needed, continue with next prompt.
+ break;
+ default:
+ // Unexpected style code, so abort.
+ raise_error = true;
+ }
+ if (raise_error)
+ break;
+ }
+
+ if (raise_error) {
+ // Not passing the response back, so free up any memory used.
+ for (int n = 0; n < count; n++) {
+ if (resp_tmp[n].resp) {
+ free(resp_tmp[n].resp);
+ }
+ }
+ free(resp_tmp);
+ return PAM_CONV_ERR;
+ } else {
+ *resp = resp_tmp;
+ return PAM_SUCCESS;
+ }
+}
+
+UserAuthPam::UserAuthPam()
+ : pimpl_(new UserAuthPamPimpl(this)) {
+}
+
+UserAuthPam::~UserAuthPam() {
+}
+
+bool UserAuthPam::Authenticate(const std::string& username,
+ const std::string& password) {
+ return pimpl_->Authenticate(username, password);
+}
+
+} // namespace remoting

Powered by Google App Engine
This is Rietveld 408576698