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; }
/* 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); }
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; }