Commit 5d41346b authored by Roger Dingledine's avatar Roger Dingledine
Browse files

prevent servers from publishing an internal IP as their address


svn:r1272
parent f55ff5b8
Loading
Loading
Loading
Loading
+45 −33
Original line number Diff line number Diff line
@@ -345,6 +345,49 @@ static void print_usage(void) {
         );
}

int resolve_my_address(or_options_t *options) {
  struct in_addr in;
  struct hostent *rent;
  char localhostname[256];

  if(!options->Address) { /* then we need to guess our address */

    if(gethostname(localhostname,sizeof(localhostname)) < 0) {
      log_fn(LOG_WARN,"Error obtaining local hostname");
      return -1;
    }
#if 0 /* don't worry about complaining, as long as it resolves */
    if(!strchr(localhostname,'.')) {
      log_fn(LOG_WARN,"fqdn '%s' has only one element. Misconfigured machine?",address);
      log_fn(LOG_WARN,"Try setting the Address line in your config file.");
      return -1;
    }
#endif
    options->Address = tor_strdup(localhostname);
    log_fn(LOG_DEBUG,"Guessed local host name as '%s'",options->Address);
  }

  /* now we know options->Address is set. resolve it and keep only the IP */

  rent = (struct hostent *)gethostbyname(options->Address);
  if (!rent) {
    log_fn(LOG_WARN,"Could not resolve Address %s. Failing.", options->Address);
    return -1;
  }
  assert(rent->h_length == 4);
  memcpy(&in.s_addr, rent->h_addr,rent->h_length);
  if(is_internal_IP(in.s_addr)) {
    log_fn(LOG_WARN,"Address '%s' resolves to '%s'. "
           "Please set the Address config option to be your public IP.",
           options->Address, inet_ntoa(in));
    return -1;
  }
  tor_free(options->Address);
  options->Address = tor_strdup(inet_ntoa(in));
  log_fn(LOG_DEBUG,"Resolved Address to %s.", options->Address);
  return 0;
}

static void free_options(or_options_t *options) {
  tor_free(options->LogLevel);
  tor_free(options->LogFile);
@@ -525,39 +568,8 @@ int getconfig(int argc, char **argv, or_options_t *options) {
  }

  if(options->ORPort) { /* get an IP for ourselves */
    struct in_addr in;
    struct hostent *rent;
    char localhostname[256];

    if(!options->Address) { /* then we need to guess our address */

      if(gethostname(localhostname,sizeof(localhostname)) < 0) {
        log_fn(LOG_WARN,"Error obtaining local hostname");
        return -1;
      }
#if 0 /* don't worry about complaining, as long as it resolves */
      if(!strchr(localhostname,'.')) {
        log_fn(LOG_WARN,"fqdn '%s' has only one element. Misconfigured machine?",address);
        log_fn(LOG_WARN,"Try setting the Address line in your config file.");
        return -1;
      }
#endif
      options->Address = tor_strdup(localhostname);
      log_fn(LOG_DEBUG,"Guessed local host name as '%s'",options->Address);
    }

    /* now we know options->Address is set. resolve it and keep only the IP */

    rent = (struct hostent *)gethostbyname(options->Address);
    if (!rent) {
      log_fn(LOG_WARN,"Could not resolve Address %s. Failing.", options->Address);
      return -1;
    }
    assert(rent->h_length == 4);
    memcpy(&in.s_addr, rent->h_addr,rent->h_length);
    tor_free(options->Address);
    options->Address = tor_strdup(inet_ntoa(in));
    log_fn(LOG_DEBUG,"Resolved Address to %s.", options->Address);
    if(resolve_my_address(options) < 0)
      result = -1;
  }

  if(options->SocksPort < 0) {