attestation: Add a skeleton daemon and client
BUG=chromium:345099
TEST=See CL:188254
Change-Id: Icb9d12e410e8c3137278969aa314b39eb38afdf3
diff --git a/attestation.gyp b/attestation.gyp
new file mode 100644
index 0000000..5926a82
--- /dev/null
+++ b/attestation.gyp
@@ -0,0 +1,68 @@
+# Copyright 2014 The Chromium OS Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+# export BOARD=wolf
+# export AR=`portageq-$BOARD envvar AR`
+# export CC=`portageq-$BOARD envvar CC`
+# export CXX=`portageq-$BOARD envvar CXX`
+# gyp -fmake --depth=. -DUSE_test=0 -Dplatform_root=$HOME/trunk/src/platform -Dsysroot=/build/$BOARD --include=../../platform/common-mk/common.gypi -Dpkg-config=pkg-config-$BOARD attestation.gyp
+# make
+
+{
+ 'variables': {
+ 'libbase_ver': 242728,
+ },
+ 'target_defaults': {
+ 'dependencies': [
+ '<(platform_root)/libchromeos/libchromeos-<(libbase_ver).gyp:*',
+ '<(platform_root)/system_api/system_api.gyp:*',
+ ],
+ 'variables': {
+ 'deps': [ # This is a list of pkg-config dependencies
+ 'libchrome-<(libbase_ver)',
+ ]
+ },
+ 'link_settings': {
+ 'libraries': [
+ '-lprotobuf',
+ ],
+ },
+ 'cflags_cc': [ '-std=gnu++11' ],
+ },
+ 'targets': [
+ {
+ 'target_name': 'attestation',
+ 'type': 'executable',
+ 'sources': [
+ 'client/main.cc',
+ ],
+ 'dependencies': [
+ 'attestation_proto'
+ ]
+ },
+ {
+ 'target_name': 'attestationd',
+ 'type': 'executable',
+ 'sources': [
+ 'server/main.cc',
+ 'server/attestation_service.cc'
+ ],
+ 'dependencies': [
+ 'attestation_proto'
+ ],
+ },
+ {
+ 'target_name': 'attestation_proto',
+ 'type': 'static_library',
+ 'variables': {
+ 'proto_in_dir': 'common',
+ 'proto_out_dir': 'include/attestation/common',
+ },
+ 'sources': [
+ '<(proto_in_dir)/dbus_interface.proto'
+ ],
+ 'includes': ['../common-mk/protoc.gypi'],
+ },
+ ],
+}
diff --git a/client/main.cc b/client/main.cc
new file mode 100644
index 0000000..d0411d6
--- /dev/null
+++ b/client/main.cc
@@ -0,0 +1,35 @@
+// Copyright 2014 The Chromium OS 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 <base/memory/ref_counted.h>
+#include <dbus/bus.h>
+#include <dbus/message.h>
+#include <dbus/object_proxy.h>
+
+#include "attestation/common/dbus_interface.h"
+#include "attestation/common/dbus_interface.pb.h"
+
+int main(int argc, char* argv[]) {
+ dbus::Bus::Options options;
+ options.bus_type = dbus::Bus::SYSTEM;
+ scoped_refptr<dbus::Bus> bus = new dbus::Bus(options);
+ dbus::ObjectProxy* object = bus->GetObjectProxy(
+ attestation::kAttestationServiceName,
+ dbus::ObjectPath(attestation::kAttestationServicePath));
+ dbus::MethodCall method_call(
+ attestation::kAttestationInterface,
+ attestation::kStatsMethod);
+ scoped_ptr<dbus::Response> response(
+ object->CallMethodAndBlock(&method_call,
+ dbus::ObjectProxy::TIMEOUT_USE_DEFAULT));
+ attestation::StatsResponse stats;
+ dbus::MessageReader reader(response.get());
+ reader.PopArrayOfBytesAsProto(&stats);
+
+ printf("Attestation has been up for %u seconds.\n", stats.uptime());
+
+ bus->ShutdownAndBlock();
+
+ return 0;
+}
diff --git a/common/dbus_interface.h b/common/dbus_interface.h
new file mode 100644
index 0000000..f45ce32
--- /dev/null
+++ b/common/dbus_interface.h
@@ -0,0 +1,20 @@
+// Copyright 2014 The Chromium OS 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 ATTESTATION_COMMON_DBUS_INTERFACE_H
+#define ATTESTATION_COMMON_DBUS_INTERFACE_H
+
+namespace attestation {
+
+// TODO(namnguyen): Move to chromeos/system_api once we're ready.
+constexpr char kAttestationInterface[] = "org.chromium.Attestation";
+constexpr char kAttestationServicePath[] = "/org/chromium/Attestation";
+constexpr char kAttestationServiceName[] = "org.chromium.Attestation";
+
+// Methods exported by attestation.
+constexpr char kStatsMethod[] = "GetStats";
+
+}; // namespace attestation
+
+#endif // ATTESTATION_COMMON_DBUS_INTERFACE_H
diff --git a/common/dbus_interface.proto b/common/dbus_interface.proto
new file mode 100644
index 0000000..59397ea
--- /dev/null
+++ b/common/dbus_interface.proto
@@ -0,0 +1,5 @@
+package attestation;
+
+message StatsResponse {
+ required int32 uptime = 1;
+}
diff --git a/server/attestation_service.cc b/server/attestation_service.cc
new file mode 100644
index 0000000..2891fe1
--- /dev/null
+++ b/server/attestation_service.cc
@@ -0,0 +1,82 @@
+// Copyright 2014 The Chromium OS 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 "attestation_service.h"
+
+#include <string>
+
+#include <base/bind.h>
+#include <base/time/time.h>
+
+#include "attestation/common/dbus_interface.pb.h"
+
+namespace attestation {
+
+namespace {
+
+// Passes |method_call| to |handler| and passes the response to
+// |response_sender|. If |handler| returns NULL, an empty response is created
+// and sent.
+static void HandleSynchronousDBusMethodCall(
+ const DBusMethodCallHandler& handler,
+ dbus::MethodCall* method_call,
+ dbus::ExportedObject::ResponseSender response_sender) {
+ ResponsePtr response = handler.Run(method_call);
+ if (!response) {
+ response = dbus::Response::FromMethodCall(method_call);
+ }
+
+ response_sender.Run(response.Pass());
+}
+
+} // namespace
+
+AttestationService::AttestationService()
+ : start_time_(base::Time()),
+ bus_(nullptr),
+ attestation_dbus_object_(nullptr) {}
+
+AttestationService::~AttestationService() {}
+
+void AttestationService::Init() {
+ dbus::Bus::Options options;
+ options.bus_type = dbus::Bus::SYSTEM;
+ bus_ = new dbus::Bus(options);
+ CHECK(bus_->Connect());
+
+ attestation_dbus_object_ = bus_->GetExportedObject(
+ dbus::ObjectPath(kAttestationServicePath));
+ CHECK(attestation_dbus_object_);
+
+ ExportDBusMethod(kStatsMethod,
+ base::Bind(&AttestationService::HandleStatsMethod,
+ base::Unretained(this)));
+
+ CHECK(bus_->RequestOwnershipAndBlock(kAttestationServiceName,
+ dbus::Bus::REQUIRE_PRIMARY))
+ << "Unable to take ownership of " << kAttestationServiceName;
+
+ start_time_ = base::Time::Now();
+}
+
+void AttestationService::ExportDBusMethod(
+ const std::string& method_name,
+ const DBusMethodCallHandler& handler) {
+ CHECK(attestation_dbus_object_->ExportMethodAndBlock(
+ kAttestationInterface, method_name,
+ base::Bind(&HandleSynchronousDBusMethodCall, handler)));
+}
+
+ResponsePtr AttestationService::HandleStatsMethod(
+ dbus::MethodCall* method_call) {
+ LOG(INFO) << "Received call to stats method.";
+ StatsResponse stats;
+ stats.set_uptime((base::Time::Now() - start_time_).InSeconds());
+ ResponsePtr response = dbus::Response::FromMethodCall(method_call);
+ dbus::MessageWriter writer(response.get());
+ writer.AppendProtoAsArrayOfBytes(stats);
+ return response.Pass();
+}
+
+} // namespace attestation
diff --git a/server/attestation_service.h b/server/attestation_service.h
new file mode 100644
index 0000000..a352f32
--- /dev/null
+++ b/server/attestation_service.h
@@ -0,0 +1,54 @@
+// Copyright 2014 The Chromium OS 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 ATTESTATION_SERVER_SERVICE_H
+#define ATTESTATION_SERVER_SERVICE_H
+
+#include <string>
+
+#include <base/callback.h>
+#include <base/memory/scoped_ptr.h>
+#include <dbus/bus.h>
+#include <dbus/exported_object.h>
+#include <dbus/message.h>
+
+#include "attestation/common/dbus_interface.h"
+
+namespace attestation {
+
+class AttestationService;
+
+typedef scoped_ptr<dbus::Response> ResponsePtr;
+// Pointer to a member function for handling D-Bus method calls. If an empty
+// scoped_ptr is returned, an empty (but successful) response will be sent.
+typedef base::Callback<ResponsePtr (dbus::MethodCall*)> DBusMethodCallHandler;
+
+// Main class within the attestation daemon that ties other classes together.
+class AttestationService {
+ public:
+ AttestationService();
+ virtual ~AttestationService();
+
+ // Connects to D-Bus system bus and exports methods.
+ void Init();
+
+ private:
+ // Exports |method_name| and uses |handler| to handle calls.
+ void ExportDBusMethod(const std::string& method_name,
+ const DBusMethodCallHandler& handler);
+
+ // Callbacks for handling D-Bus signals and method calls.
+ ResponsePtr HandleStatsMethod(dbus::MethodCall* method_call);
+
+ base::Time start_time_;
+ scoped_refptr<dbus::Bus> bus_;
+ // This is owned by bus_.
+ dbus::ExportedObject* attestation_dbus_object_;
+
+ DISALLOW_COPY_AND_ASSIGN(AttestationService);
+};
+
+} // namespace attestation
+
+#endif // ATTESTATION_SERVER_SERVICE_H
diff --git a/server/attestationd.conf b/server/attestationd.conf
new file mode 100644
index 0000000..1d72c0d
--- /dev/null
+++ b/server/attestationd.conf
@@ -0,0 +1,12 @@
+# Copyright 2014 The Chromium OS Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+description "Chromium OS device attestation service."
+author "[email protected]"
+
+start on starting system-services
+stop on stopping system-services
+respawn
+
+exec attestationd
diff --git a/server/main.cc b/server/main.cc
new file mode 100644
index 0000000..ccea698
--- /dev/null
+++ b/server/main.cc
@@ -0,0 +1,29 @@
+// Copyright 2014 The Chromium OS 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 <string>
+
+#include <base/at_exit.h>
+#include <base/command_line.h>
+#include <base/message_loop/message_loop.h>
+#include <base/strings/string_util.h>
+#include <base/strings/stringprintf.h>
+#include <chromeos/syslog_logging.h>
+
+#include "attestation_service.h"
+
+int main(int argc, char* argv[]) {
+ CommandLine::Init(argc, argv);
+
+ chromeos::InitLog(chromeos::kLogToSyslog | chromeos::kLogToStderr);
+
+ base::AtExitManager at_exit_manager; // This is for the message loop.
+ base::MessageLoopForIO message_loop;
+
+ attestation::AttestationService service;
+ service.Init();
+
+ message_loop.Run();
+ return 0;
+}
diff --git a/server/org.chromium.Attestation.conf b/server/org.chromium.Attestation.conf
new file mode 100644
index 0000000..d429014
--- /dev/null
+++ b/server/org.chromium.Attestation.conf
@@ -0,0 +1,16 @@
+<!DOCTYPE busconfig PUBLIC
+ "-//freedesktop//DTD D-BUS Bus Configuration 1.0//EN"
+ "http://www.freedesktop.org/standards/dbus/1.0/busconfig.dtd">
+<busconfig>
+ <policy user="root">
+ <allow own="org.chromium.Attestation" />
+ <allow send_destination="org.chromium.Attestation" />
+ </policy>
+
+ <policy context="default">
+ <allow send_destination="org.chromium.Attestation" />
+ <!-- introspection denied -->
+ <deny send_destination="org.chromium.Attestation"
+ send_interface="org.freedesktop.DBus.Introspectable" />
+ </policy>
+</busconfig>