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

Side by Side Diff: remoting/host/pam_authorization_factory_posix.cc

Issue 11276040: Implemented local login check for PAM (only enabled on Linux for now). (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Added explicit dtors. Created 8 years, 1 month 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
« no previous file with comments | « remoting/host/pam_authorization_factory_posix.h ('k') | remoting/host/remoting_me2me_host.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 // Copyright (c) 2012 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/pam_authorization_factory_posix.h"
6
7 #include <security/pam_appl.h>
8
9 #include "base/environment.h"
10 #include "base/logging.h"
11 #include "remoting/protocol/channel_authenticator.h"
12 #include "third_party/libjingle/source/talk/xmllite/xmlelement.h"
13
14 namespace remoting {
15
16 namespace {
17 class PamAuthorizer : public protocol::Authenticator {
18 public:
19 PamAuthorizer(scoped_ptr<protocol::Authenticator> underlying);
20 virtual ~PamAuthorizer();
21
22 // protocol::Authenticator interface.
23 virtual State state() const OVERRIDE;
24 virtual RejectionReason rejection_reason() const OVERRIDE;
25 virtual void ProcessMessage(const buzz::XmlElement* message) OVERRIDE;
26 virtual scoped_ptr<buzz::XmlElement> GetNextMessage() OVERRIDE;
27 virtual scoped_ptr<protocol::ChannelAuthenticator>
28 CreateChannelAuthenticator() const OVERRIDE;
29
30 private:
31 void MaybeCheckLocalLogin();
32 bool IsLocalLoginAllowed();
33
34 static int PamConversation(int num_messages,
35 const struct pam_message** messages,
36 struct pam_response** responses,
37 void* context);
38
39 scoped_ptr<protocol::Authenticator> underlying_;
40 enum { NOT_CHECKED, ALLOWED, DISALLOWED } local_login_status_;
41 };
42 } // namespace
43
44 PamAuthorizer::PamAuthorizer(scoped_ptr<protocol::Authenticator> underlying)
45 : underlying_(underlying.Pass()),
46 local_login_status_(NOT_CHECKED) {
47 }
48
49 PamAuthorizer::~PamAuthorizer() {
50 }
51
52 protocol::Authenticator::State PamAuthorizer::state() const {
53 if (local_login_status_ == DISALLOWED) {
54 return REJECTED;
55 } else {
56 return underlying_->state();
57 }
58 }
59
60 protocol::Authenticator::RejectionReason
61 PamAuthorizer::rejection_reason() const {
62 if (local_login_status_ == DISALLOWED) {
63 return INVALID_CREDENTIALS;
64 } else {
65 return underlying_->rejection_reason();
66 }
67 }
68
69 void PamAuthorizer::ProcessMessage(const buzz::XmlElement* message) {
70 underlying_->ProcessMessage(message);
71 MaybeCheckLocalLogin();
72 }
73
74 scoped_ptr<buzz::XmlElement> PamAuthorizer::GetNextMessage() {
75 scoped_ptr<buzz::XmlElement> result (underlying_->GetNextMessage());
76 MaybeCheckLocalLogin();
77 return result.Pass();
78 }
79
80 scoped_ptr<protocol::ChannelAuthenticator>
81 PamAuthorizer::CreateChannelAuthenticator() const {
82 return underlying_->CreateChannelAuthenticator();
83 }
84
85 void PamAuthorizer::MaybeCheckLocalLogin() {
86 if (local_login_status_ == NOT_CHECKED && state() == ACCEPTED) {
87 local_login_status_ = IsLocalLoginAllowed() ? ALLOWED : DISALLOWED;
88 }
89 }
90
91 bool PamAuthorizer::IsLocalLoginAllowed() {
92 std::string username;
93 if (!base::Environment::Create()->GetVar("USER", &username)) {
94 return false;
95 }
96
97 struct pam_conv conv = { PamConversation, NULL };
98 pam_handle_t* handle = NULL;
99 int result = pam_start("chrome-remote-desktop", username.c_str(),
100 &conv, &handle);
101 if (result == PAM_SUCCESS) {
102 result = pam_acct_mgmt(handle, 0);
103 }
104 pam_end(handle, result);
105
106 LOG(INFO) << "Local login check for " << username
107 << (result == PAM_SUCCESS ? " succeeded." : " failed.");
108
109 return result == PAM_SUCCESS;
110 }
111
112 int PamAuthorizer::PamConversation(int num_messages,
113 const struct pam_message** messages,
114 struct pam_response** responses,
115 void* context) {
116 // Assume we're only being asked to log messages, in which case our response
117 // need to be free()-able zero-initialized memory.
Wez 2012/10/26 21:52:23 nit: If we're assuming then should we CHECK()? Wi
Jamie 2012/10/26 22:13:53 We do effectively CHECK via the LOG(FATAL) below.
118 *responses = static_cast<struct pam_response*>(
119 calloc(num_messages, sizeof(struct pam_response)));
120 // We don't expect this function to be called. Since we have no easy way
Wez 2012/10/26 21:52:23 nit: Blank line before this comment.
Jamie 2012/10/26 22:13:53 Done.
121 // of returning a response, we consider it to be an error if we're asked
122 // for one. Informational and error messages are logged.
123 for (int i = 0; i < num_messages; ++i) {
124 const struct pam_message* message = messages[i];
125 switch (message->msg_style) {
126 case PAM_ERROR_MSG:
127 LOG(ERROR) << "PAM conversation error message: " << message->msg;
128 break;
129 case PAM_TEXT_INFO:
130 LOG(INFO) << "PAM conversation message: " << message->msg;
131 break;
132 default:
133 LOG(FATAL) << "Unexpected PAM conversation response required: "
134 << message->msg << "; msg_style = " << message->msg_style;
135 }
136 }
137 return PAM_SUCCESS;
138 }
139
140
141 PamAuthorizationFactory::PamAuthorizationFactory(
142 scoped_ptr<protocol::AuthenticatorFactory> underlying)
143 : underlying_(underlying.Pass()) {
144 }
145
146 PamAuthorizationFactory::~PamAuthorizationFactory() {
147 }
148
149 scoped_ptr<protocol::Authenticator>
150 PamAuthorizationFactory::CreateAuthenticator(
151 const std::string& local_jid,
152 const std::string& remote_jid,
153 const buzz::XmlElement* first_message) {
154 scoped_ptr<protocol::Authenticator> authenticator(
155 underlying_->CreateAuthenticator(local_jid, remote_jid, first_message));
156 return scoped_ptr<protocol::Authenticator>(
157 new PamAuthorizer(authenticator.Pass()));
158 }
159
160
161 } // namespace remoting
OLDNEW
« no previous file with comments | « remoting/host/pam_authorization_factory_posix.h ('k') | remoting/host/remoting_me2me_host.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698