Пример #1
0
static gboolean
afinet_dd_setup_addresses(AFSocketDestDriver *s)
{
  AFInetDestDriver *self = (AFInetDestDriver *) s;

  if (!afsocket_dd_setup_addresses_method(s))
    return FALSE;

  g_sockaddr_unref(self->super.bind_addr);
  g_sockaddr_unref(self->super.dest_addr);

  if (self->super.transport_mapper->address_family == AF_INET)
    {
      self->super.bind_addr = g_sockaddr_inet_new("0.0.0.0", 0);
      self->super.dest_addr = g_sockaddr_inet_new("0.0.0.0", 0);
    }
#if ENABLE_IPV6
  else if (self->super.transport_mapper->address_family == AF_INET6)
    {
      self->super.bind_addr = g_sockaddr_inet6_new("::", 0);
      self->super.dest_addr = g_sockaddr_inet6_new("::", 0);
    }
#endif
  else
    {
      /* address family not known */
      g_assert_not_reached();
    }

  if ((self->bind_ip && !resolve_hostname(&self->super.bind_addr, self->bind_ip)))
    return FALSE;

  if (!resolve_hostname(&self->super.dest_addr, self->hostname))
    return FALSE;

  if (!self->dest_port)
    {
      const gchar *port_change_warning = transport_mapper_inet_get_port_change_warning(self->super.transport_mapper);

      if (port_change_warning)
        {
          msg_warning(port_change_warning,
                      evt_tag_str("id", self->super.super.super.id),
                      NULL);
        }
      g_sockaddr_set_port(self->super.dest_addr, transport_mapper_inet_get_server_port(self->super.transport_mapper));
    }
  else
    g_sockaddr_set_port(self->super.dest_addr, afinet_lookup_service(self->super.transport_mapper, self->dest_port));

  return TRUE;
}
Пример #2
0
Файл: net.c Проект: mikekap/wine
BOOL netconn_resolve( WCHAR *hostname, INTERNET_PORT port, struct sockaddr *sa, socklen_t *sa_len, int timeout )
{
    DWORD ret;

    if (timeout)
    {
        DWORD status;
        HANDLE thread;
        struct resolve_args ra;

        ra.hostname = hostname;
        ra.port     = port;
        ra.sa       = sa;
        ra.sa_len   = sa_len;

        thread = CreateThread( NULL, 0, resolve_proc, &ra, 0, NULL );
        if (!thread) return FALSE;

        status = WaitForSingleObject( thread, timeout );
        if (status == WAIT_OBJECT_0) GetExitCodeThread( thread, &ret );
        else ret = ERROR_WINHTTP_TIMEOUT;
        CloseHandle( thread );
    }
    else ret = resolve_hostname( hostname, port, sa, sa_len );

    if (ret)
    {
        set_last_error( ret );
        return FALSE;
    }
    return TRUE;
}
Пример #3
0
int bacdl_connection_init(bacdl_connection_t *connection, char *tcp_host, uint16_t tcp_port, uint8_t port_id)
{
  int ret = 1;
  memset(connection, 0, sizeof(*connection));
  connection->tcp_host = tcp_host;
  connection->tcp_port = tcp_port;
  connection->port_id = port_id;

  buffer_init(&connection->send_buf, connection->send_buffer, BACDL_MAX_MESSAGE_LENGTH);
  buffer_init(&connection->rcv_buf, connection->rcv_buffer, BACDL_MAX_MESSAGE_LENGTH);

  struct sockaddr_in addr;
  addr.sin_family = AF_INET;
  addr.sin_port = htons((unsigned short)tcp_port);
  if(!resolve_hostname(tcp_host, &addr.sin_addr)) {
    error("failed to resolve hostname '%s'", tcp_host);
    ret = 0;
    goto done;
  }
  
  connection->socket = socket(AF_INET, SOCK_STREAM, 0);
  if(connection->socket < 0) {
    error("socket() call failed");
    ret = 0;
    goto done;
  }

  int nodelayflag = 1;
  setsockopt(connection->socket, IPPROTO_TCP, TCP_NODELAY, (char*)&nodelayflag, sizeof(int));

  if(connect(connection->socket, (struct sockaddr*)&addr, sizeof(addr)) < 0) {
    error("connect() call failed");
    ret = 0;
    goto done;
  }

  bacdl_msg_t msg;
  if(!bacdl_msg_init2(&msg, BACDL_MSG_CODE_PORT_ID)
    || !bacdl_port_id_msg_init(&msg.port_id, port_id)) {
    error("error initializing port_id message");
    ret = 0;
    goto done;
  }

  if(!bacdl_connection_send_msg(connection, &msg)) {
    error("error sending the port_id message");
    ret = 0;
    goto done;
  }

done:
  if(!ret) {
    if(connection->socket >= 0) {
      close(connection->socket);
      connection->socket = -1;
    }
  }

  return ret;
}
Пример #4
0
void
afinet_dd_set_localip(LogDriver *s, gchar *ip)
{
  AFInetDestDriver *self = (AFInetDestDriver *) s;

  resolve_hostname(&self->super.bind_addr, ip);
}
Пример #5
0
LogDriver *
afinet_sd_new(gint af, gchar *host, gint port, guint flags)
{
  AFInetSourceDriver *self = g_new0(AFInetSourceDriver, 1);

  afsocket_sd_init_instance(&self->super, &self->sock_options.super, flags);
  if (self->super.flags & AFSOCKET_DGRAM)
    self->super.transport = g_strdup("udp");
  else if (self->super.flags & AFSOCKET_STREAM)
    self->super.transport = g_strdup("tcp");
  if (af == AF_INET)
    {
      self->super.bind_addr = g_sockaddr_inet_new("0.0.0.0", port);
      if (!host)
        host = "0.0.0.0";
    }
  else
    {
#if ENABLE_IPV6
      self->super.bind_addr = g_sockaddr_inet6_new("::", port);
      if (!host)
        host = "::";
#else
      g_assert_not_reached();
#endif
    }
  resolve_hostname(&self->super.bind_addr, host);
  self->super.setup_socket = afinet_sd_setup_socket;

  return &self->super.super;
}
Пример #6
0
void
afinet_sd_set_localip(LogDriver *s, gchar *ip)
{
  AFSocketSourceDriver *self = (AFSocketSourceDriver *) s;

  resolve_hostname(&self->bind_addr, ip);
}
Пример #7
0
// get domain name and IP address of this host
//
int HOST_INFO::get_local_network_info() {
    struct sockaddr_storage s;
    
    strcpy(domain_name, "");
    strcpy(ip_addr, "");

    // it seems like we should use getdomainname() instead of gethostname(),
    // but on FC6 it returns "(none)".
    //
    if (gethostname(domain_name, 256)) {
        return ERR_GETHOSTBYNAME;
    }
    int retval = resolve_hostname(domain_name, s);
    if (retval) return retval;
#ifdef _WIN32
    sockaddr_in* sin = (sockaddr_in*)&s;
    strlcpy(ip_addr, inet_ntoa(sin->sin_addr), sizeof(ip_addr));
#else
    if (s.ss_family == AF_INET) {
        sockaddr_in* sin = (sockaddr_in*)&s;
        inet_ntop(AF_INET, (void*)(&sin->sin_addr), ip_addr, 256);
    } else {
        sockaddr_in6* sin = (sockaddr_in6*)&s;
        inet_ntop(AF_INET6, (void*)(&sin->sin6_addr), ip_addr, 256);
    }
#endif
    return 0;
}
Пример #8
0
/*
 * Setup some things about krb5.  This should only be called once.
 */
static void
krb5_init(void)
{
    static int beenhere = 0;
    char *p;
    char *myfqhostname=NULL;

    if (beenhere)
	return;
    beenhere = 1;

#ifndef BROKEN_MEMORY_CCACHE
    putenv(stralloc("KRB5_ENV_CCNAME=MEMORY:amanda_ccache"));
#else
    /*
     * MEMORY ccaches seem buggy and cause a lot of internal heap
     * corruption.  malloc has been known to core dump.  This behavior
     * has been witnessed in Cygnus' kerbnet 1.2, MIT's krb V 1.0.5 and
     * MIT's krb V -current as of 3/17/1999.
     *
     * We just use a lame ccache scheme with a uid suffix.
     */
    atexit(cleanup);
    {
	char *ccache;
	ccache = malloc(128);
	g_snprintf(ccache, SIZEOF(ccache),
		 "KRB5_ENV_CCNAME=FILE:/tmp/amanda_ccache.%ld.%ld",
		 (long)geteuid(), (long)getpid());
	putenv(ccache);
    }
#endif

    gethostname(myhostname, SIZEOF(myhostname) - 1);
    myhostname[SIZEOF(myhostname) - 1] = '\0';

    /*
     * In case it isn't fully qualified, do a DNS lookup.  Ignore
     * any errors (this is best-effort).
     */
    if (resolve_hostname(myhostname, SOCK_STREAM, NULL, &myfqhostname) == 0
	&& myfqhostname != NULL) {
	strncpy(myhostname, myfqhostname, SIZEOF(myhostname)-1);
	myhostname[SIZEOF(myhostname)-1] = '\0';
	amfree(myfqhostname);
    }

    /*
     * Lowercase the results.  We assume all host/ principals will be
     * lowercased.
     */
    for (p = myhostname; *p != '\0'; p++) {
	if (isupper((int)*p))
	    *p = tolower(*p);
    }
}
Пример #9
0
static gboolean
afinet_dd_setup_socket(AFSocketDestDriver *s, gint fd)
{
  AFInetDestDriver *self = (AFInetDestDriver *) s;

  if (!resolve_hostname(&self->super.dest_addr, self->super.hostname))
    return FALSE;

  return afinet_setup_socket(fd, self->super.dest_addr, (InetSocketOptions *) s->sock_options_ptr, AFSOCKET_DIR_SEND);
}
Пример #10
0
int zmq::tcp_address_t::resolve (const char *name_, bool local_, bool ipv4only_)
{
    //  Find the ':' at end that separates address from the port number.
    const char *delimiter = strrchr (name_, ':');
    if (!delimiter) {
        errno = EINVAL;
        return -1;
    }

    //  Separate the address/port.
    std::string addr_str (name_, delimiter - name_);
    std::string port_str (delimiter + 1);

    //  Remove square brackets around the address, if any.
    if (addr_str.size () >= 2 && addr_str [0] == '[' &&
          addr_str [addr_str.size () - 1] == ']')
        addr_str = addr_str.substr (1, addr_str.size () - 2);

    uint16_t port;
    //  Allow 0 specifically, to detect invalid port error in atoi if not
    if (port_str == "*" || port_str == "0")
        //  Resolve wildcard to 0 to allow autoselection of port
        port = 0;
    else {
        //  Parse the port number (0 is not a valid port).
        port = (uint16_t) atoi (port_str.c_str ());
        if (port == 0) {
            errno = EINVAL;
            return -1;
        }
    }

    //  Resolve the IP address.
    int rc;
    if (local_)
        rc = resolve_interface (addr_str.c_str (), ipv4only_);
    else
        rc = resolve_hostname (addr_str.c_str (), ipv4only_);
    if (rc != 0)
        return -1;

    //  Set the port into the address structure.
    if (address.generic.sa_family == AF_INET6)
        address.ipv6.sin6_port = htons (port);
    else
        address.ipv4.sin_port = htons (port);

    return 0;
}
Пример #11
0
// If host is a valid hostname, add its IP addresses to the list.
// Always add host itself to the list.
static void
ExpandHostAddresses(char const *host,StringList *list)
{
	list->append(host);
	condor_netaddr netaddr;

	if (strchr(host,'*') || strchr(host,'/') || netaddr.from_net_string(host)) {
		return; // not a valid hostname, so don't bother trying to look it up
	}

	std::vector<condor_sockaddr> addrs = resolve_hostname(host);
	for (std::vector<condor_sockaddr>::iterator iter = addrs.begin();
		 iter != addrs.end();
		 ++iter) {
		const condor_sockaddr& addr = *iter;
		list->append(addr.to_ip_string().Value());
	}
}
Пример #12
0
bool verify_name_has_ip(MyString name, condor_sockaddr addr){
	std::vector<condor_sockaddr> addrs;
	bool found = false;

	addrs = resolve_hostname(name);
	dprintf(D_FULLDEBUG, "IPVERIFY: checking %s against %s\n", name.Value(), addr.to_ip_string().Value());
	for(unsigned int i = 0; i < addrs.size(); i++) {
		// compare MyStrings
		// addr.to_ip_string
		if(addrs[i].to_ip_string() == addr.to_ip_string()) {
			dprintf(D_FULLDEBUG, "IPVERIFY: matched %s to %s\n", addrs[i].to_ip_string().Value(), addr.to_ip_string().Value());
			found = true;
		} else {
			dprintf(D_FULLDEBUG, "IPVERIFY: comparing %s to %s\n", addrs[i].to_ip_string().Value(), addr.to_ip_string().Value());
		}
	}
	dprintf(D_FULLDEBUG, "IPVERIFY: ip found is %i\n", found);

	return found;
}
Пример #13
0
void ci_connect(struct ci_connection *con)
{
        int sock;
        int con_res;
        error_t err;
        struct sockaddr_in* server = calloc(1, sizeof(*server));

        sock = socket(AF_INET, SOCK_STREAM, 0);
        if (sock == -1)
                perror("Creating socket");

        err = resolve_hostname(con->server.host, &con->server.ip);
        if (err != E_SUCCESS)
        {
                fprintf(stderr, "%s: %s\n", "Error connecting to IRC server",
                        err_desc[err].message);
                exit(1);
        }

        server->sin_addr.s_addr = inet_addr(con->server.ip);
        server->sin_port = htons((uint16_t)con->server.port);
        server->sin_family = AF_INET;

        con_res = connect(sock, (struct sockaddr*)server, sizeof(*server));
        if (con_res == -1)
                perror("Connecting to server");

        err = authenticate(sock, (struct sockaddr*)server, con);
        if (err != E_SUCCESS)
        {
                fprintf(stderr, "%s: %s\n", "Error connecting to IRC server",
                        err_desc[err].message);
                exit(1);
        }
        /* Start infinite loop */
        communicate(sock, (struct sockaddr*)server);
}
Пример #14
0
int
stomp_connect(stomp_connection **connection_ref, char *hostname, int port)
{
  stomp_connection *conn;

  conn = g_new0(stomp_connection, 1);

  conn->socket = socket(AF_INET, SOCK_STREAM, 0);
  if (conn->socket == -1)
    {
      msg_error("Failed to create socket!", NULL);
      return FALSE;
    }

  conn->remote_sa = g_sockaddr_inet_new("127.0.0.1", port);
  if (!resolve_hostname(&conn->remote_sa, hostname))
    {
      msg_error("Failed to resolve hostname in stomp driver",
                evt_tag_str("hostname", hostname),
                NULL);

      return FALSE;
    }

  if (!g_connect(conn->socket, conn->remote_sa))
    {
      msg_error("Stomp connection failed",
                evt_tag_str("host", hostname),
                NULL);
      _stomp_connection_free(conn);
      return FALSE;
    }

  (*connection_ref) = conn;

  return TRUE;
};
Пример #15
0
static bool from_match (const char *tok, const char *string)
{
	size_t tok_len;

	/*
	 * If a token has the magic value "ALL" the match always succeeds. Return
	 * true if the token fully matches the string. If the token is a domain
	 * name, return true if it matches the last fields of the string. If the
	 * token has the magic value "LOCAL", return true if the string does not
	 * contain a "." character. If the token is a network number, return true
	 * if it matches the head of the string.
	 */
#if HAVE_INNETGR
	if (tok[0] == '@') {	/* netgroup */
		return (netgroup_match (tok + 1, string, (char *) 0));
	} else
#endif
	if (string_match (tok, string)) {	/* ALL or exact match */
		return true;
	} else if (tok[0] == '.') {	/* domain: match last fields */
		size_t str_len;
		str_len = strlen (string);
		tok_len = strlen (tok);
		if (   (str_len > tok_len)
		    && (strcasecmp (tok, string + str_len - tok_len) == 0)) {
			return true;
		}
	} else if (strcasecmp (tok, "LOCAL") == 0) {	/* local: no dots */
		if (strchr (string, '.') == NULL) {
			return true;
		}
	} else if (   (tok[(tok_len = strlen (tok)) - 1] == '.') /* network */
		   && (strncmp (tok, resolve_hostname (string), tok_len) == 0)) {
		return true;
	}
	return false;
}
Пример #16
0
/* Open a socket to the dumper. Returns TRUE if everything is happy, FALSE
   otherwise. */
static gboolean open_read_socket(dump_info_t * info, char * split_diskbuffer,
                             guint64 splitsize, guint64 fallback_splitsize) {
    in_port_t port = 0;
    int socket;
    int fd;
    int result;
    struct addrinfo *res;

    if ((result = resolve_hostname("localhost", 0, &res, NULL) != 0)) {
        char *m;
        char *q;
	int save_errno = errno;
        char *qdiskname = quote_string(info->diskname);

        m = vstralloc("[localhost resolve failure: ",
                      strerror(save_errno),
                      "]",
                      NULL);
        q = quote_string(m);
        putresult(TAPE_ERROR, "%s %s\n", info->handle, q);
        log_add(L_FAIL, "%s %s %s %d %s",
                info->hostname, qdiskname, info->timestamp,
                info->level, q);
        amfree(qdiskname);
        amfree(m);
        amfree(q);
        return FALSE;
    }

    socket = stream_server(res->ai_family, &port, 0, STREAM_BUFSIZE, 0);
    freeaddrinfo(res);

    if (socket < 0) {
        char *m;
        char *q;
	int save_errno = errno;
        char *qdiskname = quote_string(info->diskname);

        m = vstralloc("[port create failure: ",
                      strerror(save_errno),
                      "]",
                      NULL);
        q = quote_string(m);
        putresult(TAPE_ERROR, "%s %s\n", info->handle, q);
        log_add(L_FAIL, "%s %s %s %d %s",
                info->hostname, qdiskname, info->timestamp,
                info->level, q);
        amfree(qdiskname);
        amfree(m);
        amfree(q);
        return FALSE;
    }

    putresult(PORT, "%d\n", port);

    fd = stream_accept(socket, CONNECT_TIMEOUT, 0, STREAM_BUFSIZE);

    if (fd < 0) {
        char *m, *q;
	int save_errno = errno;
        char *qdiskname = quote_string(info->diskname);
        m = vstralloc("[port connect failure: ",
                      strerror(save_errno),
                      "]",
                      NULL);
        q = quote_string(m);
        putresult(TAPE_ERROR, "%s %s\n", info->handle, q);
        log_add(L_FAIL, "%s %s %s %d %s",
                info->hostname, qdiskname, info->timestamp,
                info->level, q);
        amfree(qdiskname);
        aclose(socket);
        amfree(m);
        amfree(q);
        return FALSE;
    } else {
        aclose(socket);
    }

    info->source = taper_source_new(info->handle, PORT_WRITE, NULL, fd,
                                    split_diskbuffer, splitsize,
                                    fallback_splitsize);
    /* FIXME: This should be handled properly. */
    g_assert(info->source != NULL);
    return TRUE;
}
Пример #17
0
/*
 * krb5 version of a security handle allocator.  Logically sets
 * up a network "connection".
 */
static void
krb5_connect(
    const char *hostname,
    char *	(*conf_fn)(char *, void *),
    void	(*fn)(void *, security_handle_t *, security_status_t),
    void *	arg,
    void *	datap)
{
    struct sec_handle *rh;
    int result;
    char *canonname;

    assert(fn != NULL);
    assert(hostname != NULL);

    auth_debug(1, "krb5: krb5_connect: %s\n", hostname);

    krb5_init();

    rh = alloc(sizeof(*rh));
    security_handleinit(&rh->sech, &krb5_security_driver);
    rh->hostname = NULL;
    rh->rs = NULL;
    rh->ev_timeout = NULL;
    rh->rc = NULL;

    result = resolve_hostname(hostname, 0, NULL, &canonname);
    if(result != 0) {
	dbprintf(_("resolve_hostname(%s): %s\n"), hostname, gai_strerror(result));
	security_seterror(&rh->sech, _("resolve_hostname(%s): %s\n"), hostname,
			  gai_strerror(result));
	(*fn)(arg, &rh->sech, S_ERROR);
	return;
    }
    if (canonname == NULL) {
	dbprintf(_("resolve_hostname(%s) did not return a canonical name\n"), hostname);
	security_seterror(&rh->sech,
	        _("resolve_hostname(%s) did not return a canonical name\n"), hostname);
	(*fn)(arg, &rh->sech, S_ERROR);
       return;
    }

    rh->hostname = canonname;        /* will be replaced */
    canonname = NULL; /* steal reference */
    rh->rs = tcpma_stream_client(rh, newhandle++);
    rh->rc->conf_fn = conf_fn;
    rh->rc->datap = datap;
    rh->rc->recv_security_ok = NULL;
    rh->rc->prefix_packet = NULL;

    if (rh->rs == NULL)
	goto error;

    amfree(rh->hostname);
    rh->hostname = stralloc(rh->rs->rc->hostname);

#ifdef AMANDA_KEYTAB
    keytab_name = AMANDA_KEYTAB;
#else
    if(conf_fn) {
        keytab_name = conf_fn("krb5keytab", datap);
    }
#endif
#ifdef AMANDA_PRINCIPAL
    principal_name = AMANDA_PRINCIPAL;
#else
    if(conf_fn) {
        principal_name = conf_fn("krb5principal", datap);
    }
#endif

    /*
     * We need to open a new connection.
     *
     * XXX need to eventually limit number of outgoing connections here.
     */
    if(rh->rc->read == -1) {
	if (runkrb5(rh) < 0)
	    goto error;
	rh->rc->refcnt++;
    }

    /*
     * The socket will be opened async so hosts that are down won't
     * block everything.  We need to register a write event
     * so we will know when the socket comes alive.
     *
     * Overload rh->rs->ev_read to provide a write event handle.
     * We also register a timeout.
     */
    rh->fn.connect = fn;
    rh->arg = arg;
    rh->rs->ev_read = event_register((event_id_t)(rh->rs->rc->write),
	EV_WRITEFD, sec_connect_callback, rh);
    rh->ev_timeout = event_register(CONNECT_TIMEOUT, EV_TIME,
	sec_connect_timeout, rh);

    amfree(canonname);
    return;

error:
    amfree(canonname);
    (*fn)(arg, &rh->sech, S_ERROR);
}
Пример #18
0
/*
 * bsdtcp version of a security handle allocator.  Logically sets
 * up a network "connection".
 */
static void
bsdtcp_connect(
    const char *hostname,
    char *	(*conf_fn)(char *, void *),
    void	(*fn)(void *, security_handle_t *, security_status_t),
    void *	arg,
    void *	datap)
{
    struct sec_handle *rh;
    int result;
    char *canonname;
    char *service;
    in_port_t port;

    assert(fn != NULL);
    assert(hostname != NULL);
    (void)conf_fn;	/* Quiet unused parameter warning */
    (void)datap;	/* Quiet unused parameter warning */

    auth_debug(1, _("bsdtcp: bsdtcp_connect: %s\n"), hostname);

    rh = alloc(sizeof(*rh));
    security_handleinit(&rh->sech, &bsdtcp_security_driver);
    rh->hostname = NULL;
    rh->rs = NULL;
    rh->ev_timeout = NULL;
    rh->rc = NULL;

    result = resolve_hostname(hostname, 0, NULL, &canonname);
    if(result != 0) {
	dbprintf(_("resolve_hostname(%s): %s\n"), hostname, gai_strerror(result));
	security_seterror(&rh->sech, _("resolve_hostname(%s): %s\n"), hostname,
			  gai_strerror(result));
	(*fn)(arg, &rh->sech, S_ERROR);
	return;
    }
    if (canonname == NULL) {
	dbprintf(_("resolve_hostname(%s) did not return a canonical name\n"), hostname);
	security_seterror(&rh->sech,
	        _("resolve_hostname(%s) did not return a canonical name\n"), hostname);
	(*fn)(arg, &rh->sech, S_ERROR);
       return;
    }

    rh->hostname = canonname;	/* will be replaced */
    canonname = NULL; /* steal reference */
    rh->rs = tcpma_stream_client(rh, newhandle++);
    rh->rc->recv_security_ok = &bsd_recv_security_ok;
    rh->rc->prefix_packet = &bsd_prefix_packet;

    if (rh->rs == NULL)
	goto error;

    amfree(rh->hostname);
    rh->hostname = stralloc(rh->rs->rc->hostname);

    if (conf_fn) {
	service = conf_fn("client_port", datap);
	if (strlen(service) <= 1)
	    service = "amanda";
    } else {
	service = "amanda";
    }
    port = find_port_for_service(service, "tcp");
    if (port == 0) {
	security_seterror(&rh->sech, _("%s/tcp unknown protocol"), service);
	goto error;
    }

    /*
     * We need to open a new connection.
     *
     * XXX need to eventually limit number of outgoing connections here.
     */
    if(rh->rc->read == -1) {
	if (runbsdtcp(rh, port) < 0)
	    goto error;
	rh->rc->refcnt++;
    }

    /*
     * The socket will be opened async so hosts that are down won't
     * block everything.  We need to register a write event
     * so we will know when the socket comes alive.
     *
     * Overload rh->rs->ev_read to provide a write event handle.
     * We also register a timeout.
     */
    rh->fn.connect = fn;
    rh->arg = arg;
    rh->rs->ev_read = event_register((event_id_t)(rh->rs->rc->write),
	EV_WRITEFD, sec_connect_callback, rh);
    rh->ev_timeout = event_register(CONNECT_TIMEOUT, EV_TIME,
	sec_connect_timeout, rh);

    return;

error:
    (*fn)(arg, &rh->sech, S_ERROR);
}
Пример #19
0
Файл: net.c Проект: mikekap/wine
static DWORD CALLBACK resolve_proc( LPVOID arg )
{
    struct resolve_args *ra = arg;
    return resolve_hostname( ra->hostname, ra->port, ra->sa, ra->sa_len );
}
Пример #20
0
std::vector<condor_sockaddr> resolve_hostname(const char* hostname)
{
	MyString host(hostname);
	return resolve_hostname(host);
}
Пример #21
0
	void handle_participate_message(zeroconf_msg& message)
	{
		msg_data m_data;
		
		memcpy(&m_data, message.payload(), message.payload_size() );


		debug_->debug("receive participate(%u) from (%s)\n",radio_->id(),(char *)message.source());
                  
               if (mode==0)//if node is in the network
	       {//if you receive an other message
                  if (!strcmp((char *)message.destination(),my_ip) || !strcmp(m_data.dest_host,my_host))
                  {//you are the destination
                     //debug_->debug("%s got a message wow!:)(%s)\n",my_ip,message.source_ip);
                     if (!strcmp((char *)message.source(),"0.0.0.0")) //someone is trying to connect with my ip
                     {//if the sender is one whos trying to come in                        
			debug_->debug("found an outsider, i must reply to him\n");
			set_node_message_id(my_MACC,++msgID);
			zeroconf_msg reply;
 			memset(&reply,0,sizeof(reply));
			reply.set_type(TYPE_LEN * sizeof(char), (Os::Radio::block_data_t *) &("participate"));
			reply.set_source(IP_LEN * sizeof(char),(Os::Radio::block_data_t *) &my_ip);
	 		reply.set_destination(IP_LEN * sizeof(char),(Os::Radio::block_data_t *) &("ANY"));
         		reply.set_source_mac(MAC_LEN * sizeof(char),(Os::Radio::block_data_t *) &my_MACC );
	 		reply.set_msg_id(msgID);

			msg_data reply_data;
			strcpy(reply_data.source_host,my_host);
	 		
			reply.set_payload(sizeof(msg_data),(Os::Radio::block_data_t *) &reply_data);
			radio_->send( Os::Radio::BROADCAST_ADDRESS, sizeof(zeroconf_msg), (Os::Radio::block_data_t *)&reply);
                     }
                  } 
                  else 
                  {//else forward the message
                     //strcpy(message.not_ip,my_ip);
                     radio_->send( Os::Radio::BROADCAST_ADDRESS, sizeof(zeroconf_msg), (Os::Radio::block_data_t *)&message);
                  }
               } 
               else if (mode == 1) 
               {//if node is not in the network
				debug_->debug("eimai o 0:m_data.source_host=%s\n",m_data.source_host);	
                  if (!strcmp((char *)message.source(),my_ip)) 
                  {//if you receive message from someone with your ip
                     counter=0;
                     debug_->debug("(%u)WOW someone has my ip.... i must change it?\n",radio_->id());
                     generate_ip();//generate new ip
                  }
						
                  if (!strcmp(m_data.source_host,my_host))
                  {//if you receive message from someone with your hostname
                     debug_->debug("%u === my_host = %s & source_host = %s \n", radio_->id(), my_host, m_data.source_host);
                     counter=0;
                     //generate_hostname();//generate new hostname
					 debug_->debug("(%u)WOW someone has my hostname.... i must change it?\n",radio_->id());
                     resolve_hostname(my_host, trial_num);
                     trial_num = 1;
                  }

                  //someone is claiming the hostname i want at the same time  
                  if (!strcmp(m_data.dest_host,my_host) && strcmp((char *)message.source_mac(),my_MACC))
                  {
                     counter=0;

		     resolve_hostname(my_host, trial_num);
                  }
                  if (!strcmp((char *)message.destination(),my_ip) && strcmp((char *)message.source_mac(),my_MACC))
                  {
                     counter=0;
		     generate_ip();
                  }
                  
               }

	}
Пример #22
0
/*
 * ssl version of a security handle allocator.  Logically sets
 * up a network "connection".
 */
static void
ssl_connect(
    const char *hostname,
    char *	(*conf_fn)(char *, void *),
    void	(*fn)(void *, security_handle_t *, security_status_t),
    void *	arg,
    void *	datap)
{
    struct sec_handle *rh;
    int result;
    char *canonname;
    char *service;
    in_port_t port;
    char *src_ip = NULL;
    char *ssl_dir = NULL;
    char *ssl_fingerprint_file = NULL;
    char *ssl_cert_file = NULL;
    char *ssl_key_file = NULL;
    char *ssl_ca_cert_file = NULL;
    char *ssl_cipher_list = NULL;
    int   ssl_check_certificate_host = 1;

    assert(fn != NULL);
    assert(hostname != NULL);

    auth_debug(1, _("ssl: ssl_connect: %s\n"), hostname);

    rh = g_new0(struct sec_handle, 1);
    security_handleinit(&rh->sech, &ssl_security_driver);
    rh->hostname = NULL;
    rh->rs = NULL;
    rh->ev_timeout = NULL;
    rh->rc = NULL;

    result = resolve_hostname(hostname, 0, NULL, &canonname);
    if(result != 0) {
	g_debug(_("resolve_hostname(%s): %s"), hostname, gai_strerror(result));
	security_seterror(&rh->sech, _("resolve_hostname(%s): %s\n"), hostname,
			  gai_strerror(result));
	(*fn)(arg, &rh->sech, S_ERROR);
	return;
    }
    if (canonname == NULL) {
	g_debug(_("resolve_hostname(%s) did not return a canonical name"), hostname);
	security_seterror(&rh->sech,
	        _("resolve_hostname(%s) did not return a canonical name\n"), hostname);
	(*fn)(arg, &rh->sech, S_ERROR);
       return;
    }

    rh->hostname = canonname;	/* will be replaced */
    canonname = NULL; /* steal reference */
    rh->rs = tcpma_stream_client(rh, newhandle++);
    rh->rc->recv_security_ok = &bsd_recv_security_ok;
    rh->rc->prefix_packet = &bsd_prefix_packet;
    rh->rc->need_priv_port = 0;

    if (rh->rs == NULL)
	goto error;

    amfree(rh->hostname);
    rh->hostname = g_strdup(rh->rs->rc->hostname);

    ssl_dir = getconf_str(CNF_SSL_DIR);
    if (conf_fn) {
	service = conf_fn("remote_port", datap);
	if (!service || strlen(service) <= 1)
	    service = AMANDA_SERVICE_NAME;
	g_debug("Connecting to service '%s'", service);
	src_ip = conf_fn("src_ip", datap);
	ssl_fingerprint_file = g_strdup(conf_fn("ssl_fingerprint_file", datap));
	ssl_cert_file        = g_strdup(conf_fn("ssl_cert_file", datap));
	ssl_key_file         = g_strdup(conf_fn("ssl_key_file", datap));
	ssl_ca_cert_file     = g_strdup(conf_fn("ssl_ca_cert_file", datap));
	ssl_cipher_list      = conf_fn("ssl_cipher_list", datap);
	ssl_check_certificate_host =
			    atoi(conf_fn("ssl_check_certificate_host", datap));
    } else {
	service = AMANDA_SERVICE_NAME;
    }

    if (ssl_dir) {
	if (!ssl_cert_file || ssl_cert_file == '\0') {
	    ssl_cert_file = g_strdup_printf("%s/me/crt.pem", ssl_dir);
	}
	if (!ssl_key_file || ssl_key_file == '\0') {
	    ssl_key_file = g_strdup_printf("%s/me/private/key.pem", ssl_dir);
	}
	if (!ssl_ca_cert_file || ssl_ca_cert_file == '\0') {
	    ssl_ca_cert_file = g_strdup_printf("%s/CA/crt.pem", ssl_dir);
	}
	if (!ssl_fingerprint_file || ssl_fingerprint_file == '\0') {
	    struct stat  statbuf;
	    ssl_fingerprint_file = g_strdup_printf("%s/remote/%s/fingerprint", ssl_dir, rh->hostname);
	    if (stat(ssl_fingerprint_file, &statbuf) == -1) {
		g_free(ssl_fingerprint_file);
		ssl_fingerprint_file = NULL;
	    }
	}
    }

    port = find_port_for_service(service, "tcp");
    if (port == 0) {
	security_seterror(&rh->sech, _("%s/tcp unknown protocol"), service);
	goto error;
    }

    /*
     * We need to open a new connection.
     */
    if(rh->rc->read == -1) {
	if (runssl(rh, port, src_ip, ssl_fingerprint_file,
                   ssl_cert_file, ssl_key_file,
		   ssl_ca_cert_file, ssl_cipher_list,
		   ssl_check_certificate_host) < 0)
	    goto error;
	rh->rc->refcnt++;
    }

    g_free(ssl_fingerprint_file);
    g_free(ssl_cert_file);
    g_free(ssl_key_file);
    g_free(ssl_ca_cert_file);
    /*
     * The socket will be opened async so hosts that are down won't
     * block everything.  We need to register a write event
     * so we will know when the socket comes alive.
     *
     * Overload rh->rs->ev_read to provide a write event handle.
     * We also register a timeout.
     */
    rh->fn.connect = fn;
    rh->arg = arg;
    rh->rs->ev_read = event_register((event_id_t)(rh->rs->rc->write),
	EV_WRITEFD, sec_connect_callback, rh);
    rh->ev_timeout = event_register(CONNECT_TIMEOUT, EV_TIME,
	sec_connect_timeout, rh);

    return;

error:
    (*fn)(arg, &rh->sech, S_ERROR);
}
Пример #23
0
// faithful reimplementation of 'string_to_sin' of internet.c
bool condor_sockaddr::from_sinful(const char* sinful)
{
	if ( !sinful ) return false;

	const char* addr = sinful;
	bool ipv6 = false;
	const char* addr_begin = NULL;
	const char* port_begin = NULL;
	int addr_len = 0;
	int port_len = 0;
	if ( *addr != '<' ) return false;
	addr++;
	if ( *addr == '[' ) {
		ipv6 = true;
		addr++;
		addr_begin = addr;

		while( *addr && *addr != ']' )
			addr++;

		if ( *addr == 0 ) return false;

		addr_len = addr-addr_begin;
		addr++;
	}
	else {
		addr_begin = addr;
		while ( *addr && *addr != ':' && *addr != '>' )
			addr++;

		if ( *addr == 0 ) return false;

		addr_len = addr-addr_begin;
		// you should not do 'addr++' here
	}

	if ( *addr == ':' ) {
		addr++;
		port_begin = addr;
		//port_len = strspn(addr, "0123456789");
		// re-implemented without strspn as strspn causes valgrind
		// errors on RHEL6.
		const char * addr_ptr = addr;
		port_len = 0;
		while (*addr_ptr && isdigit(*addr_ptr++)) port_len++;
		addr += port_len;
	}
	if ( *addr == '?' ) {
		addr++;
		int len = strcspn(addr, ">");
		addr += len;
	}

	if ( addr[0] != '>' || addr[1] != '\0' ) return false;

	clear();

	int port_no = atoi(port_begin);

	char tmp[NI_MAXHOST];
	if ( ipv6 ) {
		if (addr_len >= INET6_ADDRSTRLEN) 
			return false;
		memcpy(tmp, addr_begin, addr_len);
		tmp[addr_len] = '\0';
#ifdef HAVE_STRUCT_SOCKADDR_IN_SIN_LEN
		v6.sin6_len = sizeof(sockaddr_in6);
#endif
		v6.sin6_family = AF_INET6;
		if ( inet_pton(AF_INET6, tmp, &v6.sin6_addr) <= 0) return false;
		v6.sin6_port = htons(port_no);
	}	
	else {
		if (addr_len >= NI_MAXHOST)
			return false;
		memcpy(tmp, addr_begin, addr_len);
		tmp[addr_len] = '\0';

		if (inet_pton(AF_INET, tmp, &v4.sin_addr) > 0) {
#ifdef HAVE_STRUCT_SOCKADDR_IN_SIN_LEN
			v4.sin_len = sizeof(sockaddr_in);
#endif
			v4.sin_family = AF_INET;
			v4.sin_port = htons(port_no);
		} else {
			std::vector<condor_sockaddr> ret;
			ret = resolve_hostname(tmp);
			if (!ret.empty()) {
				*this = ret.front();
				set_port(port_no);
			} else
				return false;
		}
	}
	return true;
}
Пример #24
0
int zmq::tcp_address_t::resolve (const char *name_, bool local_, bool ipv6_, bool is_src_)
{
    if (!is_src_) {
        // Test the ';' to know if we have a source address in name_
        const char *src_delimiter = strrchr (name_, ';');
        if (src_delimiter) {
            std::string src_name (name_, src_delimiter - name_);
            const int rc = resolve (src_name.c_str (), local_, ipv6_, true);
            if (rc != 0)
                return -1;
            name_ = src_delimiter + 1;
            _has_src_addr = true;
        }
    }

    //  Find the ':' at end that separates address from the port number.
    const char *delimiter = strrchr (name_, ':');
    if (!delimiter) {
        errno = EINVAL;
        return -1;
    }

    //  Separate the address/port.
    std::string addr_str (name_, delimiter - name_);
    std::string port_str (delimiter + 1);

    //  Remove square brackets around the address, if any, as used in IPv6
    if (addr_str.size () >= 2 && addr_str [0] == '[' &&
          addr_str [addr_str.size () - 1] == ']')
        addr_str = addr_str.substr (1, addr_str.size () - 2);

    // Test the '%' to know if we have an interface name / zone_id in the address
    // Reference: https://tools.ietf.org/html/rfc4007
    std::size_t pos = addr_str.rfind("%");
    uint32_t zone_id = 0;
    if (pos != std::string::npos) {
        std::string if_str = addr_str.substr(pos + 1);
        addr_str = addr_str.substr(0, pos);
        if (isalpha (if_str.at (0)))
            zone_id = if_nametoindex(if_str.c_str());
        else
            zone_id = (uint32_t) atoi (if_str.c_str ());
        if (zone_id == 0) {
            errno = EINVAL;
            return -1;
        }
    }

    //  Allow 0 specifically, to detect invalid port error in atoi if not
    uint16_t port;
    if (port_str == "*" || port_str == "0")
        //  Resolve wildcard to 0 to allow autoselection of port
        port = 0;
    else {
        //  Parse the port number (0 is not a valid port).
        port = (uint16_t) atoi (port_str.c_str ());
        if (port == 0) {
            errno = EINVAL;
            return -1;
        }
    }

    //  Resolve the IP address.
    int rc;
    if (local_ || is_src_)
        rc = resolve_interface (addr_str.c_str (), ipv6_, is_src_);
    else
        rc = resolve_hostname (addr_str.c_str (), ipv6_, is_src_);
    if (rc != 0)
        return -1;

    //  Set the port into the address structure.
    if (is_src_) {
        if (source_address.generic.sa_family == AF_INET6) {
            source_address.ipv6.sin6_port = htons (port);
            source_address.ipv6.sin6_scope_id = zone_id;
        }
        else
            source_address.ipv4.sin_port = htons (port);
    }
    else {
        if (address.generic.sa_family == AF_INET6) {
            address.ipv6.sin6_port = htons (port);
            address.ipv6.sin6_scope_id = zone_id;
        }
        else
            address.ipv4.sin_port = htons (port);
    }

    return 0;
}
Пример #25
0
int
condor_gethostname(char *name, size_t namelen) {

	if (nodns_enabled()) {

		char tmp[MAXHOSTNAMELEN];
		char *param_buf;

			// First, we try NETWORK_INTERFACE
		if ( (param_buf = param( "NETWORK_INTERFACE" )) ) {
			char ip_str[MAXHOSTNAMELEN];

			// reimplement with condor_sockaddr and to_ip_string()
			condor_sockaddr addr;

			dprintf( D_HOSTNAME, "NO_DNS: Using NETWORK_INTERFACE='%s' "
					 "to determine hostname\n", param_buf );

			snprintf( ip_str, MAXHOSTNAMELEN, "%s", param_buf );
			free( param_buf );

			if (!addr.from_ip_string(ip_str)) {
				dprintf(D_HOSTNAME,
						"NO_DNS: NETWORK_INTERFACE is invalid: %s\n",
						ip_str);
				return -1;
			}

			MyString hostname = convert_ipaddr_to_hostname(addr);
			if (hostname.Length() >= (int) namelen) {
				return -1;
			}
			strcpy(name, hostname.Value());
			return 0;
		}

			// Second, we try COLLECTOR_HOST

			// To get the hostname with NODNS we are going to jump
			// through some hoops. We will try to make a UDP
			// connection to the COLLECTOR_HOST. This will result in not
			// only letting us call getsockname to find an IP for this
			// machine, but it will select the proper IP that we can
			// use to contact the COLLECTOR_HOST
		if ( (param_buf = param( "COLLECTOR_HOST" )) ) {

			//struct hostent *collector_ent;
			int s;
			//SOCKET_LENGTH_TYPE addr_len;
			char collector_host[MAXHOSTNAMELEN];
			char *idx;
			//struct sockaddr_in addr, collector_addr;
			condor_sockaddr collector_addr;
			condor_sockaddr addr;
			std::vector<condor_sockaddr> collector_addrs;

			dprintf( D_HOSTNAME, "NO_DNS: Using COLLECTOR_HOST='%s' "
					 "to determine hostname\n", param_buf );

				// Get only the name portion of the COLLECTOR_HOST
			if ((idx = index(param_buf, ':'))) {
				*idx = '\0';
			}
			snprintf( collector_host, MAXHOSTNAMELEN, "%s", param_buf );
			free( param_buf );

				// Now that we have the name we need an IP

			collector_addrs = resolve_hostname(collector_host);
			if (collector_addrs.empty()) {
				dprintf(D_HOSTNAME,
						"NO_DNS: Failed to get IP address of collector "
						"host '%s'\n", collector_host);
				return -1;
			}

			collector_addr = collector_addrs.front();
			collector_addr.set_port(1980);

				// We are doing UDP, the benefit is connect will not send
				// any network traffic on a UDP socket
			if (-1 == (s = socket(collector_addr.get_aftype(), 
								  SOCK_DGRAM, 0))) {
				dprintf(D_HOSTNAME,
						"NO_DNS: Failed to create socket, errno=%d (%s)\n",
						errno, strerror(errno));
				return -1;
			}

			if (condor_connect(s, collector_addr)) {
				perror("connect");
				dprintf(D_HOSTNAME,
						"NO_DNS: Failed to bind socket, errno=%d (%s)\n",
						errno, strerror(errno));
				return -1;
			}

			if (condor_getsockname(s, addr)) {
				dprintf(D_HOSTNAME,
						"NO_DNS: Failed to get socket name, errno=%d (%s)\n",
						errno, strerror(errno));
				return -1;
			}

			MyString hostname = convert_ipaddr_to_hostname(addr);
			if (hostname.Length() >= (int) namelen) {
				return -1;
			}
			strcpy(name, hostname.Value());
			return 0;
		}

			// Last, we try gethostname()
		if ( gethostname( tmp, MAXHOSTNAMELEN ) == 0 ) {

			dprintf( D_HOSTNAME, "NO_DNS: Using gethostname()='%s' "
					 "to determine hostname\n", tmp );

			std::vector<condor_sockaddr> addrs;
			MyString my_hostname(tmp);
			addrs = resolve_hostname_raw(my_hostname);
			if (addrs.empty()) {
				dprintf(D_HOSTNAME,
						"NO_DNS: resolve_hostname_raw() failed, errno=%d"
						" (%s)\n", errno, strerror(errno));
				return -1;
			}

			MyString hostname = convert_ipaddr_to_hostname(addrs.front());
			if (hostname.Length() >= (int) namelen) {
				return -1;
			}
			strcpy(name, hostname.Value());
			return 0;
		}

		dprintf(D_HOSTNAME,
				"Failed in determining hostname for this machine\n");
		return -1;

	} else {
		return gethostname(name, namelen);
	}
}
Пример #26
0
static gboolean
do_directtcp_listen(
    XferElement *elt,
    int *sockp,
    DirectTCPAddr **addrsp)
{
    int sock;
    sockaddr_union data_addr;
    DirectTCPAddr *addrs;
    socklen_t len;
    struct addrinfo *res;
    struct addrinfo *res_addr;
    sockaddr_union *addr = NULL;

    if (resolve_hostname("localhost", 0, &res, NULL) != 0) {
	xfer_cancel_with_error(elt, "resolve_hostname(): %s", strerror(errno));
	return FALSE;
    }
    for (res_addr = res; res_addr != NULL; res_addr = res_addr->ai_next) {
	if (res_addr->ai_family == AF_INET) {
            addr = (sockaddr_union *)res_addr->ai_addr;
            break;
        }
    }
    if (!addr) {
        addr = (sockaddr_union *)res->ai_addr;
    }

    sock = *sockp = socket(SU_GET_FAMILY(addr), SOCK_STREAM, 0);
    if (sock < 0) {
	xfer_cancel_with_error(elt, "socket(): %s", strerror(errno));
	freeaddrinfo(res);
	return FALSE;
    }

    len = SS_LEN(addr);
    if (bind(sock, (struct sockaddr *)addr, len) != 0) {
	xfer_cancel_with_error(elt, "bind(): %s", strerror(errno));
	freeaddrinfo(res);
	close(sock);
	*sockp = -1;
	return FALSE;
    }

    if (listen(sock, 1) < 0) {
	xfer_cancel_with_error(elt, "listen(): %s", strerror(errno));
	freeaddrinfo(res);
	close(sock);
	*sockp = -1;
	return FALSE;
    }

    /* TODO: which addresses should this display? all ifaces? localhost? */
    len = sizeof(data_addr);
    if (getsockname(sock, (struct sockaddr *)&data_addr, &len) < 0)
	error("getsockname(): %s", strerror(errno));

    addrs = g_new0(DirectTCPAddr, 2);
    copy_sockaddr(&addrs[0], &data_addr);
    *addrsp = addrs;
    freeaddrinfo(res);

    return TRUE;
}
Пример #27
0
static int
stream_client_internal(
    const char *hostname,
    in_port_t port,
    size_t sendsize,
    size_t recvsize,
    in_port_t *localport,
    int nonblock,
    int priv)
{
    sockaddr_union svaddr, claddr;
    int save_errno = 0;
    int client_socket = 0;
    int *portrange = NULL;
    int result;
    struct addrinfo *res, *res_addr;

    result = resolve_hostname(hostname, SOCK_STREAM, &res, NULL);
    if(result != 0) {
	g_debug(_("resolve_hostname(%s): %s"), hostname, gai_strerror(result));
	errno = EHOSTUNREACH;
	return -1;
    }
    if(!res) {
	g_debug(_("resolve_hostname(%s): no results"), hostname);
	errno = EHOSTUNREACH;
	return -1;
    }

    for (res_addr = res; res_addr != NULL; res_addr = res_addr->ai_next) {
	/* copy the first (preferred) address we found */
	copy_sockaddr(&svaddr, (sockaddr_union *)res_addr->ai_addr);
	SU_SET_PORT(&svaddr, port);

	SU_INIT(&claddr, SU_GET_FAMILY(&svaddr));
	SU_SET_INADDR_ANY(&claddr);

	/*
	 * If a privileged port range was requested, we try to get a port in
	 * that range first and fail if it is not available.  Next, we try
	 * to get a port in the range built in when Amanda was configured.
	 * If that fails, we just go for any port.
	 *
	 * It is up to the caller to make sure we have the proper permissions
	 * to get the desired port, and to make sure we return a port that
	 * is within the range it requires.
	 */
	if (priv) {
	    portrange = getconf_intrange(CNF_RESERVED_TCP_PORT);
	} else {
	    portrange = getconf_intrange(CNF_UNRESERVED_TCP_PORT);
	}
	client_socket = connect_portrange(&claddr, (in_port_t)portrange[0],
					  (in_port_t)portrange[1],
					  "tcp", &svaddr, nonblock);
	save_errno = errno;
	if (client_socket > 0)
	    break;
    }

    freeaddrinfo(res);
					  
    if (client_socket > 0)
	goto out;

    g_debug(_("stream_client: Could not bind to port in range %d-%d."),
	      portrange[0], portrange[1]);

    errno = save_errno;
    return -1;

out:
    try_socksize(client_socket, SO_SNDBUF, sendsize);
    try_socksize(client_socket, SO_RCVBUF, recvsize);
    if (localport != NULL)
	*localport = SU_GET_PORT(&claddr);
    return client_socket;
}
Пример #28
0
static void
bsd_connect(
    const char *	hostname,
    char *		(*conf_fn)(char *, void *),
    void		(*fn)(void *, security_handle_t *, security_status_t),
    void *		arg,
    void *		datap)
{
    struct sec_handle *bh;
    in_port_t port = 0;
    struct timeval sequence_time;
    int sequence;
    char *handle;
    int result;
    struct addrinfo *res, *res_addr;
    char *canonname;
    int result_bind;
    char *service;

    assert(hostname != NULL);

    (void)conf_fn;	/* Quiet unused parameter warning */
    (void)datap;        /* Quiet unused parameter warning */

    bh = g_new0(struct sec_handle, 1);
    bh->proto_handle=NULL;
    security_handleinit(&bh->sech, &bsd_security_driver);

    result = resolve_hostname(hostname, SOCK_DGRAM, &res, &canonname);
    if(result != 0) {
	dbprintf(_("resolve_hostname(%s): %s\n"), hostname, gai_strerror(result));
	security_seterror(&bh->sech, _("resolve_hostname(%s): %s\n"), hostname,
			  gai_strerror(result));
	(*fn)(arg, &bh->sech, S_ERROR);
	return;
    }
    if (canonname == NULL) {
	dbprintf(_("resolve_hostname(%s) did not return a canonical name\n"), hostname);
	security_seterror(&bh->sech,
	        _("resolve_hostname(%s) did not return a canonical name\n"), hostname);
	(*fn)(arg, &bh->sech, S_ERROR);
	if (res) freeaddrinfo(res);
	return;
    }
    if (res == NULL) {
	dbprintf(_("resolve_hostname(%s): no results\n"), hostname);
	security_seterror(&bh->sech,
	        _("resolve_hostname(%s): no results\n"), hostname);
	(*fn)(arg, &bh->sech, S_ERROR);
	amfree(canonname);
	return;
    }

    for (res_addr = res; res_addr != NULL; res_addr = res_addr->ai_next) {
#ifdef WORKING_IPV6
	/* IPv6 socket already bound */
	if (res_addr->ai_addr->sa_family == AF_INET6 && not_init6 == 0) {
	    break;
	}
	/*
	 * Only init the IPv6 socket once
	 */
	if (res_addr->ai_addr->sa_family == AF_INET6 && not_init6 == 1) {
	    uid_t euid;
	    dgram_zero(&netfd6.dgram);

	    euid = geteuid();
	    set_root_privs(1);
	    result_bind = dgram_bind(&netfd6.dgram,
				     res_addr->ai_addr->sa_family, &port);
	    set_root_privs(0);
	    if (result_bind != 0) {
		continue;
	    }
	    netfd6.handle = NULL;
	    netfd6.pkt.body = NULL;
	    netfd6.recv_security_ok = &bsd_recv_security_ok;
	    netfd6.prefix_packet = &bsd_prefix_packet;
	    /*
	     * We must have a reserved port.  Bomb if we didn't get one.
	     */
	    if (port >= IPPORT_RESERVED) {
		security_seterror(&bh->sech,
		    _("unable to bind to a reserved port (got port %u)"),
		    (unsigned int)port);
		(*fn)(arg, &bh->sech, S_ERROR);
		freeaddrinfo(res);
		amfree(canonname);
		return;
	    }
	    not_init6 = 0;
	    bh->udp = &netfd6;
	    break;
	}
#endif

	/* IPv4 socket already bound */
	if (res_addr->ai_addr->sa_family == AF_INET && not_init4 == 0) {
	    break;
	}

	/*
	 * Only init the IPv4 socket once
	 */
	if (res_addr->ai_addr->sa_family == AF_INET && not_init4 == 1) {
	    uid_t euid;
	    dgram_zero(&netfd4.dgram);

	    euid = geteuid();
	    set_root_privs(1);
	    result_bind = dgram_bind(&netfd4.dgram,
				     res_addr->ai_addr->sa_family, &port);
	    set_root_privs(0);
	    if (result_bind != 0) {
		continue;
	    }
	    netfd4.handle = NULL;
	    netfd4.pkt.body = NULL;
	    netfd4.recv_security_ok = &bsd_recv_security_ok;
	    netfd4.prefix_packet = &bsd_prefix_packet;
	    /*
	     * We must have a reserved port.  Bomb if we didn't get one.
	     */
	    if (port >= IPPORT_RESERVED) {
		security_seterror(&bh->sech,
		    "unable to bind to a reserved port (got port %u)",
		    (unsigned int)port);
		(*fn)(arg, &bh->sech, S_ERROR);
		freeaddrinfo(res);
		amfree(canonname);
		return;
	    }
	    not_init4 = 0;
	    bh->udp = &netfd4;
	    break;
	}
    }

    if (res_addr == NULL) {
	dbprintf(_("Can't bind a socket to connect to %s\n"), hostname);
	security_seterror(&bh->sech,
	        _("Can't bind a socket to connect to %s\n"), hostname);
	(*fn)(arg, &bh->sech, S_ERROR);
	amfree(canonname);
	freeaddrinfo(res);
	return;
    }

#ifdef WORKING_IPV6
    if (res_addr->ai_addr->sa_family == AF_INET6)
	bh->udp = &netfd6;
    else
#endif
	bh->udp = &netfd4;

    auth_debug(1, _("Resolved hostname=%s\n"), canonname);

    if (conf_fn) {
        service = conf_fn("client_port", datap);
        if (!service || strlen(service) <= 1)
            service = "amanda";
    } else {
        service = "amanda";
    }
    port = find_port_for_service(service, "udp");
    if (port == 0) {
        security_seterror(&bh->sech, _("%s/udp unknown protocol"), service);
	(*fn)(arg, &bh->sech, S_ERROR);
        amfree(canonname);
	freeaddrinfo(res);
	return;
    }

    amanda_gettimeofday(&sequence_time);
    sequence = (int)sequence_time.tv_sec ^ (int)sequence_time.tv_usec;
    handle=g_malloc(15);
    g_snprintf(handle, 14, "000-%08x",  (unsigned)newhandle++);
    if (udp_inithandle(bh->udp, bh, canonname,
	(sockaddr_union *)res_addr->ai_addr, port, handle, sequence) < 0) {
	(*fn)(arg, &bh->sech, S_ERROR);
	amfree(bh->hostname);
	amfree(bh);
    }
    else {
	(*fn)(arg, &bh->sech, S_OK);
    }
    amfree(handle);
    amfree(canonname);

    freeaddrinfo(res);
}
Пример #29
0
/*
 * ssh version of a security handle allocator.  Logically sets
 * up a network "connection".
 */
static void
ssh_connect(
    const char *	hostname,
    char *		(*conf_fn)(char *, void *),
    void		(*fn)(void *, security_handle_t *, security_status_t),
    void *		arg,
    void *		datap)
{
    int result;
    struct sec_handle *rh;
    char *amandad_path=NULL, *client_username=NULL, *ssh_keys=NULL;

    assert(fn != NULL);
    assert(hostname != NULL);

    auth_debug(1, "ssh_connect: %s\n", hostname);

    rh = alloc(SIZEOF(*rh));
    security_handleinit(&rh->sech, &ssh_security_driver);
    rh->hostname = NULL;
    rh->rs = NULL;
    rh->ev_timeout = NULL;
    rh->rc = NULL;

    /* get the canonical hostname */
    rh->hostname = NULL;
    if ((result = resolve_hostname(hostname, 0, NULL, &rh->hostname)) != 0
	 || rh->hostname == NULL) {
	security_seterror(&rh->sech,
	    _("ssh_security could not find canonical name for '%s': %s"),
	    hostname, gai_strerror(result));
	(*fn)(arg, &rh->sech, S_ERROR);
	return;
    }
    rh->rs = tcpma_stream_client(rh, newhandle++);
    rh->rc->conf_fn = conf_fn;
    rh->rc->datap = datap;

    if (rh->rs == NULL)
	goto error;

    amfree(rh->hostname);
    rh->hostname = stralloc(rh->rs->rc->hostname);

    /*
     * We need to open a new connection.
     *
     * XXX need to eventually limit number of outgoing connections here.
     */
    if(conf_fn) {
	amandad_path    = conf_fn("amandad_path", datap);
	client_username = conf_fn("client_username", datap);
	ssh_keys        = conf_fn("ssh_keys", datap);
    }
    if(rh->rc->read == -1) {
	if (runssh(rh->rs->rc, amandad_path, client_username, ssh_keys) < 0) {
	    security_seterror(&rh->sech, _("can't connect to %s: %s"),
			      hostname, rh->rs->rc->errmsg);
	    goto error;
	}
	rh->rc->refcnt++;
    }

    /*
     * The socket will be opened async so hosts that are down won't
     * block everything.  We need to register a write event
     * so we will know when the socket comes alive.
     *
     * Overload rh->rs->ev_read to provide a write event handle.
     * We also register a timeout.
     */
    rh->fn.connect = fn;
    rh->arg = arg;
    rh->rs->ev_read = event_register((event_id_t)rh->rs->rc->write, EV_WRITEFD,
	sec_connect_callback, rh);
    rh->ev_timeout = event_register((event_id_t)CONNECT_TIMEOUT, EV_TIME,
	sec_connect_timeout, rh);

    return;

error:
    (*fn)(arg, &rh->sech, S_ERROR);
}
Пример #30
0
void
set_host(
    const char *host)
{
    char *cmd = NULL;
    struct hostent *hp = NULL;
    char **hostp;
    int found_host = 0;
    char *uqhost = unquote_string(host);

    if (is_extract_list_nonempty())
    {
	g_printf(_("Must clear extract list before changing host\n"));
	amfree(uqhost);
	return;
    }

    /*
     * The idea here is to try as many permutations of the hostname
     * as we can imagine.  The server will reject anything it doesn't
     * recognize.
     */

    cmd = stralloc2("HOST ", uqhost);
    if (converse(cmd) == -1)
	exit(1);
    if (server_happy())
	found_host = 1;

    /*
     * Try converting the given host to a fully qualified, canonical
     * name.
     */
    if (!found_host) {
	if ((hp = gethostbyname(uqhost)) != NULL) {
	    host = hp->h_name;
	    g_printf(_("Trying host %s ...\n"), host);
	    cmd = newstralloc2(cmd, "HOST ", host);
	    if (converse(cmd) == -1)
		exit(1);
	    if(server_happy())
		found_host = 1;
	}
    }

    /*
     * Since we have them, try any CNAMEs that were traversed from uqhost
     * to the canonical name (this assumes gethostbyname was called above)
     */
    if (!found_host) {
	if (hp) {
	    for (hostp = hp->h_aliases; (host = *hostp) != NULL; hostp++)
	    {
		g_printf(_("Trying host %s ...\n"), host);
		cmd = newstralloc2(cmd, "HOST ", host);
		if (converse(cmd) == -1)
		    exit(1);
		if(server_happy())
		{
		    found_host = 1;
		    break;
		}
	    }
	}
    }

    /* Try looking up the canonical name of the host */
    if (!found_host) {
	char *canonname;
	int result;

	result = resolve_hostname(uqhost, 0, NULL, &canonname);
	if (result == 0 && canonname) {
	    host = canonname;
	    g_printf(_("Trying host %s ...\n"), host);
	    cmd = newstralloc2(cmd, "HOST ", host);
	    if (converse(cmd) == -1)
		exit(1);
	    if(server_happy())
		found_host = 1;
	}
    }

    if(found_host) {
	dump_hostname = newstralloc(dump_hostname, host);
	amfree(disk_name);
	amfree(mount_point);
	amfree(disk_path);
	clear_dir_list();
    }
    amfree(cmd);
    amfree(uqhost);
}