summaryrefslogtreecommitdiffstats
path: root/remoting/base
diff options
context:
space:
mode:
authoralexeypa@chromium.org <alexeypa@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-12-11 07:17:19 +0000
committeralexeypa@chromium.org <alexeypa@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-12-11 07:17:19 +0000
commit6383fb7ccbdb2a9888031eb8a81b06403bb5d1a6 (patch)
treeca082bfb6e6da0dc0c18a7d1c52fb02b632aafce /remoting/base
parent3c1adb8d65f34181408fa548503e9b7222bb2d74 (diff)
downloadchromium_src-6383fb7ccbdb2a9888031eb8a81b06403bb5d1a6.zip
chromium_src-6383fb7ccbdb2a9888031eb8a81b06403bb5d1a6.tar.gz
chromium_src-6383fb7ccbdb2a9888031eb8a81b06403bb5d1a6.tar.bz2
Launch the host under LocalService account at low integrity level with all privileges removed. It receives it's own window station and desktop only accessible by SYSTEM and logon SID the host process is running under. The security descriptor assigned to th eprocess gives access to SYSTEM and limited (query and terminate) access to built-in administrators group.
BUG=134694 Review URL: https://chromiumcodereview.appspot.com/11428172 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@172268 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'remoting/base')
-rw-r--r--remoting/base/typed_buffer.h98
-rw-r--r--remoting/base/typed_buffer_unittest.cc101
2 files changed, 199 insertions, 0 deletions
diff --git a/remoting/base/typed_buffer.h b/remoting/base/typed_buffer.h
new file mode 100644
index 0000000..c80f720
--- /dev/null
+++ b/remoting/base/typed_buffer.h
@@ -0,0 +1,98 @@
+// Copyright (c) 2012 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_BASE_TYPED_BUFFER_H_
+#define REMOTING_BASE_TYPED_BUFFER_H_
+
+#include <assert.h>
+
+#include <algorithm>
+
+#include "base/basictypes.h"
+#include "base/move.h"
+
+namespace remoting {
+
+// A scoper for a variable-length structure such as SID, SECURITY_DESCRIPTOR and
+// similar. These structures typically consist of a header followed by variable-
+// length data, so the size may not match sizeof(T). The class supports
+// move-only semantics and typed buffer getters.
+template <typename T>
+class TypedBuffer {
+ MOVE_ONLY_TYPE_FOR_CPP_03(TypedBuffer, RValue)
+
+ public:
+ TypedBuffer() : buffer_(NULL), length_(0) {
+ }
+
+ // Creates an instance of the object allocating a buffer of the given size.
+ explicit TypedBuffer(uint32 length) : buffer_(NULL), length_(length) {
+ if (length_ > 0)
+ buffer_ = reinterpret_cast<T*>(new uint8[length_]);
+ }
+
+ // Move constructor for C++03 move emulation of this type.
+ TypedBuffer(RValue rvalue) : buffer_(NULL), length_(0) {
+ TypedBuffer temp;
+ temp.Swap(*rvalue.object);
+ Swap(temp);
+ }
+
+ ~TypedBuffer() {
+ if (buffer_) {
+ delete[] reinterpret_cast<uint8*>(buffer_);
+ buffer_ = NULL;
+ }
+ }
+
+ // Move operator= for C++03 move emulation of this type.
+ TypedBuffer& operator=(RValue rvalue) {
+ TypedBuffer temp;
+ temp.Swap(*rvalue.object);
+ Swap(temp);
+ return *this;
+ }
+
+ // Accessors to get the owned buffer.
+ // operator* and operator-> will assert() if there is no current buffer.
+ T& operator*() const {
+ assert(buffer_ != NULL);
+ return *buffer_;
+ }
+ T* operator->() const {
+ assert(buffer_ != NULL);
+ return buffer_;
+ }
+ T* get() const { return buffer_; }
+
+ uint32 length() const { return length_; }
+
+ // Helper returning a pointer to the structure starting at a specified byte
+ // offset.
+ T* GetAtOffset(uint32 offset) {
+ return reinterpret_cast<T*>(reinterpret_cast<uint8*>(buffer_) + offset);
+ }
+
+ // Allow TypedBuffer<T> to be used in boolean expressions, but not
+ // implicitly convertible to a real bool (which is dangerous).
+ typedef T* TypedBuffer::*Testable;
+ operator Testable() const { return buffer_ ? &TypedBuffer::buffer_ : NULL; }
+
+ // Swap two buffers.
+ void Swap(TypedBuffer& other) {
+ std::swap(buffer_, other.buffer_);
+ std::swap(length_, other.length_);
+ }
+
+ private:
+ // Points to the owned buffer.
+ T* buffer_;
+
+ // Length of the owned buffer in bytes.
+ uint32 length_;
+};
+
+} // namespace remoting
+
+#endif // REMOTING_BASE_TYPED_BUFFER_H_
diff --git a/remoting/base/typed_buffer_unittest.cc b/remoting/base/typed_buffer_unittest.cc
new file mode 100644
index 0000000..0c036fb
--- /dev/null
+++ b/remoting/base/typed_buffer_unittest.cc
@@ -0,0 +1,101 @@
+// Copyright (c) 2012 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/base/typed_buffer.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace remoting {
+
+namespace {
+
+struct Data {
+ // A variable size vector.
+ int data[1];
+};
+
+} // namespace
+
+// Check that the default constructor does not allocate the buffer.
+TEST(TypedBufferTest, Empty) {
+ TypedBuffer<Data> buffer;
+ EXPECT_FALSE(buffer.get());
+ EXPECT_FALSE(buffer);
+ EXPECT_EQ(buffer.length(), 0u);
+}
+
+// Check that allocating zero-size structure does not allocate the buffer.
+TEST(TypedBufferTest, ZeroSize) {
+ TypedBuffer<Data> buffer(0);
+ EXPECT_FALSE(buffer.get());
+ EXPECT_FALSE(buffer);
+ EXPECT_EQ(buffer.length(), 0u);
+}
+
+// Test creation of a buffer and verify that the buffer accessors work.
+TEST(TypedBufferTest, Basic) {
+ TypedBuffer<Data> buffer(sizeof(int) * 10);
+ EXPECT_TRUE(buffer.get());
+ EXPECT_TRUE(buffer);
+ EXPECT_EQ(buffer.length(), sizeof(int) * 10);
+
+ // Make sure that operator*() syntax works.
+ (*buffer).data[9] = 0x12345678;
+
+ // Make sure that operator->() syntax works.
+ EXPECT_EQ(buffer->data[9], 0x12345678);
+}
+
+// Test passing ownership.
+TEST(TypedBufferTest, Pass) {
+ TypedBuffer<Data> left;
+ TypedBuffer<Data> right(sizeof(int));
+
+ EXPECT_FALSE(left.get());
+ EXPECT_EQ(left.length(), 0u);
+ EXPECT_TRUE(right.get());
+ EXPECT_EQ(right.length(), sizeof(int));
+
+ Data* raw_ptr = right.get();
+ left = right.Pass();
+
+ // Verify that passing ownership transfers both the buffer pointer and its
+ // length.
+ EXPECT_EQ(left.get(), raw_ptr);
+ EXPECT_EQ(left.length(), sizeof(int));
+
+ // Verify that the original object was cleared.
+ EXPECT_FALSE(right.get());
+ EXPECT_EQ(right.length(), 0u);
+}
+
+// Test swapping ownership.
+TEST(TypedBufferTest, Swap) {
+ TypedBuffer<Data> left(sizeof(int));
+ TypedBuffer<Data> right(sizeof(int) * 2);
+
+ EXPECT_TRUE(left.get());
+ EXPECT_EQ(left.length(), sizeof(int));
+ EXPECT_TRUE(right.get());
+ EXPECT_EQ(right.length(), sizeof(int) * 2);
+
+ Data* raw_left = left.get();
+ Data* raw_right = right.get();
+ left.Swap(right);
+
+ // Verify that swapping simply exchange contents of two objects.
+ // length.
+ EXPECT_EQ(left.get(), raw_right);
+ EXPECT_EQ(left.length(), sizeof(int) * 2);
+ EXPECT_EQ(right.get(), raw_left);
+ EXPECT_EQ(right.length(), sizeof(int));
+}
+
+TEST(TypedBufferTest, GetAtOffset) {
+ TypedBuffer<Data> buffer(sizeof(int) * 10);
+ EXPECT_EQ(buffer.get(), buffer.GetAtOffset(0));
+ EXPECT_EQ(reinterpret_cast<Data*>(&buffer->data[9]),
+ buffer.GetAtOffset(sizeof(int) * 9));
+}
+
+} // namespace remoting