<commit_before>#include <boost/filesystem.hpp>
#include <boost/program_options.hpp>
#include <iostream>
#include <string>
#include <vector>

#include "config/config.h"
#include "logging/logging.h"
#include "storage/invstorage.h"

namespace po = boost::program_options;

int main(int argc, char **argv) {
  po::options_description desc("aktualizr_info command line options");
  // clang-format off
  desc.add_options()
    ("help,h", "print usage")
    ("config,c", po::value<std::vector<boost::filesystem::path> >()->composing(), "configuration file or directory")
    ("tls-creds",  "Outputs TLS credentials")
    ("ecu-keys",  "Outputs UPTANE keys")
    ("images-root",  "Outputs root.json from images repo")
    ("images-target",  "Outputs targets.json from images repo")
    ("director-root",  "Outputs root.json from director repo")
    ("director-target",  "Outputs targets.json from director repo");
  // clang-format on

  try {
    logger_init();
    logger_set_threshold(boost::log::trivial::error);
    po::variables_map vm;
    po::basic_parsed_options<char> parsed_options = po::command_line_parser(argc, argv).options(desc).run();
    po::store(parsed_options, vm);
    po::notify(vm);
    if (vm.count("help") != 0) {
      std::cout << desc << '\n';
      exit(EXIT_SUCCESS);
    }

    std::vector<boost::filesystem::path> sota_config_files;
    if (vm.count("config") > 0) {
      sota_config_files = vm["config"].as<std::vector<boost::filesystem::path>>();
    }
    Config config(sota_config_files);

    std::shared_ptr<INvStorage> storage = INvStorage::newStorage(config.storage);
    std::cout << "Storage backend: " << ((storage->type() == kFileSystem) ? "Filesystem" : "Sqlite") << std::endl;

    Uptane::MetaPack pack;

    bool has_metadata = storage->loadMetadata(&pack);

    std::string device_id;
    if (!storage->loadDeviceId(&device_id)) {
      std::cout << "Couldn't load device ID" << std::endl;
    } else {
      std::cout << "Device ID: " << device_id << std::endl;
    }

    std::vector<std::pair<std::string, std::string>> serials;
    if (!storage->loadEcuSerials(&serials)) {
      std::cout << "Couldn't load ECU serials" << std::endl;
    } else if (serials.size() == 0) {
      std::cout << "Primary serial is not found" << std::endl;
    } else {
      std::cout << "Primary ecu serial ID: " << serials[0].first << std::endl;
      std::cout << "Primary ecu hardware ID: " << serials[0].second << std::endl;
    }
    if (serials.size() > 1) {
      auto it = serials.begin() + 1;
      std::cout << "Secondaries:\n";
      int secondary_number = 1;
      for (; it != serials.end(); ++it) {
        std::cout << secondary_number++ << ") serial ID: " << it->first << std::endl;
        std::cout << "   hardware ID: " << it->second << std::endl;
      }
    }

    std::vector<MisconfiguredEcu> misconfigured_ecus;
    storage->loadMisconfiguredEcus(&misconfigured_ecus);
    if (misconfigured_ecus.size() != 0u) {
      std::cout << "Removed or not registered ecus:" << std::endl;
      std::vector<MisconfiguredEcu>::const_iterator it;
      for (it = misconfigured_ecus.begin(); it != misconfigured_ecus.end(); ++it) {
        std::cout << "   '" << it->serial << "' with hardware_id '" << it->hardware_id << "' "
                  << (it->state == kOld ? "has been removed from config" : "not registered yet") << std::endl;
      }
    }

    std::cout << "Provisioned on server: " << (storage->loadEcuRegistered() ? "yes" : "no") << std::endl;
    std::cout << "Fetched metadata: " << (has_metadata ? "yes" : "no") << std::endl;

    if (has_metadata) {
      if (vm.count("images-root") != 0u) {
        std::cout << "image root.json content:" << std::endl;
        std::cout << pack.image_root.toJson();
      }

      if (vm.count("images-target") != 0u) {
        std::cout << "image targets.json content:" << std::endl;
        std::cout << pack.image_targets.toJson();
      }

      if (vm.count("director-root") != 0u) {
        std::cout << "director root.json content:" << std::endl;
        std::cout << pack.director_root.toJson();
      }

      if (vm.count("director-target") != 0u) {
        std::cout << "director targets.json content:" << std::endl;
        std::cout << pack.director_targets.toJson();
      }
    }

    if (vm.count("tls-creds") != 0u) {
      std::string ca;
      std::string cert;
      std::string pkey;

      storage->loadTlsCreds(&ca, &cert, &pkey);
      std::cout << "Root CA certificate:" << std::endl << ca << std::endl;
      std::cout << "Client certificate:" << std::endl << cert << std::endl;
      std::cout << "Client private key:" << std::endl << pkey << std::endl;
    }

    if (vm.count("ecu-keys") != 0u) {
      std::string priv;
      std::string pub;

      storage->loadPrimaryKeys(&pub, &priv);
      std::cout << "Public key:" << std::endl << pub << std::endl;
      std::cout << "Private key:" << std::endl << priv << std::endl;
    }

  } catch (const po::error &o) {
    std::cout << o.what() << std::endl;
    std::cout << desc;
    return EXIT_FAILURE;
  }
}
// vim: set tabstop=2 shiftwidth=2 expandtab:
<commit_msg>Configure aktualizr-info like aktualizr<commit_after>#include <boost/filesystem.hpp>
#include <boost/program_options.hpp>
#include <iostream>
#include <string>
#include <vector>

#include "config/config.h"
#include "logging/logging.h"
#include "storage/invstorage.h"

namespace po = boost::program_options;

int main(int argc, char **argv) {
  po::options_description desc("aktualizr_info command line options");
  // clang-format off
  desc.add_options()
    ("help,h", "print usage")
    ("config,c", po::value<std::vector<boost::filesystem::path> >()->composing(), "configuration file or directory")
    ("tls-creds",  "Outputs TLS credentials")
    ("ecu-keys",  "Outputs UPTANE keys")
    ("images-root",  "Outputs root.json from images repo")
    ("images-target",  "Outputs targets.json from images repo")
    ("director-root",  "Outputs root.json from director repo")
    ("director-target",  "Outputs targets.json from director repo");
  // clang-format on

  try {
    logger_init();
    logger_set_threshold(boost::log::trivial::error);
    po::variables_map vm;
    po::basic_parsed_options<char> parsed_options = po::command_line_parser(argc, argv).options(desc).run();
    po::store(parsed_options, vm);
    po::notify(vm);
    if (vm.count("help") != 0) {
      std::cout << desc << '\n';
      exit(EXIT_SUCCESS);
    }

    Config config(vm);

    std::shared_ptr<INvStorage> storage = INvStorage::newStorage(config.storage);
    std::cout << "Storage backend: " << ((storage->type() == kFileSystem) ? "Filesystem" : "Sqlite") << std::endl;

    Uptane::MetaPack pack;

    bool has_metadata = storage->loadMetadata(&pack);

    std::string device_id;
    if (!storage->loadDeviceId(&device_id)) {
      std::cout << "Couldn't load device ID" << std::endl;
    } else {
      std::cout << "Device ID: " << device_id << std::endl;
    }

    std::vector<std::pair<std::string, std::string>> serials;
    if (!storage->loadEcuSerials(&serials)) {
      std::cout << "Couldn't load ECU serials" << std::endl;
    } else if (serials.size() == 0) {
      std::cout << "Primary serial is not found" << std::endl;
    } else {
      std::cout << "Primary ecu serial ID: " << serials[0].first << std::endl;
      std::cout << "Primary ecu hardware ID: " << serials[0].second << std::endl;
    }
    if (serials.size() > 1) {
      auto it = serials.begin() + 1;
      std::cout << "Secondaries:\n";
      int secondary_number = 1;
      for (; it != serials.end(); ++it) {
        std::cout << secondary_number++ << ") serial ID: " << it->first << std::endl;
        std::cout << "   hardware ID: " << it->second << std::endl;
      }
    }

    std::vector<MisconfiguredEcu> misconfigured_ecus;
    storage->loadMisconfiguredEcus(&misconfigured_ecus);
    if (misconfigured_ecus.size() != 0u) {
      std::cout << "Removed or not registered ecus:" << std::endl;
      std::vector<MisconfiguredEcu>::const_iterator it;
      for (it = misconfigured_ecus.begin(); it != misconfigured_ecus.end(); ++it) {
        std::cout << "   '" << it->serial << "' with hardware_id '" << it->hardware_id << "' "
                  << (it->state == kOld ? "has been removed from config" : "not registered yet") << std::endl;
      }
    }

    std::cout << "Provisioned on server: " << (storage->loadEcuRegistered() ? "yes" : "no") << std::endl;
    std::cout << "Fetched metadata: " << (has_metadata ? "yes" : "no") << std::endl;

    if (has_metadata) {
      if (vm.count("images-root") != 0u) {
        std::cout << "image root.json content:" << std::endl;
        std::cout << pack.image_root.toJson();
      }

      if (vm.count("images-target") != 0u) {
        std::cout << "image targets.json content:" << std::endl;
        std::cout << pack.image_targets.toJson();
      }

      if (vm.count("director-root") != 0u) {
        std::cout << "director root.json content:" << std::endl;
        std::cout << pack.director_root.toJson();
      }

      if (vm.count("director-target") != 0u) {
        std::cout << "director targets.json content:" << std::endl;
        std::cout << pack.director_targets.toJson();
      }
    }

    if (vm.count("tls-creds") != 0u) {
      std::string ca;
      std::string cert;
      std::string pkey;

      storage->loadTlsCreds(&ca, &cert, &pkey);
      std::cout << "Root CA certificate:" << std::endl << ca << std::endl;
      std::cout << "Client certificate:" << std::endl << cert << std::endl;
      std::cout << "Client private key:" << std::endl << pkey << std::endl;
    }

    if (vm.count("ecu-keys") != 0u) {
      std::string priv;
      std::string pub;

      storage->loadPrimaryKeys(&pub, &priv);
      std::cout << "Public key:" << std::endl << pub << std::endl;
      std::cout << "Private key:" << std::endl << priv << std::endl;
    }

  } catch (const po::error &o) {
    std::cout << o.what() << std::endl;
    std::cout << desc;
    return EXIT_FAILURE;
  }
}
// vim: set tabstop=2 shiftwidth=2 expandtab:
<|endoftext|>


<commit_before>// Copyright (c) 2012 Intel Corp
// Copyright (c) 2012 The Chromium Authors
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
//  in the Software without restriction, including without limitation the rights
//  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell co
// pies of the Software, and to permit persons to whom the Software is furnished
//  to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in al
// l copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IM
// PLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNES
// S FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS
//  OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WH
// ETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
//  CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

#include "content/nw/src/api/dispatcher_host.h"

#include "base/logging.h"
#include "base/threading/thread_restrictions.h"
#include "base/values.h"
#include "content/browser/child_process_security_policy_impl.h"
#include "content/browser/web_contents/web_contents_impl.h"
#include "content/nw/src/api/api_messages.h"
#include "content/nw/src/api/app/app.h"
#include "content/nw/src/api/base/base.h"
#include "content/nw/src/api/clipboard/clipboard.h"
#include "content/nw/src/api/menu/menu.h"
#include "content/nw/src/api/menuitem/menuitem.h"
#include "content/nw/src/api/shell/shell.h"
#include "content/nw/src/api/tray/tray.h"
#include "content/nw/src/api/window/window.h"
#include "content/nw/src/common/shell_switches.h"
#include "content/nw/src/shell_browser_context.h"
#include "content/nw/src/nw_shell.h"
#include "content/public/browser/render_process_host.h"

using content::WebContents;
using content::ShellBrowserContext;

namespace api {

DispatcherHost::DispatcherHost(content::RenderViewHost* render_view_host)
    : content::RenderViewHostObserver(render_view_host) {
}

DispatcherHost::~DispatcherHost() {
}

Base* DispatcherHost::GetApiObject(int id) {
  return objects_registry_.Lookup(id);
}

void DispatcherHost::SendEvent(Base* object,
                               const std::string& event,
                               const base::ListValue& arguments) {
  Send(new ShellViewMsg_Object_On_Event(
       routing_id(), object->id(), event, arguments));
}

bool DispatcherHost::Send(IPC::Message* message) {
  return content::RenderViewHostObserver::Send(message);
}

bool DispatcherHost::OnMessageReceived(const IPC::Message& message) {
  bool handled = true;
  base::ThreadRestrictions::ScopedAllowIO allow_io;
  IPC_BEGIN_MESSAGE_MAP(DispatcherHost, message)
    IPC_MESSAGE_HANDLER(ShellViewHostMsg_Allocate_Object, OnAllocateObject)
    IPC_MESSAGE_HANDLER(ShellViewHostMsg_Deallocate_Object, OnDeallocateObject)
    IPC_MESSAGE_HANDLER(ShellViewHostMsg_Call_Object_Method, OnCallObjectMethod)
    IPC_MESSAGE_HANDLER(ShellViewHostMsg_Call_Object_Method_Sync,
                        OnCallObjectMethodSync)
    IPC_MESSAGE_HANDLER(ShellViewHostMsg_Call_Static_Method, OnCallStaticMethod)
    IPC_MESSAGE_HANDLER(ShellViewHostMsg_Call_Static_Method_Sync,
                        OnCallStaticMethodSync)
    IPC_MESSAGE_HANDLER(ShellViewHostMsg_UncaughtException,
                        OnUncaughtException);
    IPC_MESSAGE_HANDLER(ShellViewHostMsg_GetShellId, OnGetShellId);
    IPC_MESSAGE_HANDLER(ShellViewHostMsg_CreateShell, OnCreateShell);
    IPC_MESSAGE_HANDLER(ShellViewHostMsg_GrantUniversalPermissions, OnGrantUniversalPermissions);
    IPC_MESSAGE_UNHANDLED(handled = false)
  IPC_END_MESSAGE_MAP()

  return handled;
}

void DispatcherHost::OnAllocateObject(int object_id,
                                      const std::string& type,
                                      const base::DictionaryValue& option) {
  DVLOG(1) << "OnAllocateObject: object_id:" << object_id
             << " type:" << type
             << " option:" << option;

  if (type == "Menu") {
    objects_registry_.AddWithID(new Menu(object_id, this, option), object_id);
  } else if (type == "MenuItem") {
    objects_registry_.AddWithID(
        new MenuItem(object_id, this, option), object_id);
  } else if (type == "Tray") {
    objects_registry_.AddWithID(new Tray(object_id, this, option), object_id);
  } else if (type == "Clipboard") {
    objects_registry_.AddWithID(
        new Clipboard(object_id, this, option), object_id);
  } else if (type == "Window") {
    objects_registry_.AddWithID(new Window(object_id, this, option), object_id);
  } else {
    LOG(ERROR) << "Allocate an object of unknown type: " << type;
    objects_registry_.AddWithID(new Base(object_id, this, option), object_id);
  }
}

void DispatcherHost::OnDeallocateObject(int object_id) {
  DLOG(INFO) << "OnDeallocateObject: object_id:" << object_id;
  objects_registry_.Remove(object_id);
}

void DispatcherHost::OnCallObjectMethod(
    int object_id,
    const std::string& type,
    const std::string& method,
    const base::ListValue& arguments) {
  DLOG(INFO) << "OnCallObjectMethod: object_id:" << object_id
             << " type:" << type
             << " method:" << method
             << " arguments:" << arguments;

  Base* object = GetApiObject(object_id);
  CHECK(object) << "Unknown object: " << object_id
             << " type:" << type
             << " method:" << method
             << " arguments:" << arguments;
  if (object)
    object->Call(method, arguments);
}

void DispatcherHost::OnCallObjectMethodSync(
    int object_id,
    const std::string& type,
    const std::string& method,
    const base::ListValue& arguments,
    base::ListValue* result) {
  DLOG(INFO) << "OnCallObjectMethodSync: object_id:" << object_id
             << " type:" << type
             << " method:" << method
             << " arguments:" << arguments;

  Base* object = GetApiObject(object_id);
  CHECK(object) << "Unknown object: " << object_id
             << " type:" << type
             << " method:" << method
             << " arguments:" << arguments;
  if (object)
    object->CallSync(method, arguments, result);
}

void DispatcherHost::OnCallStaticMethod(
    const std::string& type,
    const std::string& method,
    const base::ListValue& arguments) {
  DLOG(INFO) << "OnCallStaticMethod: "
             << " type:" << type
             << " method:" << method
             << " arguments:" << arguments;

  if (type == "Shell") {
    api::Shell::Call(method, arguments);
    return;
  } else if (type == "App") {
    api::App::Call(method, arguments);
    return;
  }

  NOTREACHED() << "Calling unknown method " << method << " of class " << type;
}

void DispatcherHost::OnCallStaticMethodSync(
    const std::string& type,
    const std::string& method,
    const base::ListValue& arguments,
    base::ListValue* result) {
  DLOG(INFO) << "OnCallStaticMethodSync: "
             << " type:" << type
             << " method:" << method
             << " arguments:" << arguments;

  if (type == "App") {
    content::Shell* shell =
        content::Shell::FromRenderViewHost(render_view_host());
    api::App::Call(shell, method, arguments, result);
    return;
  }

  NOTREACHED() << "Calling unknown method " << method << " of class " << type;
}

void DispatcherHost::OnUncaughtException(const std::string& err) {
  content::Shell* shell =
      content::Shell::FromRenderViewHost(render_view_host());
  shell->PrintCriticalError("Uncaught node.js Error", err);
}

void DispatcherHost::OnGetShellId(int* id) {
  content::Shell* shell =
      content::Shell::FromRenderViewHost(render_view_host());
  *id = shell->id();
}

void DispatcherHost::OnCreateShell(const std::string& url,
                                   const base::DictionaryValue& manifest,
                                   int* routing_id) {
  WebContents* base_web_contents =
      content::Shell::FromRenderViewHost(render_view_host())->web_contents();
  ShellBrowserContext* browser_context =
      static_cast<ShellBrowserContext*>(base_web_contents->GetBrowserContext());
  scoped_ptr<base::DictionaryValue> new_manifest(manifest.DeepCopy());
  bool new_renderer = false;
  if (new_manifest->GetBoolean(switches::kmNewInstance,
                               &new_renderer) && new_renderer)
    browser_context->set_pinning_renderer(false);

  WebContents::CreateParams create_params(browser_context,
                                          new_renderer ? NULL : base_web_contents->GetSiteInstance());

  WebContents* web_contents = content::WebContentsImpl::CreateWithOpener(
      create_params,
      static_cast<content::WebContentsImpl*>(base_web_contents));
  content::Shell::Create(base_web_contents,
                         GURL(url),
                         new_manifest.get(),
                         web_contents);

  if (new_renderer)
    browser_context->set_pinning_renderer(true);

  *routing_id = web_contents->GetRoutingID();
}

void DispatcherHost::OnGrantUniversalPermissions(int *ret) {
  content::Shell* shell =
      content::Shell::FromRenderViewHost(render_view_host());
  if (shell->nodejs()) {
    content::ChildProcessSecurityPolicy::GetInstance()->GrantUniversalAccess(shell->web_contents()->GetRenderProcessHost()->GetID());
    *ret = 1;
  }else
    *ret = 0;
}

}  // namespace api
<commit_msg>Allow wait in nw method handlers<commit_after>// Copyright (c) 2012 Intel Corp
// Copyright (c) 2012 The Chromium Authors
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
//  in the Software without restriction, including without limitation the rights
//  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell co
// pies of the Software, and to permit persons to whom the Software is furnished
//  to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in al
// l copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IM
// PLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNES
// S FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS
//  OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WH
// ETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
//  CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

#include "content/nw/src/api/dispatcher_host.h"

#include "base/logging.h"
#include "base/threading/thread_restrictions.h"
#include "base/values.h"
#include "content/browser/child_process_security_policy_impl.h"
#include "content/browser/web_contents/web_contents_impl.h"
#include "content/nw/src/api/api_messages.h"
#include "content/nw/src/api/app/app.h"
#include "content/nw/src/api/base/base.h"
#include "content/nw/src/api/clipboard/clipboard.h"
#include "content/nw/src/api/menu/menu.h"
#include "content/nw/src/api/menuitem/menuitem.h"
#include "content/nw/src/api/shell/shell.h"
#include "content/nw/src/api/tray/tray.h"
#include "content/nw/src/api/window/window.h"
#include "content/nw/src/common/shell_switches.h"
#include "content/nw/src/shell_browser_context.h"
#include "content/nw/src/nw_shell.h"
#include "content/public/browser/render_process_host.h"

using content::WebContents;
using content::ShellBrowserContext;

namespace api {

DispatcherHost::DispatcherHost(content::RenderViewHost* render_view_host)
    : content::RenderViewHostObserver(render_view_host) {
}

DispatcherHost::~DispatcherHost() {
}

Base* DispatcherHost::GetApiObject(int id) {
  return objects_registry_.Lookup(id);
}

void DispatcherHost::SendEvent(Base* object,
                               const std::string& event,
                               const base::ListValue& arguments) {
  Send(new ShellViewMsg_Object_On_Event(
       routing_id(), object->id(), event, arguments));
}

bool DispatcherHost::Send(IPC::Message* message) {
  return content::RenderViewHostObserver::Send(message);
}

bool DispatcherHost::OnMessageReceived(const IPC::Message& message) {
  bool handled = true;
  base::ThreadRestrictions::ScopedAllowIO allow_io;
  base::ThreadRestrictions::ScopedAllowWait allow_wait;
  IPC_BEGIN_MESSAGE_MAP(DispatcherHost, message)
    IPC_MESSAGE_HANDLER(ShellViewHostMsg_Allocate_Object, OnAllocateObject)
    IPC_MESSAGE_HANDLER(ShellViewHostMsg_Deallocate_Object, OnDeallocateObject)
    IPC_MESSAGE_HANDLER(ShellViewHostMsg_Call_Object_Method, OnCallObjectMethod)
    IPC_MESSAGE_HANDLER(ShellViewHostMsg_Call_Object_Method_Sync,
                        OnCallObjectMethodSync)
    IPC_MESSAGE_HANDLER(ShellViewHostMsg_Call_Static_Method, OnCallStaticMethod)
    IPC_MESSAGE_HANDLER(ShellViewHostMsg_Call_Static_Method_Sync,
                        OnCallStaticMethodSync)
    IPC_MESSAGE_HANDLER(ShellViewHostMsg_UncaughtException,
                        OnUncaughtException);
    IPC_MESSAGE_HANDLER(ShellViewHostMsg_GetShellId, OnGetShellId);
    IPC_MESSAGE_HANDLER(ShellViewHostMsg_CreateShell, OnCreateShell);
    IPC_MESSAGE_HANDLER(ShellViewHostMsg_GrantUniversalPermissions, OnGrantUniversalPermissions);
    IPC_MESSAGE_UNHANDLED(handled = false)
  IPC_END_MESSAGE_MAP()

  return handled;
}

void DispatcherHost::OnAllocateObject(int object_id,
                                      const std::string& type,
                                      const base::DictionaryValue& option) {
  DVLOG(1) << "OnAllocateObject: object_id:" << object_id
             << " type:" << type
             << " option:" << option;

  if (type == "Menu") {
    objects_registry_.AddWithID(new Menu(object_id, this, option), object_id);
  } else if (type == "MenuItem") {
    objects_registry_.AddWithID(
        new MenuItem(object_id, this, option), object_id);
  } else if (type == "Tray") {
    objects_registry_.AddWithID(new Tray(object_id, this, option), object_id);
  } else if (type == "Clipboard") {
    objects_registry_.AddWithID(
        new Clipboard(object_id, this, option), object_id);
  } else if (type == "Window") {
    objects_registry_.AddWithID(new Window(object_id, this, option), object_id);
  } else {
    LOG(ERROR) << "Allocate an object of unknown type: " << type;
    objects_registry_.AddWithID(new Base(object_id, this, option), object_id);
  }
}

void DispatcherHost::OnDeallocateObject(int object_id) {
  DLOG(INFO) << "OnDeallocateObject: object_id:" << object_id;
  objects_registry_.Remove(object_id);
}

void DispatcherHost::OnCallObjectMethod(
    int object_id,
    const std::string& type,
    const std::string& method,
    const base::ListValue& arguments) {
  DLOG(INFO) << "OnCallObjectMethod: object_id:" << object_id
             << " type:" << type
             << " method:" << method
             << " arguments:" << arguments;

  Base* object = GetApiObject(object_id);
  CHECK(object) << "Unknown object: " << object_id
             << " type:" << type
             << " method:" << method
             << " arguments:" << arguments;
  if (object)
    object->Call(method, arguments);
}

void DispatcherHost::OnCallObjectMethodSync(
    int object_id,
    const std::string& type,
    const std::string& method,
    const base::ListValue& arguments,
    base::ListValue* result) {
  DLOG(INFO) << "OnCallObjectMethodSync: object_id:" << object_id
             << " type:" << type
             << " method:" << method
             << " arguments:" << arguments;

  Base* object = GetApiObject(object_id);
  CHECK(object) << "Unknown object: " << object_id
             << " type:" << type
             << " method:" << method
             << " arguments:" << arguments;
  if (object)
    object->CallSync(method, arguments, result);
}

void DispatcherHost::OnCallStaticMethod(
    const std::string& type,
    const std::string& method,
    const base::ListValue& arguments) {
  DLOG(INFO) << "OnCallStaticMethod: "
             << " type:" << type
             << " method:" << method
             << " arguments:" << arguments;

  if (type == "Shell") {
    api::Shell::Call(method, arguments);
    return;
  } else if (type == "App") {
    api::App::Call(method, arguments);
    return;
  }

  NOTREACHED() << "Calling unknown method " << method << " of class " << type;
}

void DispatcherHost::OnCallStaticMethodSync(
    const std::string& type,
    const std::string& method,
    const base::ListValue& arguments,
    base::ListValue* result) {
  DLOG(INFO) << "OnCallStaticMethodSync: "
             << " type:" << type
             << " method:" << method
             << " arguments:" << arguments;

  if (type == "App") {
    content::Shell* shell =
        content::Shell::FromRenderViewHost(render_view_host());
    api::App::Call(shell, method, arguments, result);
    return;
  }

  NOTREACHED() << "Calling unknown method " << method << " of class " << type;
}

void DispatcherHost::OnUncaughtException(const std::string& err) {
  content::Shell* shell =
      content::Shell::FromRenderViewHost(render_view_host());
  shell->PrintCriticalError("Uncaught node.js Error", err);
}

void DispatcherHost::OnGetShellId(int* id) {
  content::Shell* shell =
      content::Shell::FromRenderViewHost(render_view_host());
  *id = shell->id();
}

void DispatcherHost::OnCreateShell(const std::string& url,
                                   const base::DictionaryValue& manifest,
                                   int* routing_id) {
  WebContents* base_web_contents =
      content::Shell::FromRenderViewHost(render_view_host())->web_contents();
  ShellBrowserContext* browser_context =
      static_cast<ShellBrowserContext*>(base_web_contents->GetBrowserContext());
  scoped_ptr<base::DictionaryValue> new_manifest(manifest.DeepCopy());
  bool new_renderer = false;
  if (new_manifest->GetBoolean(switches::kmNewInstance,
                               &new_renderer) && new_renderer)
    browser_context->set_pinning_renderer(false);

  WebContents::CreateParams create_params(browser_context,
                                          new_renderer ? NULL : base_web_contents->GetSiteInstance());

  WebContents* web_contents = content::WebContentsImpl::CreateWithOpener(
      create_params,
      static_cast<content::WebContentsImpl*>(base_web_contents));
  content::Shell::Create(base_web_contents,
                         GURL(url),
                         new_manifest.get(),
                         web_contents);

  if (new_renderer)
    browser_context->set_pinning_renderer(true);

  *routing_id = web_contents->GetRoutingID();
}

void DispatcherHost::OnGrantUniversalPermissions(int *ret) {
  content::Shell* shell =
      content::Shell::FromRenderViewHost(render_view_host());
  if (shell->nodejs()) {
    content::ChildProcessSecurityPolicy::GetInstance()->GrantUniversalAccess(shell->web_contents()->GetRenderProcessHost()->GetID());
    *ret = 1;
  }else
    *ret = 0;
}

}  // namespace api
<|endoftext|>


<commit_before>/*=============================================================================
	Copyright (c) 2012-2013 Richard Otis

    Distributed under the Boost Software License, Version 1.0. (See accompanying
    file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
=============================================================================*/

#include "libgibbs/include/libgibbs_pch.hpp"
#define BOOST_PYTHON_STATIC_LIB
#ifndef BOOST_SPIRIT_USE_PHOENIX_V3
#define BOOST_SPIRIT_USE_PHOENIX_V3 1
#endif
#include "libtdb/include/database.hpp"
#include "libtdb/include/conditions.hpp"
#include "libgibbs/include/equilibrium.hpp"
#include "external/coin/IpIpoptApplication.hpp"
#include "external/coin/IpSolveStatistics.hpp"
#include <cmath>
#include <boost/python.hpp>
#include <boost/python/enum.hpp>
#include <boost/python/suite/indexing/map_indexing_suite.hpp>
#include <boost/python/suite/indexing/vector_indexing_suite.hpp>

using namespace boost::python;

BOOST_PYTHON_MODULE(libpygibbs)
{
	// Wrapper to convert some common std containers
	class_<std::map<std::string,double>>("StdMap")
		.def(map_indexing_suite<std::map<std::string, double> >() )
	;
	class_<std::map<std::string,PhaseStatus>>("PhaseStatusMap")
		.def(map_indexing_suite<std::map<std::string, PhaseStatus> >() )
	;
	// TODO: why do I have charmaps at all? This is a class decl problem
	class_<std::map<char,double>>("StdCharMap")
		.def(map_indexing_suite<std::map<char, double> >() )
	;
	class_<std::vector<std::string>>("StdVector")
		.def(vector_indexing_suite<std::vector<std::string> >() )
	;
	enum_<PhaseStatus>("PhaseStatus")
		.value("ENTERED", PhaseStatus::ENTERED)
		.value("DORMANT", PhaseStatus::DORMANT)
		.value("FIXED", PhaseStatus::FIXED)
		.value("SUSPENDED",  PhaseStatus::SUSPENDED)
	;

    class_<Database>("Database", init<std::string>())
        .def("get_info", &Database::get_info)
    ;
    class_<evalconditions>("evalconditions")
    	.def_readwrite("statevars", &evalconditions::statevars)
    	.def_readwrite("elements", &evalconditions::elements)
    	.def_readwrite("phases", &evalconditions::phases)
    	.def_readwrite("xfrac", &evalconditions::xfrac)
    ;

    class_<Equilibrium, boost::shared_ptr<Equilibrium>, boost::noncopyable>("Equilibrium", no_init)
    	.def("__repr__", &Equilibrium::print)
    	.def("__str__", &Equilibrium::print)
    ;
    class_<EquilibriumFactory>("EquilibriumFactory")
        .def("GetIpopt", &EquilibriumFactory::GetIpopt)
        .def("create", &EquilibriumFactory::create)
    ;
}
<commit_msg>Fixed logging for the Python library<commit_after>/*=============================================================================
	Copyright (c) 2012-2013 Richard Otis

    Distributed under the Boost Software License, Version 1.0. (See accompanying
    file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
=============================================================================*/

#include "libgibbs/include/libgibbs_pch.hpp"
#define BOOST_PYTHON_STATIC_LIB
#ifndef BOOST_SPIRIT_USE_PHOENIX_V3
#define BOOST_SPIRIT_USE_PHOENIX_V3 1
#endif
#include "libtdb/include/database.hpp"
#include "libtdb/include/conditions.hpp"
#include "libtdb/include/logging.hpp"
#include "libgibbs/include/equilibrium.hpp"
#include "external/coin/IpIpoptApplication.hpp"
#include "external/coin/IpSolveStatistics.hpp"
#include <cmath>
#include <boost/python.hpp>
#include <boost/python/enum.hpp>
#include <boost/python/suite/indexing/map_indexing_suite.hpp>
#include <boost/python/suite/indexing/vector_indexing_suite.hpp>

using namespace boost::python;

BOOST_PYTHON_MODULE(libpygibbs)
{
	init_logging();
	// Wrapper to convert some common std containers
	class_<std::map<std::string,double>>("StdMap")
		.def(map_indexing_suite<std::map<std::string, double> >() )
	;
	class_<std::map<std::string,PhaseStatus>>("PhaseStatusMap")
		.def(map_indexing_suite<std::map<std::string, PhaseStatus> >() )
	;
	// TODO: why do I have charmaps at all? This is a class decl problem
	class_<std::map<char,double>>("StdCharMap")
		.def(map_indexing_suite<std::map<char, double> >() )
	;
	class_<std::vector<std::string>>("StdVector")
		.def(vector_indexing_suite<std::vector<std::string> >() )
	;
	enum_<PhaseStatus>("PhaseStatus")
		.value("ENTERED", PhaseStatus::ENTERED)
		.value("DORMANT", PhaseStatus::DORMANT)
		.value("FIXED", PhaseStatus::FIXED)
		.value("SUSPENDED",  PhaseStatus::SUSPENDED)
	;

    class_<Database>("Database", init<std::string>())
        .def("get_info", &Database::get_info)
    ;
    class_<evalconditions>("evalconditions")
    	.def_readwrite("statevars", &evalconditions::statevars)
    	.def_readwrite("elements", &evalconditions::elements)
    	.def_readwrite("phases", &evalconditions::phases)
    	.def_readwrite("xfrac", &evalconditions::xfrac)
    ;

    class_<Equilibrium, boost::shared_ptr<Equilibrium>, boost::noncopyable>("Equilibrium", no_init)
    	.def("__repr__", &Equilibrium::print)
    	.def("__str__", &Equilibrium::print)
    ;
    class_<EquilibriumFactory>("EquilibriumFactory")
        .def("GetIpopt", &EquilibriumFactory::GetIpopt)
        .def("create", &EquilibriumFactory::create)
    ;
}
<|endoftext|>


<commit_before>/*
 * Copyright (C) 2012-2015 Open Source Robotics Foundation
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
*/
/* Desc: A 4-wheeled vehicle
 * Author: Nate Koenig
 */

#ifndef _GAZEBO_GIMBAL_CONTROLLER_PLUGIN_HH_
#define _GAZEBO_GIMBAL_CONTROLLER_PLUGIN_HH_

#include <string>
#include <vector>

#include <gazebo/common/PID.hh>
#include <gazebo/common/Plugin.hh>
#include <gazebo/physics/physics.hh>
#include <gazebo/transport/transport.hh>
#include <gazebo/util/system.hh>
#include <gazebo/sensors/sensors.hh>

namespace gazebo
{
  class GAZEBO_VISIBLE GimbalControllerPlugin : public ModelPlugin
  {
    /// \brief Constructor
    public: GimbalControllerPlugin();

    public: virtual void Load(physics::ModelPtr _model, sdf::ElementPtr _sdf);

    public: virtual void Init();

    private: void OnUpdate();

#if 0
    /// only gazebo 7.4 and above support Any
    private: void OnPitchStringMsg(ConstAnyPtr &_msg);
    private: void OnRollStringMsg(ConstAnyPtr &_msg);
    private: void OnYawStringMsg(ConstAnyPtr &_msg);
#else
    private: void OnPitchStringMsg(ConstGzStringPtr &_msg);
    private: void OnRollStringMsg(ConstGzStringPtr &_msg);
    private: void OnYawStringMsg(ConstGzStringPtr &_msg);
#endif

    /// \TODO something to move into Angle class
    /// \brief returns _angle1 normalized about
    /// (_reference - M_PI, _reference + M_PI]
    /// \param[in] _angle1 input angle
    /// \param[in] _reference reference input angle for normalization
    /// \return normalized _angle1 about _reference
    private: double NormalizeAbout(double _angle, double _reference);

    /// \TODO something to move into Angle class
    /// \brief returns shortest angular distance from _from to _to
    /// \param[in] _from starting anglular position
    /// \param[in] _to end angular position
    /// \return distance traveled from starting to end angular positions
    private: double ShortestAngularDistance(double _from, double _to);

    private: sdf::ElementPtr sdf;

    private: std::vector<event::ConnectionPtr> connections;

    private: transport::SubscriberPtr pitchSub;
    private: transport::SubscriberPtr rollSub;
    private: transport::SubscriberPtr yawSub;

    private: transport::PublisherPtr pitchPub;
    private: transport::PublisherPtr rollPub;
    private: transport::PublisherPtr yawPub;

    private: physics::ModelPtr model;

    /// \brief yaw camera
    private: physics::JointPtr yawJoint;

    /// \brief camera roll joint
    private: physics::JointPtr rollJoint;

    /// \brief camera pitch joint
    private: physics::JointPtr pitchJoint;

    private: sensors::ImuSensorPtr imuSensor;

    private: std::string status;

    private: double pitchCommand;
    private: double yawCommand;
    private: double rollCommand;

    private: transport::NodePtr node;

    private: common::PID pitchPid;
    private: common::PID rollPid;
    private: common::PID yawPid;
    private: common::Time lastUpdateTime;
  };
}
#endif
<commit_msg>update header info, copy right<commit_after>/*
 * Copyright (C) 2012-2016 Open Source Robotics Foundation
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
*/
/* Desc: A basic gimbal controller
 * Author: John Hsu
 */

#ifndef _GAZEBO_GIMBAL_CONTROLLER_PLUGIN_HH_
#define _GAZEBO_GIMBAL_CONTROLLER_PLUGIN_HH_

#include <string>
#include <vector>

#include <gazebo/common/PID.hh>
#include <gazebo/common/Plugin.hh>
#include <gazebo/physics/physics.hh>
#include <gazebo/transport/transport.hh>
#include <gazebo/util/system.hh>
#include <gazebo/sensors/sensors.hh>

namespace gazebo
{
  class GAZEBO_VISIBLE GimbalControllerPlugin : public ModelPlugin
  {
    /// \brief Constructor
    public: GimbalControllerPlugin();

    public: virtual void Load(physics::ModelPtr _model, sdf::ElementPtr _sdf);

    public: virtual void Init();

    private: void OnUpdate();

#if 0
    /// only gazebo 7.4 and above support Any
    private: void OnPitchStringMsg(ConstAnyPtr &_msg);
    private: void OnRollStringMsg(ConstAnyPtr &_msg);
    private: void OnYawStringMsg(ConstAnyPtr &_msg);
#else
    private: void OnPitchStringMsg(ConstGzStringPtr &_msg);
    private: void OnRollStringMsg(ConstGzStringPtr &_msg);
    private: void OnYawStringMsg(ConstGzStringPtr &_msg);
#endif

    /// \TODO something to move into Angle class
    /// \brief returns _angle1 normalized about
    /// (_reference - M_PI, _reference + M_PI]
    /// \param[in] _angle1 input angle
    /// \param[in] _reference reference input angle for normalization
    /// \return normalized _angle1 about _reference
    private: double NormalizeAbout(double _angle, double _reference);

    /// \TODO something to move into Angle class
    /// \brief returns shortest angular distance from _from to _to
    /// \param[in] _from starting anglular position
    /// \param[in] _to end angular position
    /// \return distance traveled from starting to end angular positions
    private: double ShortestAngularDistance(double _from, double _to);

    private: sdf::ElementPtr sdf;

    private: std::vector<event::ConnectionPtr> connections;

    private: transport::SubscriberPtr pitchSub;
    private: transport::SubscriberPtr rollSub;
    private: transport::SubscriberPtr yawSub;

    private: transport::PublisherPtr pitchPub;
    private: transport::PublisherPtr rollPub;
    private: transport::PublisherPtr yawPub;

    private: physics::ModelPtr model;

    /// \brief yaw camera
    private: physics::JointPtr yawJoint;

    /// \brief camera roll joint
    private: physics::JointPtr rollJoint;

    /// \brief camera pitch joint
    private: physics::JointPtr pitchJoint;

    private: sensors::ImuSensorPtr imuSensor;

    private: std::string status;

    private: double pitchCommand;
    private: double yawCommand;
    private: double rollCommand;

    private: transport::NodePtr node;

    private: common::PID pitchPid;
    private: common::PID rollPid;
    private: common::PID yawPid;
    private: common::Time lastUpdateTime;
  };
}
#endif
<|endoftext|>


<commit_before>/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
/**
 * Copyright (C) 2013 Regents of the University of California.
 * @author: Yingdi Yu <yingdi@cs.ucla.edu>
 * @author: Jeff Thompson <jefft0@remap.ucla.edu>
 * See COPYING for copyright and distribution information.
 */

#ifndef NDN_KEY_CHAIN_HPP
#define NDN_KEY_CHAIN_HPP

#include "identity-certificate.hpp"
#include "public-key.hpp"
#include "signature-sha256-with-rsa.hpp"

//PublicInfo
#include "sec-public-info-sqlite3.hpp"
#include "sec-public-info-memory.hpp"
//TPM
#include "sec-tpm-file.hpp"
#include "sec-tpm-memory.hpp"

#ifdef NDN_CPP_HAVE_OSX_SECURITY
#include "sec-tpm-osx.hpp"
#endif

namespace ndn {

/**
 * KeyChain is one of the main classes of the security library.
 *
 * The KeyChain class provides a set of interfaces of identity management and private key related operations.
 */
template<class Info, class Tpm>
class KeyChainImpl : public Info, public Tpm
{
public:
  // struct Error : public std::runtime_error { Error(const std::string &what) : std::runtime_error(what) {} };

  /**
   * Create an identity by creating a pair of Key-Signing-Key (KSK) for this identity and a self-signed certificate of the KSK.
   * @param identityName The name of the identity.
   * @return The key name of the auto-generated KSK of the identity.
   */
  Name
  createIdentity(const Name& identityName)
  {
    if (!Info::doesIdentityExist(identityName)) {
      Info::addIdentity(identityName);

      Name keyName = generateRSAKeyPairAsDefault(identityName, true);

      ptr_lib::shared_ptr<IdentityCertificate> selfCert = selfSign(keyName);

      Info::addCertificateAsDefault(*selfCert);

      return keyName;
    }
    else
      return Name();
  }

  /**
   * Generate a pair of RSA keys for the specified identity.
   * @param identityName The name of the identity.
   * @param isKsk true for generating a Key-Signing-Key (KSK), false for a Data-Signing-Key (KSK).
   * @param keySize The size of the key.
   * @return The generated key name.
   */
  Name
  generateRSAKeyPair(const Name& identityName, bool isKsk = false, int keySize = 2048)
  {
    return generateKeyPair(identityName, isKsk, KEY_TYPE_RSA, keySize);
  }

  /**
   * Generate a pair of RSA keys for the specified identity and set it as default key for the identity.
   * @param identityName The name of the identity.
   * @param isKsk true for generating a Key-Signing-Key (KSK), false for a Data-Signing-Key (KSK).
   * @param keySize The size of the key.
   * @return The generated key name.
   */
  Name
  generateRSAKeyPairAsDefault(const Name& identityName, bool isKsk = false, int keySize = 2048)
  {
    Name keyName = generateKeyPair(identityName, isKsk, KEY_TYPE_RSA, keySize);

    Info::setDefaultKeyNameForIdentity(keyName);

    return keyName;
  }

  /**
   * Create an identity certificate for a public key managed by this IdentityManager.
   * @param certificatePrefix The name of public key to be signed.
   * @param signerCertificateName The name of signing certificate.
   * @param notBefore The notBefore value in the validity field of the generated certificate.
   * @param notAfter The notAfter vallue in validity field of the generated certificate.
   * @return The name of generated identity certificate.
   */
  ptr_lib::shared_ptr<IdentityCertificate>
  createIdentityCertificate
    (const Name& certificatePrefix,
     const Name& signerCertificateName,
     const MillisecondsSince1970& notBefore,
     const MillisecondsSince1970& notAfter)
  {
    Name keyName = getKeyNameFromCertificatePrefix(certificatePrefix);

    ptr_lib::shared_ptr<PublicKey> pubKey = Info::getPublicKey(keyName);
    if (!pubKey)
      throw std::runtime_error("Requested public key [" + keyName.toUri() + "] doesn't exist");

    ptr_lib::shared_ptr<IdentityCertificate> certificate =
      createIdentityCertificate(certificatePrefix,
                                *pubKey,
                                signerCertificateName,
                                notBefore, notAfter);

    Info::addCertificate(*certificate);

    return certificate;
  }

  /**
   * Create an identity certificate for a public key supplied by the caller.
   * @param certificatePrefix The name of public key to be signed.
   * @param publickey The public key to be signed.
   * @param signerCertificateName The name of signing certificate.
   * @param notBefore The notBefore value in the validity field of the generated certificate.
   * @param notAfter The notAfter vallue in validity field of the generated certificate.
   * @return The generated identity certificate.
   */
  ptr_lib::shared_ptr<IdentityCertificate>
  createIdentityCertificate
    (const Name& certificatePrefix,
     const PublicKey& publicKey,
     const Name& signerCertificateName,
     const MillisecondsSince1970& notBefore,
     const MillisecondsSince1970& notAfter)
  {
    ptr_lib::shared_ptr<IdentityCertificate> certificate (new IdentityCertificate());
    Name keyName = getKeyNameFromCertificatePrefix(certificatePrefix);

    Name certificateName = certificatePrefix;
    certificateName.append("ID-CERT").appendVersion();

    certificate->setName(certificateName);
    certificate->setNotBefore(notBefore);
    certificate->setNotAfter(notAfter);
    certificate->setPublicKeyInfo(publicKey);
    certificate->addSubjectDescription(CertificateSubjectDescription("2.5.4.41", keyName.toUri()));
    certificate->encode();

    sign(*certificate, signerCertificateName);

    return certificate;
  }

  /**
   * Fetch the private key for keyName and sign the data, and set the signature block of the data packet.
   * Throw Error if signing fails.
   * @param data Reference to the input data packet.
   * @param keyName The name of the signing key.
   * @param digestAlgorithm the digest algorithm.
   */
  void
  signInTpm(Data &data, const Name& keyName, DigestAlgorithm digestAlgorithm)
  {
    data.setSignatureValue
      (Tpm::signInTpm(data.wireEncode().value(),
                      data.wireEncode().value_size() - data.getSignature().getValue().size(),
                      keyName, digestAlgorithm));
  }

  void
  sign(Data &data)
  {
    if (!Info::defaultCertificate())
      {
        Info::refreshDefaultCertificate();

        if(!Info::defaultCertificate())
          throw std::runtime_error("Default IdentityCertificate cannot be determined");
      }

    sign(data, *Info::defaultCertificate());
  }

  /**
   * Wire encode the Data object, sign it and set its signature.
   * @param data The Data object to be signed.  This updates its signature and key locator field and wireEncoding.
   * @param certificateName The certificate name of the key to use for signing.  If omitted, infer the signing identity from the data packet name.
   */
  void
  sign(Data& data, const Name& certificateName)
  {
    ptr_lib::shared_ptr<IdentityCertificate> cert = Info::getCertificate(certificateName);
    if (!cert)
      throw std::runtime_error("Requested certificate [" + certificateName.toUri() + "] doesn't exist");

    SignatureSha256WithRsa signature;
    signature.setKeyLocator(certificateName.getPrefix(-1)); // implicit conversion should take care
    data.setSignature(signature);

    // For temporary usage, we support RSA + SHA256 only, but will support more.
    signInTpm(data, cert->getPublicKeyName(), DIGEST_ALGORITHM_SHA256);
  }

  void
  sign(Data& data, const IdentityCertificate& certificate)
  {
    SignatureSha256WithRsa signature;
    signature.setKeyLocator(certificate.getName().getPrefix(-1));
    data.setSignature(signature);

    // For temporary usage, we support RSA + SHA256 only, but will support more.
    signInTpm(data, certificate.getPublicKeyName(), DIGEST_ALGORITHM_SHA256);
  }

  /**
   * Sign the byte array using a certificate name and return a Signature object.
   * @param buffer The byte array to be signed.
   * @param bufferLength the length of buffer.
   * @param certificateName The certificate name used to get the signing key and which will be put into KeyLocator.
   * @return The Signature.
   */
  Signature
  sign(const uint8_t* buffer, size_t bufferLength, const Name& certificateName)
  {
    ptr_lib::shared_ptr<IdentityCertificate> cert = Info::getCertificate(certificateName);
    if (!cert)
      throw std::runtime_error("Requested certificate [" + certificateName.toUri() + "] doesn't exist");

    SignatureSha256WithRsa signature;
    signature.setKeyLocator(certificateName.getPrefix(-1)); // implicit conversion should take care

    // For temporary usage, we support RSA + SHA256 only, but will support more.
    signature.setValue(Tpm::signInTpm(buffer, bufferLength, cert->getPublicKeyName(), DIGEST_ALGORITHM_SHA256));
    return signature;
  }

  /**
   * Wire encode the Data object, sign it and set its signature.
   * @param data The Data object to be signed.  This updates its signature and key locator field and wireEncoding.
   * @param identityName The identity name for the key to use for signing.  If omitted, infer the signing identity from the data packet name.
   */
  void
  signByIdentity(Data& data, const Name& identityName = Name())
  {
    Name signingCertificateName = Info::getDefaultCertificateNameForIdentity(identityName);

    if (signingCertificateName.getComponentCount() == 0)
      throw std::runtime_error("No qualified certificate name found!");

    sign(data, signingCertificateName);
  }

  /**
   * Sign the byte array using an identity name and return a Signature object.
   * @param buffer The byte array to be signed.
   * @param bufferLength the length of buffer.
   * @param identityName The identity name.
   * @return The Signature.
   */
  Signature
  signByIdentity(const uint8_t* buffer, size_t bufferLength, const Name& identityName = Name())
  {
    Name signingCertificateName = Info::getDefaultCertificateNameForIdentity(identityName);

    if (signingCertificateName.size() == 0)
      throw std::runtime_error("No qualified certificate name found!");

    return sign(buffer, bufferLength, signingCertificateName);
  }

  /**
   * Generate a self-signed certificate for a public key.
   * @param keyName The name of the public key.
   * @return The generated certificate.
   */
  ptr_lib::shared_ptr<IdentityCertificate>
  selfSign(const Name& keyName)
  {
    if(keyName.empty())
      throw std::runtime_error("Incorrect key name: " + keyName.toUri());

    ptr_lib::shared_ptr<IdentityCertificate> certificate = ptr_lib::make_shared<IdentityCertificate>();

    Name certificateName = keyName.getPrefix(-1);
    certificateName.append("KEY").append(keyName.get(-1)).append("ID-CERT").appendVersion();

    ptr_lib::shared_ptr<PublicKey> pubKey = Info::getPublicKey(keyName);
    if (!pubKey)
      throw std::runtime_error("Requested public key [" + keyName.toUri() + "] doesn't exist");

    certificate->setName(certificateName);
    certificate->setNotBefore(getNow());
    certificate->setNotAfter(getNow() + 630720000 /* 20 years*/);
    certificate->setPublicKeyInfo(*pubKey);
    certificate->addSubjectDescription(CertificateSubjectDescription("2.5.4.41", keyName.toUri()));
    certificate->encode();

    selfSign(*certificate);
    return certificate;
  }

  /**
   * @brief Self-sign the supplied identity certificate
   */
  void
  selfSign (IdentityCertificate& cert)
  {
    SignatureSha256WithRsa signature;
    signature.setKeyLocator(cert.getName().getPrefix(-1)); // implicit conversion should take care
    cert.setSignature(signature);

    // For temporary usage, we support RSA + SHA256 only, but will support more.
    signInTpm(cert, cert.getPublicKeyName(), DIGEST_ALGORITHM_SHA256);
  }

private:
  /**
   * Generate a key pair for the specified identity.
   * @param identityName The name of the specified identity.
   * @param isKsk true for generating a Key-Signing-Key (KSK), false for a Data-Signing-Key (KSK).
   * @param keyType The type of the key pair, e.g. KEY_TYPE_RSA.
   * @param keySize The size of the key pair.
   * @return The name of the generated key.
   */
  Name
  generateKeyPair(const Name& identityName, bool isKsk = false, KeyType keyType = KEY_TYPE_RSA, int keySize = 2048)
  {
    Name keyName = Info::getNewKeyName(identityName, isKsk);

    Tpm::generateKeyPairInTpm(keyName.toUri(), keyType, keySize);

    ptr_lib::shared_ptr<PublicKey> pubKey = Tpm::getPublicKeyFromTpm(keyName.toUri());
    Info::addPublicKey(keyName, keyType, *pubKey);

    return keyName;
  }

  static Name
  getKeyNameFromCertificatePrefix(const Name& certificatePrefix)
  {
    Name result;

    std::string keyString("KEY");
    int i = 0;
    for(; i < certificatePrefix.size(); i++) {
      if (certificatePrefix.get(i).toEscapedString() == keyString)
        break;
    }

    if (i >= certificatePrefix.size())
      throw std::runtime_error("Identity Certificate Prefix does not have a KEY component");

    result.append(certificatePrefix.getSubName(0, i));
    result.append(certificatePrefix.getSubName(i + 1, certificatePrefix.size()-i-1));

    return result;
  }

};

}

#ifdef NDN_CPP_HAVE_OSX_SECURITY

namespace ndn
{
typedef KeyChainImpl<SecPublicInfoSqlite3, SecTpmOsx> KeyChain;
};

#else

namespace ndn
{
typedef KeyChainImpl<SecPublicInfoSqlite3, SecTpmFile> KeyChain;
};

#endif //NDN_CPP_HAVE_OSX_SECURITY

#endif
<commit_msg>security: Rename KeyChain::signInTpm to KeyChain::signDataInTpm, and make it priviate.<commit_after>/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
/**
 * Copyright (C) 2013 Regents of the University of California.
 * @author: Yingdi Yu <yingdi@cs.ucla.edu>
 * @author: Jeff Thompson <jefft0@remap.ucla.edu>
 * See COPYING for copyright and distribution information.
 */

#ifndef NDN_KEY_CHAIN_HPP
#define NDN_KEY_CHAIN_HPP

#include "identity-certificate.hpp"
#include "public-key.hpp"
#include "signature-sha256-with-rsa.hpp"

//PublicInfo
#include "sec-public-info-sqlite3.hpp"
#include "sec-public-info-memory.hpp"
//TPM
#include "sec-tpm-file.hpp"
#include "sec-tpm-memory.hpp"

#ifdef NDN_CPP_HAVE_OSX_SECURITY
#include "sec-tpm-osx.hpp"
#endif

namespace ndn {

/**
 * KeyChain is one of the main classes of the security library.
 *
 * The KeyChain class provides a set of interfaces of identity management and private key related operations.
 */
template<class Info, class Tpm>
class KeyChainImpl : public Info, public Tpm
{
public:
  // struct Error : public std::runtime_error { Error(const std::string &what) : std::runtime_error(what) {} };

  /**
   * Create an identity by creating a pair of Key-Signing-Key (KSK) for this identity and a self-signed certificate of the KSK.
   * @param identityName The name of the identity.
   * @return The key name of the auto-generated KSK of the identity.
   */
  Name
  createIdentity(const Name& identityName)
  {
    if (!Info::doesIdentityExist(identityName)) {
      Info::addIdentity(identityName);

      Name keyName = generateRSAKeyPairAsDefault(identityName, true);

      ptr_lib::shared_ptr<IdentityCertificate> selfCert = selfSign(keyName);

      Info::addCertificateAsDefault(*selfCert);

      return keyName;
    }
    else
      return Name();
  }

  /**
   * Generate a pair of RSA keys for the specified identity.
   * @param identityName The name of the identity.
   * @param isKsk true for generating a Key-Signing-Key (KSK), false for a Data-Signing-Key (KSK).
   * @param keySize The size of the key.
   * @return The generated key name.
   */
  Name
  generateRSAKeyPair(const Name& identityName, bool isKsk = false, int keySize = 2048)
  {
    return generateKeyPair(identityName, isKsk, KEY_TYPE_RSA, keySize);
  }

  /**
   * Generate a pair of RSA keys for the specified identity and set it as default key for the identity.
   * @param identityName The name of the identity.
   * @param isKsk true for generating a Key-Signing-Key (KSK), false for a Data-Signing-Key (KSK).
   * @param keySize The size of the key.
   * @return The generated key name.
   */
  Name
  generateRSAKeyPairAsDefault(const Name& identityName, bool isKsk = false, int keySize = 2048)
  {
    Name keyName = generateKeyPair(identityName, isKsk, KEY_TYPE_RSA, keySize);

    Info::setDefaultKeyNameForIdentity(keyName);

    return keyName;
  }

  /**
   * Create an identity certificate for a public key managed by this IdentityManager.
   * @param certificatePrefix The name of public key to be signed.
   * @param signerCertificateName The name of signing certificate.
   * @param notBefore The notBefore value in the validity field of the generated certificate.
   * @param notAfter The notAfter vallue in validity field of the generated certificate.
   * @return The name of generated identity certificate.
   */
  ptr_lib::shared_ptr<IdentityCertificate>
  createIdentityCertificate
    (const Name& certificatePrefix,
     const Name& signerCertificateName,
     const MillisecondsSince1970& notBefore,
     const MillisecondsSince1970& notAfter)
  {
    Name keyName = getKeyNameFromCertificatePrefix(certificatePrefix);

    ptr_lib::shared_ptr<PublicKey> pubKey = Info::getPublicKey(keyName);
    if (!pubKey)
      throw std::runtime_error("Requested public key [" + keyName.toUri() + "] doesn't exist");

    ptr_lib::shared_ptr<IdentityCertificate> certificate =
      createIdentityCertificate(certificatePrefix,
                                *pubKey,
                                signerCertificateName,
                                notBefore, notAfter);

    Info::addCertificate(*certificate);

    return certificate;
  }

  /**
   * Create an identity certificate for a public key supplied by the caller.
   * @param certificatePrefix The name of public key to be signed.
   * @param publickey The public key to be signed.
   * @param signerCertificateName The name of signing certificate.
   * @param notBefore The notBefore value in the validity field of the generated certificate.
   * @param notAfter The notAfter vallue in validity field of the generated certificate.
   * @return The generated identity certificate.
   */
  ptr_lib::shared_ptr<IdentityCertificate>
  createIdentityCertificate
    (const Name& certificatePrefix,
     const PublicKey& publicKey,
     const Name& signerCertificateName,
     const MillisecondsSince1970& notBefore,
     const MillisecondsSince1970& notAfter)
  {
    ptr_lib::shared_ptr<IdentityCertificate> certificate (new IdentityCertificate());
    Name keyName = getKeyNameFromCertificatePrefix(certificatePrefix);

    Name certificateName = certificatePrefix;
    certificateName.append("ID-CERT").appendVersion();

    certificate->setName(certificateName);
    certificate->setNotBefore(notBefore);
    certificate->setNotAfter(notAfter);
    certificate->setPublicKeyInfo(publicKey);
    certificate->addSubjectDescription(CertificateSubjectDescription("2.5.4.41", keyName.toUri()));
    certificate->encode();

    sign(*certificate, signerCertificateName);

    return certificate;
  }

  void
  sign(Data &data)
  {
    if (!Info::defaultCertificate())
      {
        Info::refreshDefaultCertificate();

        if(!Info::defaultCertificate())
          throw std::runtime_error("Default IdentityCertificate cannot be determined");
      }

    sign(data, *Info::defaultCertificate());
  }

  /**
   * Wire encode the Data object, sign it and set its signature.
   * @param data The Data object to be signed.  This updates its signature and key locator field and wireEncoding.
   * @param certificateName The certificate name of the key to use for signing.  If omitted, infer the signing identity from the data packet name.
   */
  void
  sign(Data& data, const Name& certificateName)
  {
    ptr_lib::shared_ptr<IdentityCertificate> cert = Info::getCertificate(certificateName);
    if (!cert)
      throw std::runtime_error("Requested certificate [" + certificateName.toUri() + "] doesn't exist");

    SignatureSha256WithRsa signature;
    signature.setKeyLocator(certificateName.getPrefix(-1)); // implicit conversion should take care
    data.setSignature(signature);

    // For temporary usage, we support RSA + SHA256 only, but will support more.
    signDataInTpm(data, cert->getPublicKeyName(), DIGEST_ALGORITHM_SHA256);
  }

  void
  sign(Data& data, const IdentityCertificate& certificate)
  {
    SignatureSha256WithRsa signature;
    signature.setKeyLocator(certificate.getName().getPrefix(-1));
    data.setSignature(signature);

    // For temporary usage, we support RSA + SHA256 only, but will support more.
    signDataInTpm(data, certificate.getPublicKeyName(), DIGEST_ALGORITHM_SHA256);
  }

  /**
   * Sign the byte array using a certificate name and return a Signature object.
   * @param buffer The byte array to be signed.
   * @param bufferLength the length of buffer.
   * @param certificateName The certificate name used to get the signing key and which will be put into KeyLocator.
   * @return The Signature.
   */
  Signature
  sign(const uint8_t* buffer, size_t bufferLength, const Name& certificateName)
  {
    ptr_lib::shared_ptr<IdentityCertificate> cert = Info::getCertificate(certificateName);
    if (!cert)
      throw std::runtime_error("Requested certificate [" + certificateName.toUri() + "] doesn't exist");

    SignatureSha256WithRsa signature;
    signature.setKeyLocator(certificateName.getPrefix(-1)); // implicit conversion should take care

    // For temporary usage, we support RSA + SHA256 only, but will support more.
    signature.setValue(Tpm::signInTpm(buffer, bufferLength, cert->getPublicKeyName(), DIGEST_ALGORITHM_SHA256));
    return signature;
  }

  /**
   * Wire encode the Data object, sign it and set its signature.
   * @param data The Data object to be signed.  This updates its signature and key locator field and wireEncoding.
   * @param identityName The identity name for the key to use for signing.  If omitted, infer the signing identity from the data packet name.
   */
  void
  signByIdentity(Data& data, const Name& identityName = Name())
  {
    Name signingCertificateName = Info::getDefaultCertificateNameForIdentity(identityName);

    if (signingCertificateName.getComponentCount() == 0)
      throw std::runtime_error("No qualified certificate name found!");

    sign(data, signingCertificateName);
  }

  /**
   * Sign the byte array using an identity name and return a Signature object.
   * @param buffer The byte array to be signed.
   * @param bufferLength the length of buffer.
   * @param identityName The identity name.
   * @return The Signature.
   */
  Signature
  signByIdentity(const uint8_t* buffer, size_t bufferLength, const Name& identityName = Name())
  {
    Name signingCertificateName = Info::getDefaultCertificateNameForIdentity(identityName);

    if (signingCertificateName.size() == 0)
      throw std::runtime_error("No qualified certificate name found!");

    return sign(buffer, bufferLength, signingCertificateName);
  }

  /**
   * Generate a self-signed certificate for a public key.
   * @param keyName The name of the public key.
   * @return The generated certificate.
   */
  ptr_lib::shared_ptr<IdentityCertificate>
  selfSign(const Name& keyName)
  {
    if(keyName.empty())
      throw std::runtime_error("Incorrect key name: " + keyName.toUri());

    ptr_lib::shared_ptr<IdentityCertificate> certificate = ptr_lib::make_shared<IdentityCertificate>();

    Name certificateName = keyName.getPrefix(-1);
    certificateName.append("KEY").append(keyName.get(-1)).append("ID-CERT").appendVersion();

    ptr_lib::shared_ptr<PublicKey> pubKey = Info::getPublicKey(keyName);
    if (!pubKey)
      throw std::runtime_error("Requested public key [" + keyName.toUri() + "] doesn't exist");

    certificate->setName(certificateName);
    certificate->setNotBefore(getNow());
    certificate->setNotAfter(getNow() + 630720000 /* 20 years*/);
    certificate->setPublicKeyInfo(*pubKey);
    certificate->addSubjectDescription(CertificateSubjectDescription("2.5.4.41", keyName.toUri()));
    certificate->encode();

    selfSign(*certificate);
    return certificate;
  }

  /**
   * @brief Self-sign the supplied identity certificate
   */
  void
  selfSign (IdentityCertificate& cert)
  {
    SignatureSha256WithRsa signature;
    signature.setKeyLocator(cert.getName().getPrefix(-1)); // implicit conversion should take care
    cert.setSignature(signature);

    // For temporary usage, we support RSA + SHA256 only, but will support more.
    signDataInTpm(cert, cert.getPublicKeyName(), DIGEST_ALGORITHM_SHA256);
  }

private:
  /**
   * Generate a key pair for the specified identity.
   * @param identityName The name of the specified identity.
   * @param isKsk true for generating a Key-Signing-Key (KSK), false for a Data-Signing-Key (KSK).
   * @param keyType The type of the key pair, e.g. KEY_TYPE_RSA.
   * @param keySize The size of the key pair.
   * @return The name of the generated key.
   */
  Name
  generateKeyPair(const Name& identityName, bool isKsk = false, KeyType keyType = KEY_TYPE_RSA, int keySize = 2048)
  {
    Name keyName = Info::getNewKeyName(identityName, isKsk);

    Tpm::generateKeyPairInTpm(keyName.toUri(), keyType, keySize);

    ptr_lib::shared_ptr<PublicKey> pubKey = Tpm::getPublicKeyFromTpm(keyName.toUri());
    Info::addPublicKey(keyName, keyType, *pubKey);

    return keyName;
  }

  static Name
  getKeyNameFromCertificatePrefix(const Name& certificatePrefix)
  {
    Name result;

    std::string keyString("KEY");
    int i = 0;
    for(; i < certificatePrefix.size(); i++) {
      if (certificatePrefix.get(i).toEscapedString() == keyString)
        break;
    }

    if (i >= certificatePrefix.size())
      throw std::runtime_error("Identity Certificate Prefix does not have a KEY component");

    result.append(certificatePrefix.getSubName(0, i));
    result.append(certificatePrefix.getSubName(i + 1, certificatePrefix.size()-i-1));

    return result;
  }

  /**
   * Fetch the private key for keyName and sign the data, and set the signature block of the data packet.
   * @param data Reference to the input data packet.
   * @param keyName The name of the signing key.
   * @param digestAlgorithm the digest algorithm.
   * @throws Tpm::Error
   */
  void
  signDataInTpm(Data &data, const Name& keyName, DigestAlgorithm digestAlgorithm)
  {
    data.setSignatureValue
      (Tpm::signInTpm(data.wireEncode().value(),
                      data.wireEncode().value_size() - data.getSignature().getValue().size(),
                      keyName, digestAlgorithm));
  }

};

}

#ifdef NDN_CPP_HAVE_OSX_SECURITY

namespace ndn
{
typedef KeyChainImpl<SecPublicInfoSqlite3, SecTpmOsx> KeyChain;
};

#else

namespace ndn
{
typedef KeyChainImpl<SecPublicInfoSqlite3, SecTpmFile> KeyChain;
};

#endif //NDN_CPP_HAVE_OSX_SECURITY

#endif
<|endoftext|>


<commit_before>/*
 * TTBlue Object Base Class
 * Copyright © 2008, Timothy Place
 *
 * License: This code is licensed under the terms of the GNU LGPL
 * http://www.gnu.org/licenses/lgpl.html
 */

#include "TTObject.h"
#include "TTEnvironment.h"
#include "TTClass.h"

TTObject::TTObject(TTValue& arguments)
	: classPtr(NULL), observers(NULL), messageObservers(NULL), attributeObservers(NULL),
	  locked(false), referenceCount(1), valid(false), reserved1(0), reserved2(0)
{
	messages = new TTHash;
	attributes = new TTHash;
	observers = new TTList;
	// 'valid' will be set true by the Environment class which is the factory for all objects
}

TTObject::~TTObject()
{
	TTValue	v, u;

	delete observers;

	// Delete message objects, then delete the hash that maintains them.
	messages->getKeys(v);
	for(TTUInt16 i=0; i<v.getSize(); i++){
		TTSymbol*	name = NULL;
		TTMessage*	message = NULL;

		v.get(i, &name);
		messages->lookup(name, u);
		message = TTMessagePtr(TTPtr(u));
		delete message;
	}
	delete messages;

	// Delete attribute objects, then delete the hash that maintains them.
	attributes->getKeys(v);
	for(TTUInt16 i=0; i<v.getSize(); i++){
		TTSymbol*		name = NULL;
		TTAttribute*	attribute = NULL;

		v.get(i, &name);
		attributes->lookup(name, u);
		attribute = TTAttributePtr(TTPtr(u));
		delete attribute;
	}
	delete attributes;
}

#if 0
#pragma mark -
#pragma mark Object Attributes
#endif

TTErr TTObject::registerAttribute(const TTSymbolPtr name, TTDataType type, void* address)
{
	TTAttribute* newAttribute = new TTAttribute(name, type, address);

	newAttribute->setGetterFlags(kTTAttrPassObject);
	newAttribute->setSetterFlags(kTTAttrPassObject);
	attributes->append(name, TTPtr(newAttribute));
	return kTTErrNone;
}

TTErr TTObject::registerAttribute(const TTSymbolPtr name, TTDataType type, void* address, TTGetterMethod getter)
{
	TTAttribute* newAttribute = new TTAttribute(name, type, address, getter);

	newAttribute->setSetterFlags(kTTAttrPassObject);
	attributes->append(name, TTPtr(newAttribute));
	return kTTErrNone;
}

TTErr TTObject::registerAttribute(const TTSymbolPtr name, TTDataType type, void* address, TTSetterMethod setter)
{
	TTAttribute* newAttribute = new TTAttribute(name, type, address, setter);

	newAttribute->setGetterFlags(kTTAttrPassObject);
	attributes->append(name, TTPtr(newAttribute));
	return kTTErrNone;
}

TTErr TTObject::registerAttribute(const TTSymbolPtr name, TTDataType type, void* address, TTGetterMethod getter, TTSetterMethod setter)
{
	TTAttribute* newAttribute = new TTAttribute(name, type, address, getter, setter);

	attributes->append(name, TTPtr(newAttribute));
	return kTTErrNone;
}

TTErr TTObject::findAttribute(const TTSymbolPtr name, TTAttribute** attr)
{
	TTValue v;
	TTErr	err = kTTErrNone;

	err = attributes->lookup(TTSymbolPtr(name), v);
	if(!err){
		*attr = TTAttributePtr(TTPtr(v));
		return kTTErrNone;
	}
	else
		return kTTErrInvalidAttribute;
}

TTErr TTObject::getAttributeValue(const TTSymbolPtr name, TTValue& value)
{
	TTAttributePtr	attribute;
	TTErr			err;

	err = findAttribute(name, &attribute);
	if(!err){
		if(attribute->getterFlags & kTTAttrPassObject)
			err = (this->*attribute->getter)(*attribute, value);
		else{
			TTMethodValue getter = (TTMethodValue)attribute->getter;
			err = (this->*getter)(value);
		}
	}

	return err;
}

TTErr TTObject::setAttributeValue(const TTSymbolPtr name, TTValue& value)
{
	TTAttributePtr	attribute;
	TTErr			err;

	err = findAttribute(name, &attribute);
	if(!err){
		if(attribute->readOnly)
			err = kTTErrReadOnly;
		else{
			if(attribute->rangeChecking == TT("clip"))
				value.clip(attribute->rangeLowBound, attribute->rangeHighBound);
			else if(attribute->rangeChecking == TT("cliplow"))
				value.cliplow(attribute->rangeLowBound);
			else if(attribute->rangeChecking == TT("cliphigh"))
				value.cliphigh(attribute->rangeHighBound);

			if(attribute->setterFlags & kTTAttrPassObject)
				err = (this->*attribute->setter)(*attribute, value);
			else{
				TTMethodConstValue setter = (TTMethodConstValue)attribute->setter;
				err = (this->*setter)(value);
			}
		}
	}
	return err;
}

TTErr TTObject::getAttributeGetterFlags(const TTSymbolPtr name, TTAttributeFlags& value)
{
	TTAttributePtr	attribute;
	TTErr			err;

	err = findAttribute(name, &attribute);
	if(!err)
		attribute->getGetterFlags(value);

	return err;
}

TTErr TTObject::setAttributeGetterFlags(const TTSymbolPtr name, TTAttributeFlags& value)
{
	TTAttributePtr	attribute;
	TTErr			err;

	err = findAttribute(name, &attribute);
	if(!err)
		attribute->setGetterFlags(value);

	return err;
}

TTErr TTObject::getAttributeSetterFlags(const TTSymbolPtr name, TTAttributeFlags& value)
{
	TTAttributePtr	attribute;
	TTErr			err;

	err = findAttribute(name, &attribute);
	if(!err)
		attribute->getSetterFlags(value);

	return err;
}

TTErr TTObject::setAttributeSetterFlags(const TTSymbolPtr name, TTAttributeFlags& value)
{
	TTAttributePtr	attribute;
	TTErr			err;

	err = findAttribute(name, &attribute);
	if(!err)
		attribute->setSetterFlags(value);

	return err;
}

void TTObject::getAttributeNames(TTValue& attributeNameList)
{
	attributes->getKeys(attributeNameList);
}

TTErr TTObject::registerAttributeProperty(const TTSymbolPtr attributeName, const TTSymbolPtr propertyName, const TTValue& initialValue, TTGetterMethod getter, TTSetterMethod setter)
{
	TTAttributePtr	theAttr = NULL;
	TTValue			v;
	TTErr			err;

	err = attributes->lookup(attributeName, v);
	if(!err){
		theAttr = TTAttributePtr(TTPtr(v));
		err = theAttr->registerAttribute(propertyName, kTypeLocalValue, NULL, getter, setter);
		theAttr->setAttributeValue(propertyName, (TTValue&)initialValue);
	}
	return err;
}

void TTObject::getMessageNames(TTValue& messageNameList)
{
	messages->getKeys(messageNameList);
}

TTSymbol* TTObject::getName() const
{
	return classPtr->name;
}

#if 0
#pragma mark -
#pragma mark Object Messages
#endif

TTErr TTObject::registerMessage(const TTSymbolPtr name, TTMethod method)
{
	TTMessagePtr newMessage = new TTMessage(name, method, kTTMessageDefaultFlags);

	if(ttEnvironment && ttEnvironment->debugMessaging)
		logMessage("Registering Message '%s' with flags = %ld, message count for this object is now %ld\n", name->getCString(), kTTMessageDefaultFlags, messages->getSize());

	messages->append(name, TTPtr(newMessage));
	return kTTErrNone;
}

TTErr TTObject::registerMessage(const TTSymbolPtr name, TTMethod method, TTMessageFlags flags)
{
	TTMessagePtr newMessage = new TTMessage(name, method, flags);

	if(ttEnvironment->debugMessaging)
		logMessage("Registering Message '%s' with flags = %ld, message count for this object is now %ld\n", name->getCString(), kTTMessageDefaultFlags, messages->getSize());

	messages->append(name, TTPtr(newMessage));
	return kTTErrNone;
}

TTErr TTObject::findMessage(const TTSymbolPtr name, TTMessage** message)
{
	TTValue v;
	TTErr	err = kTTErrNone;

	err = messages->lookup(TTSymbolPtr(name), v);
	if(!err){
		*message = TTMessagePtr(TTPtr(v));
		return kTTErrNone;
	}
	else
		return kTTErrInvalidAttribute;
}

TTErr TTObject::sendMessage(const TTSymbolPtr name)
{
	TTValue	v;
	return sendMessage(name, v);
}

TTErr TTObject::sendMessage(const TTSymbolPtr name, TTValue& value)
{
	TTMessagePtr	message;
	TTErr			err;

	err = findMessage(name, &message);
	if(!err){
		if(message->flags & kTTMessagePassNone){
			TTMethodNone method = (TTMethodNone)message->method;
			return (this->*method)();
		}
		else if(message->flags & kTTMessagePassNameAndValue){
			return (this->*message->method)(name, value);
		}
		else{	// default is kTTMessagePassValue
			TTMethodValue method = (TTMethodValue)message->method;
			return (this->*method)(value);
		}
	}
	return kTTErrMethodNotFound;
}

#if 0
#pragma mark -
#pragma mark Observing
#endif

TTErr TTObject::registerObserverForMessage(const TTObject& observingObject, const TTSymbolPtr messageName)
{
	return kTTErrGeneric;
}

TTErr TTObject::registerObserverForAttribute(const TTObject& observingObject, const TTSymbolPtr attributeName)
{
	return kTTErrGeneric;
}

TTErr TTObject::registerObserverForNotifications(const TTObject& observingObject)
{
	TTValuePtr v = new TTValue(observingObject);
	observers->appendUnique(v);
	return kTTErrNone;
}

TTErr TTObject::unregisterObserverForMessage(const TTObject& observingObject, const TTSymbolPtr messageName)
{
	return kTTErrGeneric;
}

TTErr TTObject::unregisterObserverForAttribute(const TTObject& observingObject, const TTSymbolPtr attributeName)
{
	return kTTErrGeneric;
}

TTErr TTObject::unregisterObserverForNotifications(const TTObject& observingObject)
{
	TTValue	c(observingObject);
	TTValue	v;
	TTErr	err;

	err = observers->findEquals(c, v);
	if(!err)
		observers->remove(v);
	return err;
}

#if 0
#pragma mark -
#pragma mark Logging
#endif

/**	Log messages scoped to this object instance. */
TTErr TTObject::logMessage(TTImmutableCString fmtstring, ...)
{
	char	str[4096];
	char	fullstr[4096];
	va_list	ap;

	va_start(ap, fmtstring);
	vsnprintf(str, 4000, fmtstring, ap);
	va_end(ap);
	str[4095] = 0;

	strncpy(fullstr, classPtr->name->getCString(), 4095);
	strncat(fullstr, " : ", 4095);
	strncat(fullstr, str, 4095);
	TTLogMessage(fullstr);
	return kTTErrNone;
}

TTErr TTObject::logWarning(TTImmutableCString fmtstring, ...)
{
	char	str[4096];
	char	fullstr[4096];
	va_list	ap;

	va_start(ap, fmtstring);
	vsnprintf(str, 4000, fmtstring, ap);
	va_end(ap);
	str[4095] = 0;

	strncpy(fullstr, classPtr->name->getCString(), 4095);
	strncat(fullstr, " : ", 4095);
	strncat(fullstr, str, 4095);
	TTLogWarning(fullstr);
	return kTTErrNone;
}

TTErr TTObject::logError(TTImmutableCString fmtstring, ...)
{
	char	str[4096];
	char	fullstr[4096];
	va_list	ap;

	va_start(ap, fmtstring);
	vsnprintf(str, 4000, fmtstring, ap);
	va_end(ap);
	str[4095] = 0;

	strncpy(fullstr, classPtr->name->getCString(), 4095);
	strncat(fullstr, " : ", 4095);
	strncat(fullstr, str, 4095);
	TTLogError(fullstr);
	return kTTErrNone;
}

TTErr TTObject::logDebug(TTImmutableCString fmtstring, ...)
{
	if(ttEnvironment->debugBasic){
		char	str[4000];
		char	fullstr[4096];
		va_list	ap;

		va_start(ap, fmtstring);
		vsnprintf(str, 4000, fmtstring, ap);
		va_end(ap);
		str[4095] = 0;

		strncpy(fullstr, classPtr->name->getCString(), 4095);
		strncat(fullstr, " : ", 4095);
		strncat(fullstr, str, 4095);
		TTLogDebug(fullstr);
	}
	return kTTErrNone;
}

<commit_msg>fix for crash: out of bounds writing to a string in TTObject<commit_after>/*
 * TTBlue Object Base Class
 * Copyright © 2008, Timothy Place
 *
 * License: This code is licensed under the terms of the GNU LGPL
 * http://www.gnu.org/licenses/lgpl.html
 */

#include "TTObject.h"
#include "TTEnvironment.h"
#include "TTClass.h"

TTObject::TTObject(TTValue& arguments)
	: classPtr(NULL), observers(NULL), messageObservers(NULL), attributeObservers(NULL),
	  locked(false), referenceCount(1), valid(false), reserved1(0), reserved2(0)
{
	messages = new TTHash;
	attributes = new TTHash;
	observers = new TTList;
	// 'valid' will be set true by the Environment class which is the factory for all objects
}

TTObject::~TTObject()
{
	TTValue	v, u;

	delete observers;

	// Delete message objects, then delete the hash that maintains them.
	messages->getKeys(v);
	for(TTUInt16 i=0; i<v.getSize(); i++){
		TTSymbol*	name = NULL;
		TTMessage*	message = NULL;

		v.get(i, &name);
		messages->lookup(name, u);
		message = TTMessagePtr(TTPtr(u));
		delete message;
	}
	delete messages;

	// Delete attribute objects, then delete the hash that maintains them.
	attributes->getKeys(v);
	for(TTUInt16 i=0; i<v.getSize(); i++){
		TTSymbol*		name = NULL;
		TTAttribute*	attribute = NULL;

		v.get(i, &name);
		attributes->lookup(name, u);
		attribute = TTAttributePtr(TTPtr(u));
		delete attribute;
	}
	delete attributes;
}

#if 0
#pragma mark -
#pragma mark Object Attributes
#endif

TTErr TTObject::registerAttribute(const TTSymbolPtr name, TTDataType type, void* address)
{
	TTAttribute* newAttribute = new TTAttribute(name, type, address);

	newAttribute->setGetterFlags(kTTAttrPassObject);
	newAttribute->setSetterFlags(kTTAttrPassObject);
	attributes->append(name, TTPtr(newAttribute));
	return kTTErrNone;
}

TTErr TTObject::registerAttribute(const TTSymbolPtr name, TTDataType type, void* address, TTGetterMethod getter)
{
	TTAttribute* newAttribute = new TTAttribute(name, type, address, getter);

	newAttribute->setSetterFlags(kTTAttrPassObject);
	attributes->append(name, TTPtr(newAttribute));
	return kTTErrNone;
}

TTErr TTObject::registerAttribute(const TTSymbolPtr name, TTDataType type, void* address, TTSetterMethod setter)
{
	TTAttribute* newAttribute = new TTAttribute(name, type, address, setter);

	newAttribute->setGetterFlags(kTTAttrPassObject);
	attributes->append(name, TTPtr(newAttribute));
	return kTTErrNone;
}

TTErr TTObject::registerAttribute(const TTSymbolPtr name, TTDataType type, void* address, TTGetterMethod getter, TTSetterMethod setter)
{
	TTAttribute* newAttribute = new TTAttribute(name, type, address, getter, setter);

	attributes->append(name, TTPtr(newAttribute));
	return kTTErrNone;
}

TTErr TTObject::findAttribute(const TTSymbolPtr name, TTAttribute** attr)
{
	TTValue v;
	TTErr	err = kTTErrNone;

	err = attributes->lookup(TTSymbolPtr(name), v);
	if(!err){
		*attr = TTAttributePtr(TTPtr(v));
		return kTTErrNone;
	}
	else
		return kTTErrInvalidAttribute;
}

TTErr TTObject::getAttributeValue(const TTSymbolPtr name, TTValue& value)
{
	TTAttributePtr	attribute;
	TTErr			err;

	err = findAttribute(name, &attribute);
	if(!err){
		if(attribute->getterFlags & kTTAttrPassObject)
			err = (this->*attribute->getter)(*attribute, value);
		else{
			TTMethodValue getter = (TTMethodValue)attribute->getter;
			err = (this->*getter)(value);
		}
	}

	return err;
}

TTErr TTObject::setAttributeValue(const TTSymbolPtr name, TTValue& value)
{
	TTAttributePtr	attribute;
	TTErr			err;

	err = findAttribute(name, &attribute);
	if(!err){
		if(attribute->readOnly)
			err = kTTErrReadOnly;
		else{
			if(attribute->rangeChecking == TT("clip"))
				value.clip(attribute->rangeLowBound, attribute->rangeHighBound);
			else if(attribute->rangeChecking == TT("cliplow"))
				value.cliplow(attribute->rangeLowBound);
			else if(attribute->rangeChecking == TT("cliphigh"))
				value.cliphigh(attribute->rangeHighBound);

			if(attribute->setterFlags & kTTAttrPassObject)
				err = (this->*attribute->setter)(*attribute, value);
			else{
				TTMethodConstValue setter = (TTMethodConstValue)attribute->setter;
				err = (this->*setter)(value);
			}
		}
	}
	return err;
}

TTErr TTObject::getAttributeGetterFlags(const TTSymbolPtr name, TTAttributeFlags& value)
{
	TTAttributePtr	attribute;
	TTErr			err;

	err = findAttribute(name, &attribute);
	if(!err)
		attribute->getGetterFlags(value);

	return err;
}

TTErr TTObject::setAttributeGetterFlags(const TTSymbolPtr name, TTAttributeFlags& value)
{
	TTAttributePtr	attribute;
	TTErr			err;

	err = findAttribute(name, &attribute);
	if(!err)
		attribute->setGetterFlags(value);

	return err;
}

TTErr TTObject::getAttributeSetterFlags(const TTSymbolPtr name, TTAttributeFlags& value)
{
	TTAttributePtr	attribute;
	TTErr			err;

	err = findAttribute(name, &attribute);
	if(!err)
		attribute->getSetterFlags(value);

	return err;
}

TTErr TTObject::setAttributeSetterFlags(const TTSymbolPtr name, TTAttributeFlags& value)
{
	TTAttributePtr	attribute;
	TTErr			err;

	err = findAttribute(name, &attribute);
	if(!err)
		attribute->setSetterFlags(value);

	return err;
}

void TTObject::getAttributeNames(TTValue& attributeNameList)
{
	attributes->getKeys(attributeNameList);
}

TTErr TTObject::registerAttributeProperty(const TTSymbolPtr attributeName, const TTSymbolPtr propertyName, const TTValue& initialValue, TTGetterMethod getter, TTSetterMethod setter)
{
	TTAttributePtr	theAttr = NULL;
	TTValue			v;
	TTErr			err;

	err = attributes->lookup(attributeName, v);
	if(!err){
		theAttr = TTAttributePtr(TTPtr(v));
		err = theAttr->registerAttribute(propertyName, kTypeLocalValue, NULL, getter, setter);
		theAttr->setAttributeValue(propertyName, (TTValue&)initialValue);
	}
	return err;
}

void TTObject::getMessageNames(TTValue& messageNameList)
{
	messages->getKeys(messageNameList);
}

TTSymbol* TTObject::getName() const
{
	return classPtr->name;
}

#if 0
#pragma mark -
#pragma mark Object Messages
#endif

TTErr TTObject::registerMessage(const TTSymbolPtr name, TTMethod method)
{
	TTMessagePtr newMessage = new TTMessage(name, method, kTTMessageDefaultFlags);

	if(ttEnvironment && ttEnvironment->debugMessaging)
		logMessage("Registering Message '%s' with flags = %ld, message count for this object is now %ld\n", name->getCString(), kTTMessageDefaultFlags, messages->getSize());

	messages->append(name, TTPtr(newMessage));
	return kTTErrNone;
}

TTErr TTObject::registerMessage(const TTSymbolPtr name, TTMethod method, TTMessageFlags flags)
{
	TTMessagePtr newMessage = new TTMessage(name, method, flags);

	if(ttEnvironment->debugMessaging)
		logMessage("Registering Message '%s' with flags = %ld, message count for this object is now %ld\n", name->getCString(), kTTMessageDefaultFlags, messages->getSize());

	messages->append(name, TTPtr(newMessage));
	return kTTErrNone;
}

TTErr TTObject::findMessage(const TTSymbolPtr name, TTMessage** message)
{
	TTValue v;
	TTErr	err = kTTErrNone;

	err = messages->lookup(TTSymbolPtr(name), v);
	if(!err){
		*message = TTMessagePtr(TTPtr(v));
		return kTTErrNone;
	}
	else
		return kTTErrInvalidAttribute;
}

TTErr TTObject::sendMessage(const TTSymbolPtr name)
{
	TTValue	v;
	return sendMessage(name, v);
}

TTErr TTObject::sendMessage(const TTSymbolPtr name, TTValue& value)
{
	TTMessagePtr	message;
	TTErr			err;

	err = findMessage(name, &message);
	if(!err){
		if(message->flags & kTTMessagePassNone){
			TTMethodNone method = (TTMethodNone)message->method;
			return (this->*method)();
		}
		else if(message->flags & kTTMessagePassNameAndValue){
			return (this->*message->method)(name, value);
		}
		else{	// default is kTTMessagePassValue
			TTMethodValue method = (TTMethodValue)message->method;
			return (this->*method)(value);
		}
	}
	return kTTErrMethodNotFound;
}

#if 0
#pragma mark -
#pragma mark Observing
#endif

TTErr TTObject::registerObserverForMessage(const TTObject& observingObject, const TTSymbolPtr messageName)
{
	return kTTErrGeneric;
}

TTErr TTObject::registerObserverForAttribute(const TTObject& observingObject, const TTSymbolPtr attributeName)
{
	return kTTErrGeneric;
}

TTErr TTObject::registerObserverForNotifications(const TTObject& observingObject)
{
	TTValuePtr v = new TTValue(observingObject);
	observers->appendUnique(v);
	return kTTErrNone;
}

TTErr TTObject::unregisterObserverForMessage(const TTObject& observingObject, const TTSymbolPtr messageName)
{
	return kTTErrGeneric;
}

TTErr TTObject::unregisterObserverForAttribute(const TTObject& observingObject, const TTSymbolPtr attributeName)
{
	return kTTErrGeneric;
}

TTErr TTObject::unregisterObserverForNotifications(const TTObject& observingObject)
{
	TTValue	c(observingObject);
	TTValue	v;
	TTErr	err;

	err = observers->findEquals(c, v);
	if(!err)
		observers->remove(v);
	return err;
}

#if 0
#pragma mark -
#pragma mark Logging
#endif

/**	Log messages scoped to this object instance. */
TTErr TTObject::logMessage(TTImmutableCString fmtstring, ...)
{
	char	str[4096];
	char	fullstr[4096];
	va_list	ap;

	va_start(ap, fmtstring);
	vsnprintf(str, 4000, fmtstring, ap);
	va_end(ap);
	str[4095] = 0;

	strncpy(fullstr, classPtr->name->getCString(), 4095);
	strncat(fullstr, " : ", 4095);
	strncat(fullstr, str, 4095);
	TTLogMessage(fullstr);
	return kTTErrNone;
}

TTErr TTObject::logWarning(TTImmutableCString fmtstring, ...)
{
	char	str[4096];
	char	fullstr[4096];
	va_list	ap;

	va_start(ap, fmtstring);
	vsnprintf(str, 4000, fmtstring, ap);
	va_end(ap);
	str[4095] = 0;

	strncpy(fullstr, classPtr->name->getCString(), 4095);
	strncat(fullstr, " : ", 4095);
	strncat(fullstr, str, 4095);
	TTLogWarning(fullstr);
	return kTTErrNone;
}

TTErr TTObject::logError(TTImmutableCString fmtstring, ...)
{
	char	str[4096];
	char	fullstr[4096];
	va_list	ap;

	va_start(ap, fmtstring);
	vsnprintf(str, 4000, fmtstring, ap);
	va_end(ap);
	str[4095] = 0;

	strncpy(fullstr, classPtr->name->getCString(), 4095);
	strncat(fullstr, " : ", 4095);
	strncat(fullstr, str, 4095);
	TTLogError(fullstr);
	return kTTErrNone;
}

TTErr TTObject::logDebug(TTImmutableCString fmtstring, ...)
{
	if(ttEnvironment->debugBasic){
		char	str[4096];
		char	fullstr[4096];
		va_list	ap;

		va_start(ap, fmtstring);
		vsnprintf(str, 4000, fmtstring, ap);
		va_end(ap);
		str[4095] = 0;

		strncpy(fullstr, classPtr->name->getCString(), 4095);
		strncat(fullstr, " : ", 4095);
		strncat(fullstr, str, 4095);
		TTLogDebug(fullstr);
	}
	return kTTErrNone;
}

<|endoftext|>