diff options
author | sergeyu@chromium.org <sergeyu@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-02-16 04:46:46 +0000 |
---|---|---|
committer | sergeyu@chromium.org <sergeyu@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-02-16 04:46:46 +0000 |
commit | fd11101b4e85f84eaada7c5892e0842ebcc57d9b (patch) | |
tree | 9f6b095106549080c210bdf419a93ce0dd6b85a0 /remoting | |
parent | 08105b4e5315fdc8e5552f9484f873fa58a05f19 (diff) | |
download | chromium_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.h | 30 | ||||
-rw-r--r-- | remoting/host/user_authenticator_pam.cc | 106 | ||||
-rw-r--r-- | remoting/host/user_authenticator_pam.h | 46 | ||||
-rw-r--r-- | remoting/remoting.gyp | 4 |
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', ], }, }], |