diff options
author | dmaclach@chromium.org <dmaclach@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-04-04 22:44:11 +0000 |
---|---|---|
committer | dmaclach@chromium.org <dmaclach@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-04-04 22:44:11 +0000 |
commit | 0b7e42805341699a240997b202d4d23aed4b458b (patch) | |
tree | 44b31edf61ace0f552a113dd56368768d9774598 /remoting/host/user_authenticator_linux.cc | |
parent | 167d52bbfbfc80f2232474eddfeb8bc587008d71 (diff) | |
download | chromium_src-0b7e42805341699a240997b202d4d23aed4b458b.zip chromium_src-0b7e42805341699a240997b202d4d23aed4b458b.tar.gz chromium_src-0b7e42805341699a240997b202d4d23aed4b458b.tar.bz2 |
Clean up remoting project
Cleaned up some file names so it simplifies our project, and gets us more inline with chromium standards.
Removed several unnecessary headers that were cluttering the remoting namespace.
Simplified some of the double pimpl implementations that we had on Linux to hide X11 stuff.
Got HostAuthentication working reasonably well as a mock.
BUG=NONE
TEST=BUILD
Review URL: http://codereview.chromium.org/6780014
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@80385 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'remoting/host/user_authenticator_linux.cc')
-rw-r--r-- | remoting/host/user_authenticator_linux.cc | 124 |
1 files changed, 123 insertions, 1 deletions
diff --git a/remoting/host/user_authenticator_linux.cc b/remoting/host/user_authenticator_linux.cc index d3b837c..b1a70cd 100644 --- a/remoting/host/user_authenticator_linux.cc +++ b/remoting/host/user_authenticator_linux.cc @@ -2,10 +2,132 @@ // 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 "remoting/host/user_authenticator.h" + +#include <security/pam_appl.h> +#include <stdlib.h> + +#include <string> + +#include "base/basictypes.h" namespace remoting { +namespace { + +// 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); +}; + +const char kPamServiceName[] = "chromoting"; + +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 + // static UserAuthenticator* UserAuthenticator::Create() { return new UserAuthenticatorPam(); |