tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

agent.cc (7797B)


      1 // Copyright 2022 The Chromium Authors.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 #include <algorithm>
      6 #include <fstream>
      7 #include <iostream>
      8 #include <string>
      9 #include <regex>
     10 #include <vector>
     11 
     12 #include "content_analysis/sdk/analysis_agent.h"
     13 #include "demo/handler.h"
     14 #include "demo/handler_misbehaving.h"
     15 
     16 using namespace content_analysis::sdk;
     17 
     18 // Different paths are used depending on whether this agent should run as a
     19 // use specific agent or not.  These values are chosen to match the test
     20 // values in chrome browser.
     21 constexpr char kPathUser[] = "path_user";
     22 constexpr char kPathSystem[] = "brcm_chrm_cas";
     23 
     24 // Global app config.
     25 std::string path = kPathSystem;
     26 bool use_queue = false;
     27 bool user_specific = false;
     28 std::vector<unsigned long> delays = {0};  // In milliseconds.
     29 unsigned long num_threads = 8u;
     30 std::string save_print_data_path = "";
     31 RegexArray toBlock, toWarn, toReport;
     32 static bool useMisbehavingHandler = false;
     33 static std::string modeStr;
     34 
     35 // Command line parameters.
     36 constexpr const char* kArgDelaySpecific = "--delays=";
     37 constexpr const char* kArgDelayMsSpecific = "--delaysMs=";
     38 constexpr const char* kArgPath = "--path=";
     39 constexpr const char* kArgQueued = "--queued";
     40 constexpr const char* kArgThreads = "--threads=";
     41 constexpr const char* kArgUserSpecific = "--user";
     42 constexpr const char* kArgToBlock = "--toblock=";
     43 constexpr const char* kArgToWarn = "--towarn=";
     44 constexpr const char* kArgToReport = "--toreport=";
     45 constexpr const char* kArgMisbehave = "--misbehave=";
     46 constexpr const char* kArgHelp = "--help";
     47 constexpr const char* kArgSavePrintRequestDataTo = "--save-print-request-data-to=";
     48 
     49 std::map<std::string, Mode> sStringToMode = {
     50 #define AGENT_MODE(name) {#name, Mode::Mode_##name},
     51 #include "modes.h"
     52 #undef AGENT_MODE
     53 };
     54 
     55 std::map<Mode, std::string> sModeToString = {
     56 #define AGENT_MODE(name) {Mode::Mode_##name, #name},
     57 #include "modes.h"
     58 #undef AGENT_MODE
     59 };
     60 
     61 std::vector<std::pair<std::string, std::regex>>
     62 ParseRegex(const std::string str) {
     63  std::vector<std::pair<std::string, std::regex>> ret;
     64  for (auto it = str.begin(); it != str.end(); /* nop */) {
     65    auto it2 = std::find(it, str.end(), ',');
     66    ret.push_back(std::make_pair(std::string(it, it2), std::regex(it, it2)));
     67    it = it2 == str.end() ? it2 : it2 + 1;
     68  }
     69 
     70  return ret;
     71 }
     72 
     73 bool ParseCommandLine(int argc, char* argv[]) {
     74  for (int i = 1; i < argc; ++i) {
     75    const std::string arg = argv[i];
     76    if (arg.find(kArgUserSpecific) == 0) {
     77      // If kArgPath was already used, abort.
     78      if (path != kPathSystem) {
     79        std::cout << std::endl << "ERROR: use --path=<path> after --user";
     80        return false;
     81      }
     82      path = kPathUser;
     83      user_specific = true;
     84    } else if ((arg.find(kArgDelaySpecific) == 0) ||
     85               (arg.find(kArgDelayMsSpecific) == 0)) {
     86      bool isSecs = (arg.find(kArgDelaySpecific) == 0);
     87      std::string delaysStr = arg.substr(strlen(isSecs ? kArgDelaySpecific : kArgDelayMsSpecific));
     88      unsigned long scale = isSecs ? 1000 : 1;
     89      delays.clear();
     90      size_t posStart = 0, posEnd;
     91      unsigned long delay;
     92      while ((posEnd = delaysStr.find(',', posStart)) != std::string::npos) {
     93        delay = std::stoul(delaysStr.substr(posStart, posEnd - posStart));
     94        delay = std::min(delay*scale, 30*1000ul);
     95        delays.push_back(delay);
     96        posStart = posEnd + 1;
     97      }
     98      delay = std::stoul(delaysStr.substr(posStart));
     99      delay = std::min(delay*scale, 30*1000ul);
    100      delays.push_back(delay);
    101    } else if (arg.find(kArgPath) == 0) {
    102      path = arg.substr(strlen(kArgPath));
    103    } else if (arg.find(kArgQueued) == 0) {
    104      use_queue = true;
    105    } else if (arg.find(kArgThreads) == 0) {
    106      num_threads = std::stoul(arg.substr(strlen(kArgThreads)));
    107    } else if (arg.find(kArgToBlock) == 0) {
    108      toBlock = ParseRegex(arg.substr(strlen(kArgToBlock)));
    109    } else if (arg.find(kArgToWarn) == 0) {
    110      toWarn = ParseRegex(arg.substr(strlen(kArgToWarn)));
    111    } else if (arg.find(kArgToReport) == 0) {
    112      toReport = ParseRegex(arg.substr(strlen(kArgToReport)));
    113    } else if (arg.find(kArgMisbehave) == 0) {
    114      modeStr = arg.substr(strlen(kArgMisbehave));
    115      useMisbehavingHandler = true;
    116    } else if (arg.find(kArgHelp) == 0) {
    117      return false;
    118    } else if (arg.find(kArgSavePrintRequestDataTo) == 0) {
    119      int arg_len = strlen(kArgSavePrintRequestDataTo);
    120      save_print_data_path = arg.substr(arg_len);
    121    }
    122  }
    123 
    124  return true;
    125 }
    126 
    127 void PrintHelp() {
    128  std::cout
    129    << std::endl << std::endl
    130    << "Usage: agent [OPTIONS]" << std::endl
    131    << "A simple agent to process content analysis requests." << std::endl
    132    << "Data containing the string 'block' blocks the request data from being used." << std::endl
    133    << std::endl << "Options:"  << std::endl
    134    << kArgDelaySpecific << "<delay1,delay2,...> : Add delays to request processing in seconds. Delays are limited to 30 seconds and are applied round-robin to requests. Default is 0." << std::endl
    135    << kArgDelayMsSpecific << "<delay1,delay2,...> : Like --delays but takes durations in milliseconds." << std::endl
    136    << kArgPath << " <path> : Used the specified path instead of default. Must come after --user." << std::endl
    137    << kArgQueued << " : Queue requests for processing in a background thread" << std::endl
    138    << kArgThreads << " : When queued, number of threads in the request processing thread pool" << std::endl
    139    << kArgUserSpecific << " : Make agent OS user specific." << std::endl
    140    << kArgHelp << " : prints this help message" << std::endl
    141    << kArgSavePrintRequestDataTo << " : saves the PDF data to the given file path for print requests" << std::endl
    142    << kArgToBlock << "<regex> : Regular expression matching file and text content to block." << std::endl
    143    << kArgToWarn << "<regex> : Regular expression matching file and text content to warn about." << std::endl
    144    << kArgToReport << "<regex> : Regular expression matching file and text content to report." << std::endl
    145    << kArgMisbehave << "<mode> : Use 'misbehaving' agent in given mode for testing purposes." << std::endl;
    146 }
    147 
    148 int main(int argc, char* argv[]) {
    149  if (!ParseCommandLine(argc, argv)) {
    150    PrintHelp();
    151    return 1;
    152  }
    153 
    154  auto handler =
    155    useMisbehavingHandler
    156      ? MisbehavingHandler::Create(modeStr, std::move(delays), save_print_data_path, std::move(toBlock), std::move(toWarn), std::move(toReport))
    157      : use_queue
    158        ? std::make_unique<QueuingHandler>(num_threads, std::move(delays), save_print_data_path, std::move(toBlock), std::move(toWarn), std::move(toReport))
    159        : std::make_unique<Handler>(std::move(delays), save_print_data_path, std::move(toBlock), std::move(toWarn), std::move(toReport));
    160 
    161  if (!handler) {
    162    std::cout << "[Demo] Failed to construct handler." << std::endl;
    163    return 1;
    164  }
    165 
    166  // Each agent uses a unique name to identify itself with Google Chrome.
    167  content_analysis::sdk::ResultCode rc;
    168  auto agent = content_analysis::sdk::Agent::Create(
    169      {path, user_specific}, std::move(handler), &rc);
    170  if (!agent || rc != content_analysis::sdk::ResultCode::OK) {
    171    std::cout << "[Demo] Error starting agent: "
    172              << content_analysis::sdk::ResultCodeToString(rc)
    173              << std::endl;
    174    return 1;
    175  };
    176 
    177  std::cout << "[Demo] " << agent->DebugString() << std::endl;
    178 
    179  // Blocks, sending events to the handler until agent->Stop() is called.
    180  rc = agent->HandleEvents();
    181  if (rc != content_analysis::sdk::ResultCode::OK) {
    182    std::cout << "[Demo] Error from handling events: "
    183              << content_analysis::sdk::ResultCodeToString(rc)
    184              << std::endl;
    185    std::cout << "[Demo] " << agent->DebugString() << std::endl;
    186  }
    187 
    188  return 0;
    189 }