15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifndef DBUS_FILE_DESCRIPTOR_H_
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define DBUS_FILE_DESCRIPTOR_H_
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/basictypes.h"
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "dbus/dbus_export.h"
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace dbus {
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// FileDescriptor is a type used to encapsulate D-Bus file descriptors
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// and to follow the RAII idiom appropiate for use with message operations
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// where the descriptor might be easily leaked.  To guard against this the
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// descriptor is closed when an instance is destroyed if it is owned.
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Ownership is asserted only when PutValue is used and TakeValue can be
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// used to take ownership.
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// For example, in the following
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//  FileDescriptor fd;
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//  if (!reader->PopString(&name) ||
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//      !reader->PopFileDescriptor(&fd) ||
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//      !reader->PopUint32(&flags)) {
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// the descriptor in fd will be closed if the PopUint32 fails.  But
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//   writer.AppendFileDescriptor(dbus::FileDescriptor(1));
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// will not automatically close "1" because it is not owned.
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Descriptors must be validated before marshalling in a D-Bus message
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// or using them after unmarshalling.  We disallow descriptors to a
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// directory to reduce the security risks.  Splitting out validation
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// also allows the caller to do this work on the File thread to conform
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// with i/o restrictions.
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class CHROME_DBUS_EXPORT FileDescriptor {
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Permits initialization without a value for passing to
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // dbus::MessageReader::PopFileDescriptor to fill in and from int values.
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FileDescriptor() : value_(-1), owner_(false), valid_(false) {}
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  explicit FileDescriptor(int value) : value_(value), owner_(false),
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      valid_(false) {}
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual ~FileDescriptor();
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Retrieves value as an int without affecting ownership.
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int value() const;
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Retrieves whether or not the descriptor is ok to send/receive.
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int is_valid() const { return valid_; }
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Sets the value and assign ownership.
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void PutValue(int value) {
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    value_ = value;
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    owner_ = true;
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    valid_ = false;
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Takes the value and ownership.
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int TakeValue();
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Checks (and records) validity of the file descriptor.
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // We disallow directories to avoid potential sandbox escapes.
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Note this call must be made on a thread where file i/o is allowed.
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void CheckValidity();
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int value_;
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool owner_;
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool valid_;
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(FileDescriptor);
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace dbus
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif  // DBUS_FILE_DESCRIPTOR_H_
76