예제 #1
0
/** Write the persistent state to disk. Return 0 for success, <0 on failure. */
int
or_state_save(time_t now)
{
  char *state, *contents;
  char tbuf[ISO_TIME_LEN+1];
  char *fname;

  tor_assert(global_state);

  if (global_state->next_write > now)
    return 0;

  /* Call everything else that might dirty the state even more, in order
   * to avoid redundant writes. */
  entry_guards_update_state(global_state);
  rep_hist_update_state(global_state);
  circuit_build_times_update_state(&circ_times, global_state);
  if (accounting_is_enabled(get_options()))
    accounting_run_housekeeping(now);

  global_state->LastWritten = now;

  tor_free(global_state->TorVersion);
  tor_asprintf(&global_state->TorVersion, "Tor %s", get_version());

  state = config_dump(&state_format, NULL, global_state, 1, 0);
  format_local_iso_time(tbuf, now);
  tor_asprintf(&contents,
               "# Tor state file last generated on %s local time\n"
               "# Other times below are in GMT\n"
               "# You *do not* need to edit this file.\n\n%s",
               tbuf, state);
  tor_free(state);
  fname = get_datadir_fname("state");
  if (write_str_to_file(fname, contents, 0)<0) {
    log_warn(LD_FS, "Unable to write state to file \"%s\"; "
             "will try again later", fname);
    last_state_file_write_failed = 1;
    tor_free(fname);
    tor_free(contents);
    /* Try again after STATE_WRITE_RETRY_INTERVAL (or sooner, if the state
     * changes sooner). */
    global_state->next_write = now + STATE_WRITE_RETRY_INTERVAL;
    return -1;
  }

  last_state_file_write_failed = 0;
  log_info(LD_GENERAL, "Saved state to \"%s\"", fname);
  tor_free(fname);
  tor_free(contents);

  if (server_mode(get_options()))
    global_state->next_write = now + STATE_RELAY_CHECKPOINT_INTERVAL;
  else
    global_state->next_write = TIME_MAX;

  return 0;
}
예제 #2
0
파일: util_bug.c 프로젝트: nmathewson/Tor
tor_bug_occurred_(const char *fname, unsigned int line,
                  const char *func, const char *expr,
                  int once, const char *fmt, ...)
{
  char *buf = NULL;
  const char *once_str = once ?
    " (Future instances of this warning will be silenced.)": "";
  if (! expr) {
    if (capturing_bugs()) {
      add_captured_bug("This line should not have been reached.");
      return;
    }
    log_warn(LD_BUG, "%s:%u: %s: This line should not have been reached.%s",
             fname, line, func, once_str);
    tor_asprintf(&buf,
                 "Line unexpectedly reached at %s at %s:%u",
                 func, fname, line);
  } else {
    if (capturing_bugs()) {
      add_captured_bug(expr);
      return;
    }

    va_list ap;
    char *extra = NULL;

#ifdef __clang__
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wformat-nonliteral"
#endif
    if (fmt) {
      va_start(ap,fmt);
      tor_vasprintf(&extra, fmt, ap);
      va_end(ap);
    }
#ifdef __clang__
#pragma clang diagnostic pop
#endif

    log_warn(LD_BUG, "%s:%u: %s: Non-fatal assertion %s failed.%s",
             fname, line, func, expr, once_str);
    tor_asprintf(&buf, "Non-fatal assertion %s failed in %s at %s:%u%s%s",
                 expr, func, fname, line, fmt ? " : " : "",
                 extra ? extra : "");
    tor_free(extra);
  }
  log_backtrace(LOG_WARN, LD_BUG, buf);
  tor_free(buf);

#ifdef TOR_UNIT_TESTS
  if (failed_assertion_cb) {
    failed_assertion_cb();
  }
#endif
}
예제 #3
0
/** Set up code to handle generating error messages on crashes. */
int
configure_backtrace_handler(const char *tor_version)
{
  tor_free(bt_version);
  if (tor_version)
    tor_asprintf(&bt_version, "Tor %s", tor_version);
  else
    tor_asprintf(&bt_version, "Tor");

  return install_bt_handler();
}
예제 #4
0
static void
test_storagedir_deletion(void *arg)
{
  (void)arg;
  char *dirname = tor_strdup(get_fname_rnd("store_dir"));
  storage_dir_t *d = NULL;
  char *fn1 = NULL, *fn2 = NULL;
  char *bytes = NULL;
  int r;
  const char str1[] = "There are nine and sixty ways to disguise communiques";
  const char str2[] = "And rather more than one of them is right";

  // Make sure the directory is there. */
  d = storage_dir_new(dirname, 10);
  storage_dir_free(d);
  d = NULL;

  tor_asprintf(&fn1, "%s/1007", dirname);
  r = write_str_to_file(fn1, str1, 0);
  tt_int_op(r, OP_EQ, 0);

  tor_asprintf(&fn2, "%s/1003.tmp", dirname);
  r = write_str_to_file(fn2, str2, 0);
  tt_int_op(r, OP_EQ, 0);

  // The tempfile should be deleted the next time we list the directory.
  d = storage_dir_new(dirname, 10);
  tt_int_op(1, OP_EQ, smartlist_len(storage_dir_list(d)));
  tt_u64_op(strlen(str1), OP_EQ, storage_dir_get_usage(d));
  tt_int_op(FN_FILE, OP_EQ, file_status(fn1));
  tt_int_op(FN_NOENT, OP_EQ, file_status(fn2));

  bytes = (char*) storage_dir_read(d, "1007", 1, NULL);
  tt_str_op(bytes, OP_EQ, str1);

  // Should have no effect; file already gone.
  storage_dir_remove_file(d, "1003.tmp");
  tt_int_op(1, OP_EQ, smartlist_len(storage_dir_list(d)));
  tt_u64_op(strlen(str1), OP_EQ, storage_dir_get_usage(d));

  // Actually remove a file.
  storage_dir_remove_file(d, "1007");
  tt_int_op(FN_NOENT, OP_EQ, file_status(fn1));
  tt_int_op(0, OP_EQ, smartlist_len(storage_dir_list(d)));
  tt_u64_op(0, OP_EQ, storage_dir_get_usage(d));

 done:
  tor_free(dirname);
  tor_free(fn1);
  tor_free(fn2);
  storage_dir_free(d);
  tor_free(bytes);
}
예제 #5
0
파일: ntmain.c 프로젝트: Lab414/30May
/** Build a formatted command line used for the NT service. Return a
 * pointer to the formatted string on success, or NULL on failure.  Set
 * *<b>using_default_torrc</b> to true if we're going to use the default
 * location to torrc, or 1 if an option was specified on the command line.
 */
static char *
nt_service_command_line(int *using_default_torrc)
{
  TCHAR tor_exe[MAX_PATH+1];
  char tor_exe_ascii[MAX_PATH*2+1];
  char *command=NULL, *options=NULL;
  smartlist_t *sl;
  int i;
  *using_default_torrc = 1;

  /* Get the location of tor.exe */
  if (0 == GetModuleFileName(NULL, tor_exe, MAX_PATH))
    return NULL;

  /* Get the service arguments */
  sl = smartlist_new();
  for (i = 1; i < backup_argc; ++i) {
    if (!strcmp(backup_argv[i], "--options") ||
        !strcmp(backup_argv[i], "-options")) {
      while (++i < backup_argc) {
        if (!strcmp(backup_argv[i], "-f"))
          *using_default_torrc = 0;
        smartlist_add(sl, backup_argv[i]);
      }
    }
  }
  if (smartlist_len(sl))
    options = smartlist_join_strings(sl,"\" \"",0,NULL);
  smartlist_free(sl);

#ifdef UNICODE
  wcstombs(tor_exe_ascii, tor_exe, sizeof(tor_exe_ascii));
  tor_exe_ascii[sizeof(tor_exe_ascii)-1] = '\0';
#else
  strlcpy(tor_exe_ascii, tor_exe, sizeof(tor_exe_ascii));
#endif

  /* Allocate a string for the NT service command line and */
  /* Format the service command */
  if (options) {
    tor_asprintf(&command, "\"%s\" --nt-service \"%s\"",
                 tor_exe_ascii, options);
  } else { /* ! options */
    tor_asprintf(&command, "\"%s\" --nt-service", tor_exe_ascii);
  }

  tor_free(options);
  return command;
}
예제 #6
0
static void
test_md_corrupt_desc(void *arg)
{
  char *cp = NULL;
  smartlist_t *sl = NULL;
  (void) arg;

  sl = microdescs_add_to_cache(get_microdesc_cache(),
                               "@last-listed 2015-06-22 10:00:00\n"
                               "onion-k\n",
                               NULL, SAVED_IN_JOURNAL, 0, time(NULL), NULL);
  tt_int_op(smartlist_len(sl), OP_EQ, 0);
  smartlist_free(sl);

  sl = microdescs_add_to_cache(get_microdesc_cache(),
                               "@last-listed 2015-06-22 10:00:00\n"
                               "wiggly\n",
                               NULL, SAVED_IN_JOURNAL, 0, time(NULL), NULL);
  tt_int_op(smartlist_len(sl), OP_EQ, 0);
  smartlist_free(sl);

  tor_asprintf(&cp, "%s\n%s", test_md1, "@foobar\nonion-wobble\n");

  sl = microdescs_add_to_cache(get_microdesc_cache(),
                               cp, cp+strlen(cp),
                               SAVED_IN_JOURNAL, 0, time(NULL), NULL);
  tt_int_op(smartlist_len(sl), OP_EQ, 0);

 done:
  tor_free(cp);
  smartlist_free(sl);
}
예제 #7
0
파일: util_bug.c 프로젝트: nmathewson/Tor
tor_assertion_failed_(const char *fname, unsigned int line,
                      const char *func, const char *expr,
                      const char *fmt, ...)
{
  char *buf = NULL;
  char *extra = NULL;
  va_list ap;

#ifdef __clang__
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wformat-nonliteral"
#endif
  if (fmt) {
    va_start(ap,fmt);
    tor_vasprintf(&extra, fmt, ap);
    va_end(ap);
  }
#ifdef __clang__
#pragma clang diagnostic pop
#endif

  log_err(LD_BUG, "%s:%u: %s: Assertion %s failed; aborting.",
          fname, line, func, expr);
  tor_asprintf(&buf, "Assertion %s failed in %s at %s:%u: %s",
               expr, func, fname, line, extra ? extra : "");
  tor_free(extra);
  log_backtrace(LOG_ERR, LD_BUG, buf);
  tor_free(buf);
}
예제 #8
0
/**
 * Save a broken state file to a backup location.
 */
static void
or_state_save_broken(char *fname)
{
  int i;
  file_status_t status;
  char *fname2 = NULL;
  for (i = 0; i < 100; ++i) {
    tor_asprintf(&fname2, "%s.%d", fname, i);
    status = file_status(fname2);
    if (status == FN_NOENT)
      break;
    tor_free(fname2);
  }
  if (i == 100) {
    log_warn(LD_BUG, "Unable to parse state in \"%s\"; too many saved bad "
             "state files to move aside. Discarding the old state file.",
             fname);
    unlink(fname);
  } else {
    log_warn(LD_BUG, "Unable to parse state in \"%s\". Moving it aside "
             "to \"%s\".  This could be a bug in Tor; please tell "
             "the developers.", fname, fname2);
    if (rename(fname, fname2) < 0) {
      log_warn(LD_BUG, "Weirdly, I couldn't even move the state aside. The "
               "OS gave an error of %s", strerror(errno));
    }
  }
  tor_free(fname2);
}
예제 #9
0
파일: voteflags.c 프로젝트: unixninja92/Tor
/** Give a statement of our current performance thresholds for inclusion
 * in a vote document. */
char *
dirserv_get_flag_thresholds_line(void)
{
  char *result=NULL;
  const int measured_threshold =
    get_options()->MinMeasuredBWsForAuthToIgnoreAdvertised;
  const int enough_measured_bw =
    dirserv_get_last_n_measured_bws() > measured_threshold;

  tor_asprintf(&result,
      "stable-uptime=%lu stable-mtbf=%lu "
      "fast-speed=%lu "
      "guard-wfu=%.03f%% guard-tk=%lu "
      "guard-bw-inc-exits=%lu guard-bw-exc-exits=%lu "
      "enough-mtbf=%d ignoring-advertised-bws=%d",
      (unsigned long)stable_uptime,
      (unsigned long)stable_mtbf,
      (unsigned long)fast_bandwidth_kb*1000,
      guard_wfu*100,
      (unsigned long)guard_tk,
      (unsigned long)guard_bandwidth_including_exits_kb*1000,
      (unsigned long)guard_bandwidth_excluding_exits_kb*1000,
      enough_mtbf_info ? 1 : 0,
      enough_measured_bw ? 1 : 0);

  return result;
}
예제 #10
0
static void
test_md_cache_broken(void *data)
{
  or_options_t *options;
  char *fn=NULL;
  microdesc_cache_t *mc = NULL;

  (void)data;

  options = get_options_mutable();
  tt_assert(options);
  tor_free(options->CacheDirectory);
  options->CacheDirectory = tor_strdup(get_fname("md_datadir_test2"));

#ifdef _WIN32
  tt_int_op(0, OP_EQ, mkdir(options->CacheDirectory));
#else
  tt_int_op(0, OP_EQ, mkdir(options->CacheDirectory, 0700));
#endif

  tor_asprintf(&fn, "%s"PATH_SEPARATOR"cached-microdescs",
               options->CacheDirectory);

  write_str_to_file(fn, truncated_md, 1);

  mc = get_microdesc_cache();
  tt_assert(mc);

 done:
  if (options)
    tor_free(options->CacheDirectory);
  tor_free(fn);
  microdesc_free_all();
}
예제 #11
0
static char *
fmt_coord(msg_aux_data_t d)
{
  char *v;
  struct coord *c = d.ptr;
  tor_asprintf(&v, "[%d, %d]", c->x, c->y);
  return v;
}
예제 #12
0
파일: hibernate.c 프로젝트: ChatSecure/tor
/** Helper function: called when we get a GETINFO request for an
 * accounting-related key on the control connection <b>conn</b>.  If we can
 * answer the request for <b>question</b>, then set *<b>answer</b> to a newly
 * allocated string holding the result.  Otherwise, set *<b>answer</b> to
 * NULL. */
int
getinfo_helper_accounting(control_connection_t *conn,
                          const char *question, char **answer,
                          const char **errmsg)
{
  (void) conn;
  (void) errmsg;
  if (!strcmp(question, "accounting/enabled")) {
    *answer = tor_strdup(accounting_is_enabled(get_options()) ? "1" : "0");
  } else if (!strcmp(question, "accounting/hibernating")) {
    if (hibernate_state == HIBERNATE_STATE_DORMANT)
      *answer = tor_strdup("hard");
    else if (hibernate_state == HIBERNATE_STATE_LOWBANDWIDTH)
      *answer = tor_strdup("soft");
    else
      *answer = tor_strdup("awake");
  } else if (!strcmp(question, "accounting/bytes")) {
    tor_asprintf(answer, U64_FORMAT" "U64_FORMAT,
                 U64_PRINTF_ARG(n_bytes_read_in_interval),
                 U64_PRINTF_ARG(n_bytes_written_in_interval));
  } else if (!strcmp(question, "accounting/bytes-left")) {
    uint64_t limit = get_options()->AccountingMax;
    uint64_t read_left = 0, write_left = 0;
    if (n_bytes_read_in_interval < limit)
      read_left = limit - n_bytes_read_in_interval;
    if (n_bytes_written_in_interval < limit)
      write_left = limit - n_bytes_written_in_interval;
    tor_asprintf(answer, U64_FORMAT" "U64_FORMAT,
                 U64_PRINTF_ARG(read_left), U64_PRINTF_ARG(write_left));
  } else if (!strcmp(question, "accounting/interval-start")) {
    *answer = tor_malloc(ISO_TIME_LEN+1);
    format_iso_time(*answer, interval_start_time);
  } else if (!strcmp(question, "accounting/interval-wake")) {
    *answer = tor_malloc(ISO_TIME_LEN+1);
    format_iso_time(*answer, interval_wakeup_time);
  } else if (!strcmp(question, "accounting/interval-end")) {
    *answer = tor_malloc(ISO_TIME_LEN+1);
    format_iso_time(*answer, interval_end_time);
  } else {
    *answer = NULL;
  }
  return 0;
}
예제 #13
0
파일: shared_random.c 프로젝트: Samdney/tor
/* Return a heap allocated string that contains the given <b>srv</b> string
 * representation formatted for a networkstatus document using the
 * <b>key</b> as the start of the line. This doesn't return NULL. */
static char *
srv_to_ns_string(const sr_srv_t *srv, const char *key)
{
  char *srv_str;
  char srv_hash_encoded[SR_SRV_VALUE_BASE64_LEN + 1];
  tor_assert(srv);
  tor_assert(key);

  sr_srv_encode(srv_hash_encoded, sizeof(srv_hash_encoded), srv);
  tor_asprintf(&srv_str, "%s %" PRIu64 " %s\n", key,
               srv->num_reveals, srv_hash_encoded);
  log_debug(LD_DIR, "SR: Consensus SRV line: %s", srv_str);
  return srv_str;
}
예제 #14
0
파일: shared_random.c 프로젝트: Samdney/tor
/* Using <b>commit</b>, return a newly allocated string containing the commit
 * information that should be used during SRV calculation. It's the caller
 * responsibility to free the memory. Return NULL if this is not a commit to be
 * used for SRV calculation. */
static char *
get_srv_element_from_commit(const sr_commit_t *commit)
{
  char *element;
  tor_assert(commit);

  if (!commit_has_reveal_value(commit)) {
    return NULL;
  }

  tor_asprintf(&element, "%s%s", sr_commit_get_rsa_fpr(commit),
               commit->encoded_reveal);
  return element;
}
예제 #15
0
파일: shared_random.c 프로젝트: Samdney/tor
/* Given <b>commit</b> give the line that we should place in our votes.
 * It's the responsibility of the caller to free the string. */
static char *
get_vote_line_from_commit(const sr_commit_t *commit, sr_phase_t phase)
{
  char *vote_line = NULL;

  switch (phase) {
  case SR_PHASE_COMMIT:
    tor_asprintf(&vote_line, "%s %u %s %s %s\n",
                 commit_ns_str,
                 SR_PROTO_VERSION,
                 crypto_digest_algorithm_get_name(commit->alg),
                 sr_commit_get_rsa_fpr(commit),
                 commit->encoded_commit);
    break;
  case SR_PHASE_REVEAL:
  {
    /* Send a reveal value for this commit if we have one. */
    const char *reveal_str = commit->encoded_reveal;
    if (tor_mem_is_zero(commit->encoded_reveal,
                        sizeof(commit->encoded_reveal))) {
      reveal_str = "";
    }
    tor_asprintf(&vote_line, "%s %u %s %s %s %s\n",
                 commit_ns_str,
                 SR_PROTO_VERSION,
                 crypto_digest_algorithm_get_name(commit->alg),
                 sr_commit_get_rsa_fpr(commit),
                 commit->encoded_commit, reveal_str);
    break;
  }
  default:
    tor_assert(0);
  }

  log_debug(LD_DIR, "SR: Commit vote line: %s", vote_line);
  return vote_line;
}
예제 #16
0
/** Return a newly allocated string holding the address described in
 * <b>sa</b>.  AF_UNIX, AF_UNSPEC, AF_INET, and AF_INET6 are supported. */
char *
tor_sockaddr_to_str(const struct sockaddr *sa)
{
  char address[TOR_ADDR_BUF_LEN];
  char *result;
  tor_addr_t addr;
  uint16_t port;
#ifdef HAVE_SYS_UN_H
  if (sa->sa_family == AF_UNIX) {
    struct sockaddr_un *s_un = (struct sockaddr_un *)sa;
    tor_asprintf(&result, "unix:%s", s_un->sun_path);
    return result;
  }
#endif
  if (sa->sa_family == AF_UNSPEC)
    return tor_strdup("unspec");

  if (tor_addr_from_sockaddr(&addr, sa, &port) < 0)
    return NULL;
  if (! tor_addr_to_str(address, &addr, sizeof(address), 1))
    return NULL;
  tor_asprintf(&result, "%s:%d", address, (int)port);
  return result;
}
예제 #17
0
/* From a valid srv object and an allocated config line, set the line's
 * value to the state string representation of a shared random value. */
static void
disk_state_put_srv_line(const sr_srv_t *srv, config_line_t *line)
{
  char encoded[SR_SRV_VALUE_BASE64_LEN + 1];

  tor_assert(line);

  /* No SRV value thus don't add the line. This is possible since we might
   * not have a current or previous SRV value in our state. */
  if (srv == NULL) {
    return;
  }
  sr_srv_encode(encoded, sizeof(encoded), srv);
  tor_asprintf(&line->value, "%" PRIu64 " %s", srv->num_reveals, encoded);
}
예제 #18
0
/* From a valid commit object and an allocated config line, set the line's
 * value to the state string representation of a commit. */
static void
disk_state_put_commit_line(const sr_commit_t *commit, config_line_t *line)
{
  char *reveal_str = NULL;

  tor_assert(commit);
  tor_assert(line);

  if (!tor_mem_is_zero(commit->encoded_reveal,
                       sizeof(commit->encoded_reveal))) {
    /* Add extra whitespace so we can format the line correctly. */
    tor_asprintf(&reveal_str, " %s", commit->encoded_reveal);
  }
  tor_asprintf(&line->value, "%u %s %s %s%s",
               SR_PROTO_VERSION,
               crypto_digest_algorithm_get_name(commit->alg),
               sr_commit_get_rsa_fpr(commit),
               commit->encoded_commit,
               reveal_str != NULL ? reveal_str : "");
  if (reveal_str != NULL) {
    memwipe(reveal_str, 0, strlen(reveal_str));
    tor_free(reveal_str);
  }
}
예제 #19
0
/** Take seconds <b>secs</b> and return a newly allocated human-readable
 * uptime string */
static char *
secs_to_uptime(long secs)
{
  long int days = secs / 86400;
  int hours = (int)((secs - (days * 86400)) / 3600);
  int minutes = (int)((secs - (days * 86400) - (hours * 3600)) / 60);
  char *uptime_string = NULL;

  switch (days) {
  case 0:
    tor_asprintf(&uptime_string, "%d:%02d hours", hours, minutes);
    break;
  case 1:
    tor_asprintf(&uptime_string, "%ld day %d:%02d hours",
                 days, hours, minutes);
    break;
  default:
    tor_asprintf(&uptime_string, "%ld days %d:%02d hours",
                 days, hours, minutes);
    break;
  }

  return uptime_string;
}
예제 #20
0
/** Print a spec-conformant string to stdout describing the results of
 *  the TCP port forwarding operation from <b>external_port</b> to
 *  <b>internal_port</b>. */
static void
tor_fw_helper_report_port_fw_results(uint16_t internal_port,
                                     uint16_t external_port,
                                     int succeded,
                                     const char *message)
{
    char *report_string = NULL;

    tor_asprintf(&report_string, "%s %s %u %u %s %s\n",
                 "tor-fw-helper",
                 "tcp-forward",
                 external_port, internal_port,
                 succeded ? "SUCCESS" : "FAIL",
                 message);
    fprintf(stdout, "%s", report_string);
    fflush(stdout);
    tor_free(report_string);
}
예제 #21
0
/** Unregister all TrackHostExits mappings from any address to
 * *.exitname.exit. */
void
clear_trackexithost_mappings(const char *exitname)
{
  char *suffix = NULL;
  if (!addressmap || !exitname)
    return;
  tor_asprintf(&suffix, ".%s.exit", exitname);
  tor_strlower(suffix);

  STRMAP_FOREACH_MODIFY(addressmap, address, addressmap_entry_t *, ent) {
    if (ent->source == ADDRMAPSRC_TRACKEXIT &&
        !strcmpend(ent->new_address, suffix)) {
      addressmap_ent_remove(address, ent);
      MAP_DEL_CURRENT(address);
    }
  } STRMAP_FOREACH_END;

  tor_free(suffix);
}
예제 #22
0
/* Save the disk state to disk but before that update it from the current
 * state so we always have the latest. Return 0 on success else -1. */
static int
disk_state_save_to_disk(void)
{
  int ret;
  char *state, *content = NULL, *fname = NULL;
  char tbuf[ISO_TIME_LEN + 1];
  time_t now = time(NULL);

  /* If we didn't have the opportunity to setup an internal disk state,
   * don't bother saving something to disk. */
  if (sr_disk_state == NULL) {
    ret = 0;
    goto done;
  }

  /* Make sure that our disk state is up to date with our memory state
   * before saving it to disk. */
  disk_state_update();
  state = config_dump(&state_format, NULL, sr_disk_state, 0, 0);
  format_local_iso_time(tbuf, now);
  tor_asprintf(&content,
               "# Tor shared random state file last generated on %s "
               "local time\n"
               "# Other times below are in UTC\n"
               "# Please *do not* edit this file.\n\n%s",
               tbuf, state);
  tor_free(state);
  fname = get_datadir_fname(default_fname);
  if (write_str_to_file(fname, content, 0) < 0) {
    log_warn(LD_FS, "SR: Unable to write SR state to file %s", fname);
    ret = -1;
    goto done;
  }
  ret = 0;
  log_debug(LD_DIR, "SR: Saved state to file %s", fname);

 done:
  tor_free(fname);
  tor_free(content);
  return ret;
}
예제 #23
0
/** Return a string containing the address:port that a proxy transport
 *  should bind on. The string is stored on the heap and must be freed
 *  by the caller of this function. */
char *
get_stored_bindaddr_for_server_transport(const char *transport)
{
  char *default_addrport = NULL;
  const char *stored_bindaddr = NULL;

  config_line_t *line = get_transport_in_state_by_name(transport);
  if (!line) /* Found no references in state for this transport. */
    goto no_bindaddr_found;

  stored_bindaddr = get_transport_bindaddr(line->value, transport);
  if (stored_bindaddr) /* found stored bindaddr in state file. */
    return tor_strdup(stored_bindaddr);

 no_bindaddr_found:
  /** If we didn't find references for this pluggable transport in the
      state file, we should instruct the pluggable transport proxy to
      listen on INADDR_ANY on a random ephemeral port. */
  tor_asprintf(&default_addrport, "%s:%s", fmt_addr32(INADDR_ANY), "0");
  return default_addrport;
}
예제 #24
0
파일: test_entrynodes.c 프로젝트: adoll/tor
/** Append some EntryGuard lines to the Tor state at <b>state</b>.

   <b>entry_guard_lines</b> is a smartlist containing 2-tuple
   smartlists that carry the key and values of the statefile.
   As an example:
   entry_guard_lines =
     (("EntryGuard", "name 67E72FF33D7D41BF11C569646A0A7B4B188340DF DirCache"),
      ("EntryGuardDownSince", "2014-06-07 16:02:46 2014-06-07 16:02:46"))
*/
static void
state_insert_entry_guard_helper(or_state_t *state,
                                smartlist_t *entry_guard_lines)
{
  config_line_t **next, *line;

  next = &state->EntryGuards;
  *next = NULL;

  /* Loop over all the state lines in the smartlist */
  SMARTLIST_FOREACH_BEGIN(entry_guard_lines, const smartlist_t *,state_lines) {
    /* Get key and value for each line */
    const char *state_key = smartlist_get(state_lines, 0);
    const char *state_value = smartlist_get(state_lines, 1);

    *next = line = tor_malloc_zero(sizeof(config_line_t));
    line->key = tor_strdup(state_key);
    tor_asprintf(&line->value, "%s", state_value);
    next = &(line->next);
  } SMARTLIST_FOREACH_END(state_lines);
}
예제 #25
0
/**
 * Output a histogram of current circuit build times to
 * the or_state_t state structure.
 */
void
circuit_build_times_update_state(circuit_build_times_t *cbt,
                                 or_state_t *state)
{
  uint32_t *histogram;
  build_time_t i = 0;
  build_time_t nbins = 0;
  config_line_t **next, *line;

  histogram = circuit_build_times_create_histogram(cbt, &nbins);
  // write to state
  config_free_lines(state->BuildtimeHistogram);
  next = &state->BuildtimeHistogram;
  *next = NULL;

  state->TotalBuildTimes = cbt->total_build_times;
  state->CircuitBuildAbandonedCount = 0;

  for (i = 0; i < CBT_NCIRCUITS_TO_OBSERVE; i++) {
    if (cbt->circuit_build_times[i] == CBT_BUILD_ABANDONED)
      state->CircuitBuildAbandonedCount++;
  }

  for (i = 0; i < nbins; i++) {
    // compress the histogram by skipping the blanks
    if (histogram[i] == 0) continue;
    *next = line = tor_malloc_zero(sizeof(config_line_t));
    line->key = tor_strdup("CircuitBuildTimeBin");
    tor_asprintf(&line->value, "%d %d",
            CBT_BIN_TO_MS(i), histogram[i]);
    next = &(line->next);
  }

  if (!unit_tests) {
    if (!get_options()->AvoidDiskWrites)
      or_state_mark_dirty(get_or_state(), 0);
  }

  tor_free(histogram);
}
예제 #26
0
/** Return string containing the address:port part of the
 *  TransportProxy <b>line</b> for transport <b>transport</b>.
 *  If the line is corrupted, return NULL. */
static const char *
get_transport_bindaddr(const char *line, const char *transport)
{
  char *line_tmp = NULL;

  if (strlen(line) < strlen(transport) + 2) {
    goto broken_state;
  } else {
    /* line should start with the name of the transport and a space.
       (for example, "obfs2 127.0.0.1:47245") */
    tor_asprintf(&line_tmp, "%s ", transport);
    if (strcmpstart(line, line_tmp))
      goto broken_state;

    tor_free(line_tmp);
    return (line+strlen(transport)+1);
  }

 broken_state:
  tor_free(line_tmp);
  return NULL;
}
예제 #27
0
파일: test.c 프로젝트: phplaboratory/tor
/* Remove a directory and all of its subdirectories */
static void
rm_rf(const char *dir)
{
  struct stat st;
  smartlist_t *elements;

  elements = tor_listdir(dir);
  if (elements) {
    SMARTLIST_FOREACH_BEGIN(elements, const char *, cp) {
         char *tmp = NULL;
         tor_asprintf(&tmp, "%s"PATH_SEPARATOR"%s", dir, cp);
         if (0 == stat(tmp,&st) && (st.st_mode & S_IFDIR)) {
           rm_rf(tmp);
         } else {
           if (unlink(tmp)) {
             fprintf(stderr, "Error removing %s: %s\n", tmp, strerror(errno));
           }
         }
         tor_free(tmp);
    } SMARTLIST_FOREACH_END(cp);
    SMARTLIST_FOREACH(elements, char *, cp, tor_free(cp));
    smartlist_free(elements);
  }
예제 #28
0
static void
test_routerkeys_write_fingerprint(void *arg)
{
  crypto_pk_t *key = pk_generate(2);
  or_options_t *options = get_options_mutable();
  const char *ddir = get_fname("write_fingerprint");
  char *cp = NULL, *cp2 = NULL;
  char fp[FINGERPRINT_LEN+1];

  (void)arg;

  tt_assert(key);

  options->ORPort_set = 1; /* So that we can get the server ID key */
  tor_free(options->DataDirectory);
  options->DataDirectory = tor_strdup(ddir);
  options->Nickname = tor_strdup("haflinger");
  set_server_identity_key(key);
  set_client_identity_key(crypto_pk_dup_key(key));

  tt_int_op(0, OP_EQ, check_private_dir(ddir, CPD_CREATE, NULL));
  tt_int_op(crypto_pk_cmp_keys(get_server_identity_key(),key),OP_EQ,0);

  /* Write fingerprint file */
  tt_int_op(0, OP_EQ, router_write_fingerprint(0));
  cp = read_file_to_str(get_fname("write_fingerprint/fingerprint"),
                        0, NULL);
  crypto_pk_get_fingerprint(key, fp, 0);
  tor_asprintf(&cp2, "haflinger %s\n", fp);
  tt_str_op(cp, OP_EQ, cp2);
  tor_free(cp);
  tor_free(cp2);

  /* Write hashed-fingerprint file */
  tt_int_op(0, OP_EQ, router_write_fingerprint(1));
  cp = read_file_to_str(get_fname("write_fingerprint/hashed-fingerprint"),
                        0, NULL);
  crypto_pk_get_hashed_fingerprint(key, fp);
  tor_asprintf(&cp2, "haflinger %s\n", fp);
  tt_str_op(cp, OP_EQ, cp2);
  tor_free(cp);
  tor_free(cp2);

  /* Replace outdated file */
  write_str_to_file(get_fname("write_fingerprint/hashed-fingerprint"),
                    "junk goes here", 0);
  tt_int_op(0, OP_EQ, router_write_fingerprint(1));
  cp = read_file_to_str(get_fname("write_fingerprint/hashed-fingerprint"),
                        0, NULL);
  crypto_pk_get_hashed_fingerprint(key, fp);
  tor_asprintf(&cp2, "haflinger %s\n", fp);
  tt_str_op(cp, OP_EQ, cp2);
  tor_free(cp);
  tor_free(cp2);

 done:
  crypto_pk_free(key);
  set_client_identity_key(NULL);
  tor_free(cp);
  tor_free(cp2);
}
예제 #29
0
파일: confparse.c 프로젝트: Archer-sys/tor
/** <b>c</b>-\>key is known to be a real key. Update <b>options</b>
 * with <b>c</b>-\>value and return 0, or return -1 if bad value.
 *
 * Called from config_assign_line() and option_reset().
 */
static int
config_assign_value(const config_format_t *fmt, void *options,
                    config_line_t *c, char **msg)
{
  int i, ok;
  const config_var_t *var;
  void *lvalue;
  int *csv_int;
  smartlist_t *csv_str;

  CONFIG_CHECK(fmt, options);

  var = config_find_option(fmt, c->key);
  tor_assert(var);

  lvalue = STRUCT_VAR_P(options, var->var_offset);

  switch (var->type) {

  case CONFIG_TYPE_PORT:
    if (!strcasecmp(c->value, "auto")) {
      *(int *)lvalue = CFG_AUTO_PORT;
      break;
    }
    /* fall through */
  case CONFIG_TYPE_INT:
  case CONFIG_TYPE_UINT:
    i = (int)tor_parse_long(c->value, 10,
                            var->type==CONFIG_TYPE_INT ? INT_MIN : 0,
                            var->type==CONFIG_TYPE_PORT ? 65535 : INT_MAX,
                            &ok, NULL);
    if (!ok) {
      tor_asprintf(msg,
          "Int keyword '%s %s' is malformed or out of bounds.",
          c->key, c->value);
      return -1;
    }
    *(int *)lvalue = i;
    break;

  case CONFIG_TYPE_INTERVAL: {
    i = config_parse_interval(c->value, &ok);
    if (!ok) {
      tor_asprintf(msg,
          "Interval '%s %s' is malformed or out of bounds.",
          c->key, c->value);
      return -1;
    }
    *(int *)lvalue = i;
    break;
  }

  case CONFIG_TYPE_MSEC_INTERVAL: {
    i = config_parse_msec_interval(c->value, &ok);
    if (!ok) {
      tor_asprintf(msg,
          "Msec interval '%s %s' is malformed or out of bounds.",
          c->key, c->value);
      return -1;
    }
    *(int *)lvalue = i;
    break;
  }

  case CONFIG_TYPE_MEMUNIT: {
    uint64_t u64 = config_parse_memunit(c->value, &ok);
    if (!ok) {
      tor_asprintf(msg,
          "Value '%s %s' is malformed or out of bounds.",
          c->key, c->value);
      return -1;
    }
    *(uint64_t *)lvalue = u64;
    break;
  }

  case CONFIG_TYPE_BOOL:
    i = (int)tor_parse_long(c->value, 10, 0, 1, &ok, NULL);
    if (!ok) {
      tor_asprintf(msg,
          "Boolean '%s %s' expects 0 or 1.",
          c->key, c->value);
      return -1;
    }
    *(int *)lvalue = i;
    break;

  case CONFIG_TYPE_AUTOBOOL:
    if (!strcmp(c->value, "auto"))
      *(int *)lvalue = -1;
    else if (!strcmp(c->value, "0"))
      *(int *)lvalue = 0;
    else if (!strcmp(c->value, "1"))
      *(int *)lvalue = 1;
    else {
      tor_asprintf(msg, "Boolean '%s %s' expects 0, 1, or 'auto'.",
                   c->key, c->value);
      return -1;
    }
    break;

  case CONFIG_TYPE_STRING:
  case CONFIG_TYPE_FILENAME:
    tor_free(*(char **)lvalue);
    *(char **)lvalue = tor_strdup(c->value);
    break;

  case CONFIG_TYPE_DOUBLE:
    *(double *)lvalue = atof(c->value);
    break;

  case CONFIG_TYPE_ISOTIME:
    if (parse_iso_time(c->value, (time_t *)lvalue)) {
      tor_asprintf(msg,
          "Invalid time '%s' for keyword '%s'", c->value, c->key);
      return -1;
    }
    break;

  case CONFIG_TYPE_ROUTERSET:
    if (*(routerset_t**)lvalue) {
      routerset_free(*(routerset_t**)lvalue);
    }
    *(routerset_t**)lvalue = routerset_new();
    if (routerset_parse(*(routerset_t**)lvalue, c->value, c->key)<0) {
      tor_asprintf(msg, "Invalid exit list '%s' for option '%s'",
                   c->value, c->key);
      return -1;
    }
    break;

  case CONFIG_TYPE_CSV:
    if (*(smartlist_t**)lvalue) {
      SMARTLIST_FOREACH(*(smartlist_t**)lvalue, char *, cp, tor_free(cp));
      smartlist_clear(*(smartlist_t**)lvalue);
    } else {
예제 #30
0
/**
 * Generate a routerstatus for v3_networkstatus test.
 */
vote_routerstatus_t *
dir_common_gen_routerstatus_for_v3ns(int idx, time_t now)
{
  vote_routerstatus_t *vrs=NULL;
  routerstatus_t *rs = NULL;
  tor_addr_t addr_ipv6;
  char *method_list = NULL;

  switch (idx) {
    case 0:
      /* Generate the first routerstatus. */
      vrs = tor_malloc_zero(sizeof(vote_routerstatus_t));
      rs = &vrs->status;
      vrs->version = tor_strdup("0.1.2.14");
      rs->published_on = now-1500;
      strlcpy(rs->nickname, "router2", sizeof(rs->nickname));
      memset(rs->identity_digest, TEST_DIR_ROUTER_ID_1, DIGEST_LEN);
      memset(rs->descriptor_digest, TEST_DIR_ROUTER_DD_1, DIGEST_LEN);
      rs->addr = 0x99008801;
      rs->or_port = 443;
      rs->dir_port = 8000;
      /* all flags but running and v2dir cleared */
      rs->is_flagged_running = 1;
      rs->is_v2_dir = 1;
      break;
    case 1:
      /* Generate the second routerstatus. */
      vrs = tor_malloc_zero(sizeof(vote_routerstatus_t));
      rs = &vrs->status;
      vrs->version = tor_strdup("0.2.0.5");
      rs->published_on = now-1000;
      strlcpy(rs->nickname, "router1", sizeof(rs->nickname));
      memset(rs->identity_digest, TEST_DIR_ROUTER_ID_2, DIGEST_LEN);
      memset(rs->descriptor_digest, TEST_DIR_ROUTER_DD_2, DIGEST_LEN);
      rs->addr = 0x99009901;
      rs->or_port = 443;
      rs->dir_port = 0;
      tor_addr_parse(&addr_ipv6, "[1:2:3::4]");
      tor_addr_copy(&rs->ipv6_addr, &addr_ipv6);
      rs->ipv6_orport = 4711;
      rs->is_exit = rs->is_stable = rs->is_fast = rs->is_flagged_running =
        rs->is_valid = rs->is_possible_guard = rs->is_v2_dir = 1;
      break;
    case 2:
      /* Generate the third routerstatus. */
      vrs = tor_malloc_zero(sizeof(vote_routerstatus_t));
      rs = &vrs->status;
      vrs->version = tor_strdup("0.1.0.3");
      rs->published_on = now-1000;
      strlcpy(rs->nickname, "router3", sizeof(rs->nickname));
      memset(rs->identity_digest, TEST_DIR_ROUTER_ID_3, DIGEST_LEN);
      memset(rs->descriptor_digest, TEST_DIR_ROUTER_DD_3, DIGEST_LEN);
      rs->addr = 0xAA009901;
      rs->or_port = 400;
      rs->dir_port = 9999;
      rs->is_authority = rs->is_exit = rs->is_stable = rs->is_fast =
        rs->is_flagged_running = rs->is_valid = rs->is_v2_dir =
        rs->is_possible_guard = 1;
      break;
    case 3:
      /* Generate a fourth routerstatus that is not running. */
      vrs = tor_malloc_zero(sizeof(vote_routerstatus_t));
      rs = &vrs->status;
      vrs->version = tor_strdup("0.1.6.3");
      rs->published_on = now-1000;
      strlcpy(rs->nickname, "router4", sizeof(rs->nickname));
      memset(rs->identity_digest, TEST_DIR_ROUTER_ID_4, DIGEST_LEN);
      memset(rs->descriptor_digest, TEST_DIR_ROUTER_DD_4, DIGEST_LEN);
      rs->addr = 0xC0000203;
      rs->or_port = 500;
      rs->dir_port = 1999;
      rs->is_v2_dir = 1;
      /* Running flag (and others) cleared */
      break;
    case 4:
      /* No more for this test; return NULL */
      vrs = NULL;
      break;
    default:
      /* Shouldn't happen */
      tt_assert(0);
  }
  if (vrs) {
    vrs->microdesc = tor_malloc_zero(sizeof(vote_microdesc_hash_t));
    method_list = make_consensus_method_list(MIN_SUPPORTED_CONSENSUS_METHOD,
                                             MAX_SUPPORTED_CONSENSUS_METHOD,
                                             ",");
    tor_asprintf(&vrs->microdesc->microdesc_hash_line,
                 "m %s "
                 "sha256=xyzajkldsdsajdadlsdjaslsdksdjlsdjsdaskdaaa%d\n",
                 method_list, idx);
  }

 done:
  tor_free(method_list);
  return vrs;
}