summaryrefslogtreecommitdiffstats
path: root/remoting
diff options
context:
space:
mode:
authorsergeyu@chromium.org <sergeyu@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-02-16 04:46:46 +0000
committersergeyu@chromium.org <sergeyu@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-02-16 04:46:46 +0000
commitfd11101b4e85f84eaada7c5892e0842ebcc57d9b (patch)
tree9f6b095106549080c210bdf419a93ce0dd6b85a0 /remoting
parent08105b4e5315fdc8e5552f9484f873fa58a05f19 (diff)
downloadchromium_src-fd11101b4e85f84eaada7c5892e0842ebcc57d9b.zip
chromium_src-fd11101b4e85f84eaada7c5892e0842ebcc57d9b.tar.gz
chromium_src-fd11101b4e85f84eaada7c5892e0842ebcc57d9b.tar.bz2
Chromoting: UserAuthenticator interface and its implementation for PAM.
BUG=none TEST=manual Review URL: http://codereview.chromium.org/6484002 Patch from Lambros Lambrou <lambroslambrou@chromium.org>. git-svn-id: svn://svn.chromium.org/chrome/trunk/src@75069 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'remoting')
-rw-r--r--remoting/host/user_authenticator.h30
-rw-r--r--remoting/host/user_authenticator_pam.cc106
-rw-r--r--remoting/host/user_authenticator_pam.h46
-rw-r--r--remoting/remoting.gyp4
4 files changed, 186 insertions, 0 deletions
diff --git a/remoting/host/user_authenticator.h b/remoting/host/user_authenticator.h
new file mode 100644
index 0000000..10f6cfd
--- /dev/null
+++ b/remoting/host/user_authenticator.h
@@ -0,0 +1,30 @@
+// 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.
+
+#ifndef REMOTING_HOST_USER_AUTHENTICATOR_H_
+#define REMOTING_HOST_USER_AUTHENTICATOR_H_
+
+#include <string>
+
+namespace remoting {
+
+// Interface for authenticating users for access to remote desktop session.
+// Implementation is platform-specific.
+// Implementations may assume each instance of this class handles only a
+// single Authenticate request.
+// TODO(lambroslambrou): Decide whether this needs an asychronous interface
+// (for example AuthenticateStart()..AuthenticateEndCallback()), or whether the
+// multi-threading policy could be handled by the caller.
+class UserAuthenticator {
+ public:
+ virtual ~UserAuthenticator() {}
+
+ // Authenticate a user, returning true if the username/password are valid.
+ virtual bool Authenticate(const std::string& username,
+ const std::string& password) = 0;
+};
+
+} // namespace remoting
+
+#endif // REMOTING_HOST_USER_AUTHENTICATOR_H_
diff --git a/remoting/host/user_authenticator_pam.cc b/remoting/host/user_authenticator_pam.cc
new file mode 100644
index 0000000..5a45f4c
--- /dev/null
+++ b/remoting/host/user_authenticator_pam.cc
@@ -0,0 +1,106 @@
+// 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_authenticator_pam.h"
+
+#include <stdlib.h>
+
+#include <string>
+
+#include <security/pam_appl.h>
+
+namespace remoting {
+
+static const char kPamServiceName[] = "chromoting";
+
+UserAuthenticatorPam::UserAuthenticatorPam() {
+}
+
+UserAuthenticatorPam::~UserAuthenticatorPam() {
+}
+
+bool UserAuthenticatorPam::Authenticate(const std::string& username,
+ const std::string& password) {
+ username_ = username;
+ password_ = password;
+ pam_conv conversation;
+ conversation.conv = ConvFunction;
+ conversation.appdata_ptr = static_cast<void*>(this);
+ // TODO(lambroslambrou): Allow PAM service name to be configurable.
+ pam_handle_t* pam_handle;
+ if (pam_start(kPamServiceName, username_.c_str(),
+ &conversation, &pam_handle) != PAM_SUCCESS) {
+ return false;
+ }
+
+ // TODO(lambroslambrou): Move to separate thread.
+ int pam_status = pam_authenticate(pam_handle, 0);
+ pam_end(pam_handle, pam_status);
+ return pam_status == PAM_SUCCESS;
+}
+
+// static
+int UserAuthenticatorPam::ConvFunction(int num_msg,
+ const pam_message** msg,
+ pam_response** resp,
+ void* appdata_ptr) {
+ if (num_msg <= 0)
+ return PAM_CONV_ERR;
+ UserAuthenticatorPam* user_auth =
+ static_cast<UserAuthenticatorPam*>(appdata_ptr);
+ // Must allocate with malloc(), as the calling PAM module will
+ // release the memory with free().
+ pam_response* resp_tmp = static_cast<pam_response*>(
+ malloc(num_msg * sizeof(pam_response)));
+ if (resp_tmp == NULL)
+ return PAM_CONV_ERR;
+
+ bool raise_error = false;
+ // On exit from the loop, 'count' will hold the number of initialised items
+ // that the cleanup code needs to look at, in case of error.
+ int count;
+ for (count = 0; count < num_msg; count++) {
+ // Alias for readability.
+ pam_response* resp_item = &resp_tmp[count];
+ resp_item->resp_retcode = 0;
+ resp_item->resp = NULL;
+ switch (msg[count]->msg_style) {
+ case PAM_PROMPT_ECHO_ON:
+ resp_item->resp = strdup(user_auth->username_.c_str());
+ if (resp_item->resp == NULL)
+ raise_error = true;
+ break;
+ case PAM_PROMPT_ECHO_OFF:
+ resp_item->resp = strdup(user_auth->password_.c_str());
+ if (resp_item->resp == NULL)
+ raise_error = true;
+ break;
+ case PAM_TEXT_INFO:
+ // No response needed, as this instructs the PAM client to display
+ // text to the user. Leave as NULL and 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;
+ }
+}
+
+} // namespace remoting
diff --git a/remoting/host/user_authenticator_pam.h b/remoting/host/user_authenticator_pam.h
new file mode 100644
index 0000000..f854731
--- /dev/null
+++ b/remoting/host/user_authenticator_pam.h
@@ -0,0 +1,46 @@
+// 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.
+
+#ifndef REMOTING_HOST_USER_AUTHENTICATOR_PAM_H_
+#define REMOTING_HOST_USER_AUTHENTICATOR_PAM_H_
+
+#include <string>
+
+#include "base/basictypes.h"
+#include "remoting/host/user_authenticator.h"
+
+struct pam_message;
+struct pam_response;
+
+namespace remoting {
+
+// Class to perform a single PAM user authentication.
+//
+// TODO(lambroslambrou): As pam_authenticate() can be blocking, this needs to
+// expose an asynchronous API, with pam_authenticate() called in a background
+// thread.
+class UserAuthenticatorPam : public UserAuthenticator {
+ public:
+ UserAuthenticatorPam();
+ virtual ~UserAuthenticatorPam();
+ virtual bool Authenticate(const std::string& username,
+ const std::string& password);
+
+ private:
+ // Conversation function passed to PAM as a callback.
+ static int ConvFunction(int num_msg,
+ const pam_message** msg,
+ pam_response** resp,
+ void* appdata_ptr);
+
+ // Store these for the PAM conversation function.
+ std::string username_;
+ std::string password_;
+
+ DISALLOW_COPY_AND_ASSIGN(UserAuthenticatorPam);
+};
+
+} // namespace remoting
+
+#endif // REMOTING_HOST_USER_AUTHENTICATOR_PAM_H_
diff --git a/remoting/remoting.gyp b/remoting/remoting.gyp
index 9b5239f..f1b2ec3 100644
--- a/remoting/remoting.gyp
+++ b/remoting/remoting.gyp
@@ -212,6 +212,7 @@
'host/json_host_config.h',
'host/in_memory_host_config.cc',
'host/in_memory_host_config.h',
+ 'host/user_authenticator.h',
],
'conditions': [
['OS=="win"', {
@@ -228,12 +229,15 @@
'host/capturer_linux.h',
'host/event_executor_linux.cc',
'host/event_executor_linux.h',
+ 'host/user_authenticator_pam.cc',
+ 'host/user_authenticator_pam.h',
],
'link_settings': {
'libraries': [
'-lX11',
'-lXdamage',
'-lXtst',
+ '-lpam',
],
},
}],