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

Side by Side Diff: session_manager_service.cc

Issue 6239002: [login_manager] Prevent non-children from calling RestartJob (Closed) Base URL: http://git.chromium.org/git/login_manager.git@master
Patch Set: Created 9 years, 11 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 unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « session_manager_service.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2009-2010 The Chromium OS Authors. All rights reserved. 1 // Copyright (c) 2009-2010 The Chromium OS Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "login_manager/session_manager_service.h" 5 #include "login_manager/session_manager_service.h"
6 6
7 #include <dbus/dbus-glib-lowlevel.h> 7 #include <dbus/dbus-glib-lowlevel.h>
8 #include <errno.h> 8 #include <errno.h>
9 #include <glib.h> 9 #include <glib.h>
10 #include <grp.h> 10 #include <grp.h>
(...skipping 188 matching lines...) Expand 10 before | Expand all | Expand 10 after
199 G_TYPE_NONE, // return type 199 G_TYPE_NONE, // return type
200 2, // num params 200 2, // num params
201 G_TYPE_STRING, // state ("started" or "stopped") 201 G_TYPE_STRING, // state ("started" or "stopped")
202 G_TYPE_STRING); // current user 202 G_TYPE_STRING); // current user
203 203
204 if (!store_->LoadOrCreate()) 204 if (!store_->LoadOrCreate())
205 LOG(ERROR) << "Could not load existing settings. Continuing anyway..."; 205 LOG(ERROR) << "Could not load existing settings. Continuing anyway...";
206 return Reset(); 206 return Reset();
207 } 207 }
208 208
209 bool SessionManagerService::Register(
210 const chromeos::dbus::BusConnection &connection) {
211 if (!chromeos::dbus::AbstractDbusService::Register(connection))
212 return false;
213 const std::string filter =
214 StringPrintf("type='method_call', interface='%s'", service_interface());
215 DBusConnection* conn =
216 ::dbus_g_connection_get_connection(connection.g_connection());
217 CHECK(conn);
218 DBusError error;
219 ::dbus_error_init(&error);
220 ::dbus_bus_add_match(conn, filter.c_str(), &error);
221 if (::dbus_error_is_set(&error)) {
222 LOG(WARNING) << "Failed to add match to bus: " << error.name << ", message="
223 << (error.message ? error.message : "unknown error");
224 return false;
225 }
226 if (!::dbus_connection_add_filter(conn,
227 &SessionManagerService::FilterMessage,
228 this,
229 NULL)) {
230 LOG(WARNING) << "Failed to add filter to connection";
231 return false;
232 }
233 return true;
234 }
235
209 bool SessionManagerService::Reset() { 236 bool SessionManagerService::Reset() {
210 if (session_manager_) 237 if (session_manager_)
211 g_object_unref(session_manager_); 238 g_object_unref(session_manager_);
212 session_manager_ = 239 session_manager_ =
213 reinterpret_cast<gobject::SessionManager*>( 240 reinterpret_cast<gobject::SessionManager*>(
214 g_object_new(gobject::session_manager_get_type(), NULL)); 241 g_object_new(gobject::session_manager_get_type(), NULL));
215 242
216 // Allow references to this instance. 243 // Allow references to this instance.
217 session_manager_->service = this; 244 session_manager_->service = this;
218 245
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after
305 exit(1); // Run() is not supposed to return. 332 exit(1); // Run() is not supposed to return.
306 } 333 }
307 g_child_watch_add_full(G_PRIORITY_HIGH_IDLE, 334 g_child_watch_add_full(G_PRIORITY_HIGH_IDLE,
308 pid, 335 pid,
309 HandleChildExit, 336 HandleChildExit,
310 this, 337 this,
311 NULL); 338 NULL);
312 return pid; 339 return pid;
313 } 340 }
314 341
342 bool SessionManagerService::IsKnownChild(int pid) {
343 return std::find(child_pids_.begin(), child_pids_.end(), pid) !=
344 child_pids_.end();
345 }
346
315 void SessionManagerService::AllowGracefulExit() { 347 void SessionManagerService::AllowGracefulExit() {
316 shutting_down_ = true; 348 shutting_down_ = true;
317 if (exit_on_child_done_) { 349 if (exit_on_child_done_) {
318 g_idle_add_full(G_PRIORITY_DEFAULT_IDLE, 350 g_idle_add_full(G_PRIORITY_DEFAULT_IDLE,
319 ServiceShutdown, 351 ServiceShutdown,
320 this, 352 this,
321 NULL); 353 NULL);
322 } 354 }
323 } 355 }
324 356
(...skipping 476 matching lines...) Expand 10 before | Expand all | Expand 10 after
801 if (at == string::npos) 833 if (at == string::npos)
802 return false; 834 return false;
803 835
804 // it has more than one @. 836 // it has more than one @.
805 if (email_address.find(kEmailSeparator, at+1) != string::npos) 837 if (email_address.find(kEmailSeparator, at+1) != string::npos)
806 return false; 838 return false;
807 839
808 return true; 840 return true;
809 } 841 }
810 842
843 // static
844 DBusHandlerResult SessionManagerService::FilterMessage(DBusConnection* conn,
845 DBusMessage* message,
846 void* data) {
847 SessionManagerService* service = static_cast<SessionManagerService*>(data);
848 if (::dbus_message_is_method_call(message,
849 service->service_interface(),
850 kSessionManagerRestartJob)) {
851 const char* sender = ::dbus_message_get_sender(message);
852 if (!sender) {
853 LOG(ERROR) << "Call to RestartJob has no sender";
854 return DBUS_HANDLER_RESULT_HANDLED;
855 }
856 LOG(INFO) << "Received RestartJob from " << sender;
857 DBusMessage* get_pid =
858 ::dbus_message_new_method_call("org.freedesktop.DBus",
859 "/org/freedesktop/DBus",
860 "org.freedesktop.DBus",
861 "GetConnectionUnixProcessID");
862 CHECK(get_pid);
863 ::dbus_message_append_args(get_pid,
864 DBUS_TYPE_STRING, &sender,
865 DBUS_TYPE_INVALID);
866 DBusMessage* got_pid =
867 ::dbus_connection_send_with_reply_and_block(conn, get_pid, -1, NULL);
868 ::dbus_message_unref(get_pid);
869 if (!got_pid) {
870 LOG(ERROR) << "Could not look up sender of RestartJob";
871 return DBUS_HANDLER_RESULT_HANDLED;
872 }
873 uint32 pid;
874 if (!::dbus_message_get_args(got_pid, NULL,
875 DBUS_TYPE_UINT32, &pid,
876 DBUS_TYPE_INVALID)) {
877 ::dbus_message_unref(got_pid);
878 LOG(ERROR) << "Could not extract pid of sender of RestartJob";
879 return DBUS_HANDLER_RESULT_HANDLED;
880 }
881 ::dbus_message_unref(got_pid);
882 if (!service->IsKnownChild(pid)) {
883 LOG(WARNING) << "Sender of RestartJob is no child of mine!";
884 return DBUS_HANDLER_RESULT_HANDLED;
885 }
886 }
887 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
888 }
889
811 void SessionManagerService::SetupHandlers() { 890 void SessionManagerService::SetupHandlers() {
812 // I have to ignore SIGUSR1, because Xorg sends it to this process when it's 891 // I have to ignore SIGUSR1, because Xorg sends it to this process when it's
813 // got no clients and is ready for new ones. If we don't ignore it, we die. 892 // got no clients and is ready for new ones. If we don't ignore it, we die.
814 struct sigaction action; 893 struct sigaction action;
815 memset(&action, 0, sizeof(action)); 894 memset(&action, 0, sizeof(action));
816 action.sa_handler = SIG_IGN; 895 action.sa_handler = SIG_IGN;
817 CHECK(sigaction(SIGUSR1, &action, NULL) == 0); 896 CHECK(sigaction(SIGUSR1, &action, NULL) == 0);
818 897
819 action.sa_handler = SessionManagerService::do_nothing; 898 action.sa_handler = SessionManagerService::do_nothing;
820 CHECK(sigaction(SIGALRM, &action, NULL) == 0); 899 CHECK(sigaction(SIGALRM, &action, NULL) == 0);
(...skipping 177 matching lines...) Expand 10 before | Expand all | Expand 10 after
998 1077
999 gboolean SessionManagerService::GetPropertyHelper(const std::string& name, 1078 gboolean SessionManagerService::GetPropertyHelper(const std::string& name,
1000 std::string* OUT_value, 1079 std::string* OUT_value,
1001 std::string* OUT_signature, 1080 std::string* OUT_signature,
1002 GError** error) { 1081 GError** error) {
1003 std::string encoded; 1082 std::string encoded;
1004 if (!store_->Get(name, OUT_value, &encoded)) { 1083 if (!store_->Get(name, OUT_value, &encoded)) {
1005 std::string error_string = 1084 std::string error_string =
1006 base::StringPrintf("The requested property %s is unknown.", 1085 base::StringPrintf("The requested property %s is unknown.",
1007 name.c_str()); 1086 name.c_str());
1008 LOG(INFO) << error_string;
1009 SetGError(error, 1087 SetGError(error,
1010 CHROMEOS_LOGIN_ERROR_UNKNOWN_PROPERTY, 1088 CHROMEOS_LOGIN_ERROR_UNKNOWN_PROPERTY,
1011 error_string.c_str()); 1089 error_string.c_str());
1012 return FALSE; 1090 return FALSE;
1013 } 1091 }
1014 if (!base::Base64Decode(encoded, OUT_signature)) { 1092 if (!base::Base64Decode(encoded, OUT_signature)) {
1015 SetGError(error, 1093 SetGError(error,
1016 CHROMEOS_LOGIN_ERROR_DECODE_FAIL, 1094 CHROMEOS_LOGIN_ERROR_DECODE_FAIL,
1017 "Signature could not be decoded."); 1095 "Signature could not be decoded.");
1018 return FALSE; 1096 return FALSE;
(...skipping 16 matching lines...) Expand all
1035 arg_list.push_back(args[i_arg]); 1113 arg_list.push_back(args[i_arg]);
1036 } 1114 }
1037 } 1115 }
1038 if (arg_list.size()) { 1116 if (arg_list.size()) {
1039 arg_lists.push_back(arg_list); 1117 arg_lists.push_back(arg_list);
1040 } 1118 }
1041 return arg_lists; 1119 return arg_lists;
1042 } 1120 }
1043 1121
1044 } // namespace login_manager 1122 } // namespace login_manager
OLDNEW
« no previous file with comments | « session_manager_service.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698