Пример #1
0
static bool test_internal_dns_update_self(struct torture_context *tctx)
{
	struct dns_connection *conn;
	struct dns_update_request *req, *resp;
	struct dns_rrec *rec = NULL;
	char *host;
	DNS_ERROR err;
	struct sockaddr_storage *ss;

	conn = setup_connection(tctx);
	if (conn == NULL) {
		return false;
	}

	host = talloc_asprintf(tctx, "%s.%s", getenv("DC_SERVER"), get_dns_domain(tctx));
	if (host == NULL) {
		return false;
	}

	err = dns_create_update(conn, get_dns_domain(tctx), &req);
	if (!ERR_DNS_IS_OK(err)) {
		printf("Failed to update packet\n");
		return false;
	}

	ss = str_to_sockaddr(conn, getenv("DC_SERVER_IP"));
	if (ss == NULL) {
		printf("Converting '%s' to sockaddr_storage failed\n", getenv("DC_SERVER_IP"));
		return false;
	}

	err = dns_create_a_record(req, host, 300, ss, &rec);
	if (!ERR_DNS_IS_OK(err)) {
		printf("Failed to create A update record\n");
		return false;
	}

	err = dns_add_rrec(req, rec, &req->num_updates, &req->updates);
	if (!ERR_DNS_IS_OK(err)) {
		printf("Failed to add A update record to update packet\n");
		return false;
	}

	err = dns_update_transaction(conn, conn, req, &resp);
	if (!ERR_DNS_IS_OK(err)) {
		printf("Failed to send update\n");
		return false;
	}

	if (dns_response_code(resp->flags) != DNS_REFUSED) {
		printf("Update returned %u\n", dns_response_code(resp->flags));
		return false;
	}

	/* FIXME: is there _any_ way to unmarshal the response to check this? */

	return true;
}
Пример #2
0
/* like sec_accept, but first it gets the remote system's hostname */
static void
ssh_accept(
    const security_driver_t *driver,
    char       *(*conf_fn)(char *, void *),
    int		in,
    int		out,
    void	(*fn)(security_handle_t *, pkt_t *),
    void       *datap)
{
    struct sec_handle *rh;
    struct tcp_conn *rc = sec_tcp_conn_get(NULL, "", 0);
    char *ssh_connection, *p;
    char *errmsg = NULL;
    sockaddr_union addr;
    int result;

    /* "Accepting" an SSH connection means that amandad was invoked via sshd, so
     * we should have anSSH_CONNECTION env var.  If not, then this probably isn't
     * a real SSH connection and we should bail out. */
    ssh_connection = getenv("SSH_CONNECTION");
    if (!ssh_connection) {
	errmsg = g_strdup("$SSH_CONNECTION not set - was amandad started by sshd?");
	goto error;
    }

    /* make a local copy, to munge */
    ssh_connection = g_strdup(ssh_connection);

    /* strip off the first component - the ASCII IP address */
    if ((p = strchr(ssh_connection, ' ')) == NULL) {
	errmsg = g_strdup("$SSH_CONNECTION malformed");
	goto error;
    }
    *p = '\0';

    /* ---- everything from here on is just a warning, leaving hostname at "" */

    SU_INIT(&addr, AF_INET);

    /* turn the string address into a sockaddr */
    if ((result = str_to_sockaddr(ssh_connection, &addr)) != 1) {
	if (result == 0) {
	    g_warning("Could not parse peer address %s", ssh_connection);
	} else {
	    g_warning("Parsing peer address %s: %s", ssh_connection, gai_strerror(result));
	}
	goto done;
    }

    /* find the hostname */
    result = getnameinfo((struct sockaddr *)&addr, SS_LEN(&addr),
		 rc->hostname, sizeof(rc->hostname), NULL, 0, 0);
    if (result != 0) {
	g_warning("Could not get hostname for SSH client %s: %s", ssh_connection,
		gai_strerror(result));
	goto done;
    }

    /* and verify it */
    if (check_name_give_sockaddr(rc->hostname,
				 (struct sockaddr *)&addr, &errmsg) < 0) {
	rc->hostname[0] = '\0'; /* null out the bad hostname */
	g_warning("Checking SSH client DNS: %s", errmsg);
	amfree(errmsg);
	goto done;
    }

done:
    g_free(ssh_connection);

    rc->read = in;
    rc->write = out;
    rc->accept_fn = fn;
    rc->driver = driver;
    rc->conf_fn = conf_fn;
    rc->datap = datap;
    sec_tcp_conn_read(rc);
    return;

error:
    if (ssh_connection)
	g_free(ssh_connection);

    /* make up a fake handle for the error */
    rh = g_new0(struct sec_handle, 1);
    security_handleinit(&rh->sech, driver);
    security_seterror((security_handle_t*)rh, "ssh_accept: %s", errmsg);
    amfree(errmsg);
    (*fn)(&rh->sech, NULL);
}
Пример #3
0
static int
do_directtcp_connect(
    XferElementGlue *self,
    DirectTCPAddr *addrs)
{
    XferElement *elt = XFER_ELEMENT(self);
    sockaddr_union addr;
    int sock;
#ifdef WORKING_IPV6
    char strsockaddr[INET6_ADDRSTRLEN + 20];
#else
    char strsockaddr[INET_ADDRSTRLEN + 20];
#endif

    if (!addrs) {
	g_debug("element-glue got no directtcp addresses to connect to!");
	if (!elt->cancelled) {
	    xfer_cancel_with_error(elt,
		"%s got no directtcp addresses to connect to",
		xfer_element_repr(elt));
	}
	goto cancel_wait;
    }

    /* set up the sockaddr -- IPv4 only */
    copy_sockaddr(&addr, addrs);

    str_sockaddr_r(&addr, strsockaddr, sizeof(strsockaddr));

    if (strncmp(strsockaddr,"255.255.255.255:", 16) == 0) {
	char  buffer[32770];
	char *s;
	int   size;
	char *data_host;
	int   data_port;

	g_debug("do_directtcp_connect making indirect data connection to %s",
		strsockaddr);
	data_port = SU_GET_PORT(&addr);
	sock = stream_client(NULL, "localhost", data_port,
                                   STREAM_BUFSIZE, 0, NULL, 0);
	if (sock < 0) {
	    xfer_cancel_with_error(elt, "stream_client(): %s", strerror(errno));
	    goto cancel_wait;
	}
	size = full_read(sock, buffer, 32768);
	if (size < 0 ) {
	    xfer_cancel_with_error(elt, "failed to read from indirecttcp: %s",
				   strerror(errno));
	    goto cancel_wait;
	}
	close(sock);
	buffer[size++] = ' ';
	buffer[size] = '\0';
	if ((s = strchr(buffer, ':')) == NULL) {
	    xfer_cancel_with_error(elt,
				   "Failed to parse indirect data stream: %s",
				   buffer);
	    goto cancel_wait;
	}
	*s++ = '\0';
	data_host = buffer;
	data_port = atoi(s);

	str_to_sockaddr(data_host, &addr);
	SU_SET_PORT(&addr, data_port);

	str_sockaddr_r(&addr, strsockaddr, sizeof(strsockaddr));
    }

    sock = socket(SU_GET_FAMILY(&addr), SOCK_STREAM, 0);

    g_debug("do_directtcp_connect making data connection to %s", strsockaddr);

    if (sock < 0) {
	xfer_cancel_with_error(elt,
	    "socket(): %s", strerror(errno));
	goto cancel_wait;
    }
    if (connect(sock, (struct sockaddr *)&addr, SS_LEN(&addr)) < 0) {
	xfer_cancel_with_error(elt,
	    "connect(): %s", strerror(errno));
	close(sock);
	goto cancel_wait;
    }

    g_debug("do_directtcp_connect: connected to %s, fd %d", strsockaddr, sock);

    return sock;

cancel_wait:
    wait_until_xfer_cancelled(elt->xfer);
    return -1;
}