Exemple #1
0
void
mc_log(const char *fmt, ...)
{
	va_list args;
	FILE *f;
	char *logfilename;

	if (is_logging_enabled()) {
		va_start(args, fmt);
		logfilename = g_strdup_printf("%s/.mc/log", home_dir);
		if ((f = fopen(logfilename, "a")) != NULL) {
			(void)vfprintf(f, fmt, args);
			(void)fclose(f);
		}
		g_free(logfilename);
	}
}
Exemple #2
0
bool netcat_resolvehost(nc_host_t *dst, const char *name)
{
  int i;
  struct hostent *hostent;
  struct in_addr res_addr;
#ifdef USE_IPV6
  struct in6_addr res6_addr;
#endif

  assert(name && name[0]);
  debug_v(("netcat_resolvehost(dst=%p, name=\"%s\")", (void *)dst, name));

  /* reset all fields of the dst struct */
  memset(dst, 0, sizeof(*dst));

  /* try to see if `name' is a numeric address, in case try reverse lookup */
  if (netcat_inet_pton(AF_INET, name, &res_addr)) {
    memcpy(&dst->host.iaddrs[0], &res_addr, sizeof(dst->host.iaddrs[0]));
    strncpy(dst->host.addrs[0], netcat_inet_ntop(AF_INET, &res_addr), sizeof(dst->host.addrs[0]));

    /* if opt_numeric is set or we don't require verbosity, we are done */
    if (opt_numeric)
      return TRUE;

    /* failures to look up a PTR record are *not* considered fatal */
    hostent = gethostbyaddr((char *)&res_addr, sizeof(res_addr), AF_INET);
    if (!hostent)
      ncprint(NCPRINT_VERB2 | NCPRINT_WARNING,
	      _("Inverse name lookup failed for `%s'"), name);
    else {
      strncpy(dst->host.name, hostent->h_name, MAXHOSTNAMELEN - 2);
      /* now do the direct lookup to see if the PTR was authoritative */
      hostent = gethostbyname(dst->host.name);

      /* Any kind of failure in this section results in a host not auth
         warning, and the dst->host.name field cleaned (I don't care if there is a
         PTR, if it's unauthoritative). */
      if (!hostent || !hostent->h_addr_list[0]) {
	ncprint(NCPRINT_VERB1 | NCPRINT_WARNING,
		_("Host %s isn't authoritative! (direct lookup failed)"),
		dst->host.addrs[0]);
	goto check_failed;
      }
      for (i = 0; hostent->h_addr_list[i] && (i < MAXINETADDRS); i++)
	if (!memcmp(&dst->host.iaddrs[0], hostent->h_addr_list[i],
		    sizeof(dst->host.iaddrs[0])))
	  return TRUE;		/* resolving verified, it's AUTH */

      ncprint(NCPRINT_VERB1 | NCPRINT_WARNING,
	      _("Host %s isn't authoritative! (direct lookup mismatch)"),
	      dst->host.addrs[0]);
      ncprint(NCPRINT_VERB1, _("  %s -> %s  BUT  %s -> %s"),
	      dst->host.addrs[0], dst->host.name, dst->host.name,
	      netcat_inet_ntop(AF_INET, hostent->h_addr_list[0]));

 check_failed:
      memset(dst->host.name, 0, sizeof(dst->host.name));
    }				/* if hostent */
  }
#ifdef USE_IPV6
  /* same as above, but check for an IPv6 address notation */
  else if (netcat_inet_pton(AF_INET6, name, &res6_addr)) {
    memcpy(&dst->host6.iaddrs[0], &res6_addr, sizeof(dst->host6.iaddrs[0]));
    strncpy(dst->host6.addrs[0], netcat_inet_ntop(AF_INET6, &res_addr), sizeof(dst->host6.addrs[0]));

    /* if opt_numeric is set or we don't require verbosity, we are done */
    if (opt_numeric)
      return TRUE;
  }
#endif
  else {			/* couldn't translate: it must be a name! */
    bool host_auth_taken = FALSE;

    /* if the opt_numeric option is set, we must not use DNS in any way */
    if (opt_numeric)
      return FALSE;

    /* failures to look up a name are reported to the calling function */
    if (!(hostent = gethostbyname(name)))
      return FALSE;

    /* now I need to handle the host aliases (CNAME).  If we lookup host
       www.bighost.foo, which is an alias for www.bighost.mux.foo, the hostent
       struct will contain the real name in h_name, which is not what we want
       for the output purpose (the user doesn't want to see something he didn't
       type.  So assume the lookup name as the "official" name and fetch the
       ips for the reverse lookup. */
    debug(("(lookup) lookup=\"%s\" official=\"%s\" (should match)\n", name,
	  hostent->h_name));
    strncpy(dst->host.name, name, MAXHOSTNAMELEN - 1);

    /* now save all the available ip addresses (no more than MAXINETADDRS) */
    for (i = 0; hostent->h_addr_list[i] && (i < MAXINETADDRS); i++) {
      memcpy(&dst->host.iaddrs[i], hostent->h_addr_list[i], sizeof(dst->host.iaddrs[0]));
      strncpy(dst->host.addrs[i], netcat_inet_ntop(AF_INET, &dst->host.iaddrs[i]),
	      sizeof(dst->host.addrs[0]));
    }				/* end of foreach addr, part A */

    /* for speed purposes, skip the authoritative checking if we haven't got
       any verbosity level set.  note that this will cause invalid results
       in the dst struct, but we don't care at this point. (FIXME: ?) */
    if (!is_logging_enabled())
      return TRUE;

    /* do inverse lookups in a separated loop for each collected addresses */
    for (i = 0; dst->host.iaddrs[i].s_addr && (i < MAXINETADDRS); i++) {
      hostent = gethostbyaddr((char *)&dst->host.iaddrs[i], sizeof(dst->host.iaddrs[0]),
			      AF_INET);

      if (!hostent || !hostent->h_name) {
	ncprint(NCPRINT_VERB1 | NCPRINT_WARNING,
		_("Inverse name lookup failed for `%s'"), dst->host.addrs[i]);
	continue;
      }

      /* now the case.  hostnames aren't case sensitive because of this we may
         find a different case for the authoritative hostname.  For the same
         previous reason we may want to keep the user typed case, but this time
         we are going to override it because this tool is a "network exploration
         tool", thus it's good to see the case they chose for this host. */
      if (strcasecmp(dst->host.name, hostent->h_name)) {
	int xcmp;
	char savedhost[MAXHOSTNAMELEN];

	/* refering to the flowchart (see the drafts directory contained in
	   this package), try to guess the real hostname */
	strncpy(savedhost, hostent->h_name, sizeof(savedhost));
	savedhost[sizeof(savedhost) - 1] = 0;

	/* ok actually the given host and the reverse-resolved address doesn't
	   match, so try to see if we can find the real machine name.  In order to
	   this to happen the originally found address must match with the newly
	   found hostname directly resolved.  If this doesn't, or if this resolve
	   fails, then fall back to the original warning message: they have a DNS
	   misconfigured! */
	hostent = gethostbyname(savedhost);
	if (!hostent)
	  continue;		/* FIXME: missing information analysis */

	for (xcmp = 0; hostent->h_addr_list[xcmp] &&
		(xcmp < MAXINETADDRS); xcmp++) {
	  if (!memcmp(&dst->host.iaddrs[i], hostent->h_addr_list[xcmp],
		     sizeof(dst->host.iaddrs[0])))
	    goto found_real_host;
	}

	ncprint(NCPRINT_WARNING | NCPRINT_VERB1,
		_("This host's reverse DNS doesn't match! %s -- %s"),
		hostent->h_name, dst->host.name);
	continue;

 found_real_host:
	ncprint(NCPRINT_NOTICE | NCPRINT_VERB2,
		_("Real hostname for %s [%s] is %s"),
		dst->host.name, dst->host.addrs[i], savedhost);
	continue;
      }
      else if (!host_auth_taken) {	/* case: take only the first one as auth */
	strncpy(dst->host.name, hostent->h_name, sizeof(dst->host.name));
	host_auth_taken = TRUE;
      }
    }				/* end of foreach addr, part B */
  }

  return TRUE;
}