Example #1
0
static const char *obtain_cert(const char *hostname, const char *proto, unsigned port,
				const char *app_proto, unsigned quiet)
{
	socket_st hd;
	char txt_port[16];
	unsigned udp = 0;
	static char tmpfile[32];
	int fd, ret;
	const char *str = "Obtaining certificate from";
	const char *service;

	if (strcmp(proto, "udp") == 0)
		udp = 1;
	else if (strcmp(proto, "tcp") != 0) {
		/* we cannot handle this protocol */
		return NULL;
	}

	strcpy(tmpfile, "danetool-certXXXXXX");

	sockets_init();
	snprintf(txt_port, sizeof(txt_port), "%u", port);

	if (quiet)
		str = NULL;
	service = port_to_service(txt_port, proto);
	socket_open(&hd, hostname, service, udp, str);

	if (app_proto == NULL) app_proto = service;
	socket_starttls(&hd, app_proto);

	umask(066);
	fd = mkstemp(tmpfile);
	if (fd == -1) {
		int e = errno;
		fprintf(stderr, "error[%d]: %s\n", __LINE__,
			strerror(e));
		exit(1);
	}

	ret = get_cert(&hd, hostname, udp, fd);
	close(fd);

	socket_bye(&hd);

	if (ret == -1)
		return NULL;
	else
		return tmpfile;
}
Example #2
0
void
socket_open(socket_st * hd, const char *hostname, const char *service,
	    const char *app_proto, int flags, const char *msg, gnutls_datum_t *rdata)
{
	struct addrinfo hints, *res, *ptr;
	int sd, err = 0;
	int udp = flags & SOCKET_FLAG_UDP;
	int ret;
	int fastopen = flags & SOCKET_FLAG_FASTOPEN;
	char buffer[MAX_BUF + 1];
	char portname[16] = { 0 };
	gnutls_datum_t idna;
	char *a_hostname;

	memset(hd, 0, sizeof(*hd));

	if (flags & SOCKET_FLAG_VERBOSE)
		hd->verbose = 1;

	if (rdata) {
		hd->rdata.data = rdata->data;
		hd->rdata.size = rdata->size;
	}

	ret = gnutls_idna_map(hostname, strlen(hostname), &idna, 0);
	if (ret < 0) {
		fprintf(stderr, "Cannot convert %s to IDNA: %s\n", hostname, gnutls_strerror(ret));
		exit(1);
	}

	hd->hostname = strdup(hostname);
	a_hostname = (char*)idna.data;

	if (msg != NULL)
		printf("Resolving '%s:%s'...\n", a_hostname, service);

	/* get server name */
	memset(&hints, 0, sizeof(hints));
	hints.ai_socktype = udp ? SOCK_DGRAM : SOCK_STREAM;
	if ((err = getaddrinfo(a_hostname, service, &hints, &res))) {
		fprintf(stderr, "Cannot resolve %s:%s: %s\n", hostname,
			service, gai_strerror(err));
		exit(1);
	}

	sd = -1;
	for (ptr = res; ptr != NULL; ptr = ptr->ai_next) {
		sd = socket(ptr->ai_family, ptr->ai_socktype,
			    ptr->ai_protocol);
		if (sd == -1)
			continue;

		if ((err =
		     getnameinfo(ptr->ai_addr, ptr->ai_addrlen, buffer,
				 MAX_BUF, portname, sizeof(portname),
				 NI_NUMERICHOST | NI_NUMERICSERV)) != 0) {
			fprintf(stderr, "getnameinfo(): %s\n",
				gai_strerror(err));
			continue;
		}

		if (hints.ai_socktype == SOCK_DGRAM) {
#if defined(IP_DONTFRAG)
			int yes = 1;
			if (setsockopt(sd, IPPROTO_IP, IP_DONTFRAG,
				       (const void *) &yes,
				       sizeof(yes)) < 0)
				perror("setsockopt(IP_DF) failed");
#elif defined(IP_MTU_DISCOVER)
			int yes = IP_PMTUDISC_DO;
			if (setsockopt(sd, IPPROTO_IP, IP_MTU_DISCOVER,
				       (const void *) &yes,
				       sizeof(yes)) < 0)
				perror("setsockopt(IP_DF) failed");
#endif
		}

		if (fastopen && ptr->ai_socktype == SOCK_STREAM
		    && (ptr->ai_family == AF_INET || ptr->ai_family == AF_INET6)) {
			memcpy(&hd->connect_addr, ptr->ai_addr, ptr->ai_addrlen);
			hd->connect_addrlen = ptr->ai_addrlen;

			if (msg)
				printf("%s '%s:%s' (TFO)...\n", msg, buffer, portname);

		} else {
			if (msg)
				printf("%s '%s:%s'...\n", msg, buffer, portname);

			if ((err = connect(sd, ptr->ai_addr, ptr->ai_addrlen)) < 0)
				continue;
		}

		hd->fd = sd;
		if (flags & SOCKET_FLAG_STARTTLS) {
			hd->app_proto = app_proto;
			socket_starttls(hd);
			hd->app_proto = NULL;
		}

		if (!(flags & SOCKET_FLAG_SKIP_INIT)) {
			hd->session = init_tls_session(hostname);
			if (hd->session == NULL) {
				fprintf(stderr, "error initializing session\n");
				exit(1);
			}
		}

		if (hd->session) {
			if (hd->rdata.data) {
				gnutls_session_set_data(hd->session, hd->rdata.data, hd->rdata.size);
			}

			gnutls_transport_set_int(hd->session, sd);
		}

		if (!(flags & SOCKET_FLAG_RAW) && !(flags & SOCKET_FLAG_SKIP_INIT)) {
			err = do_handshake(hd);
			if (err == GNUTLS_E_PUSH_ERROR) { /* failed connecting */
				gnutls_deinit(hd->session);
				hd->session = NULL;
				continue;
			}
			else if (err < 0) {
				fprintf(stderr, "*** handshake has failed: %s\n", gnutls_strerror(err));
				exit(1);
			}
		}

		break;
	}

	if (err != 0) {
		int e = errno;
		fprintf(stderr, "Could not connect to %s:%s: %s\n",
				buffer, portname, strerror(e));
		exit(1);
	}

	if (sd == -1) {
		fprintf(stderr, "Could not find a supported socket\n");
		exit(1);
	}

	if ((flags & SOCKET_FLAG_RAW) || (flags & SOCKET_FLAG_SKIP_INIT))
		hd->secure = 0;
	else
		hd->secure = 1;

	hd->fd = sd;
	hd->ip = strdup(buffer);
	hd->service = strdup(portname);
	hd->ptr = ptr;
	hd->addr_info = res;
	hd->rdata.data = NULL;
	gnutls_free(idna.data);
	return;
}
Example #3
0
int main(int argc, char **argv)
{
	int ret;
	int i;
	gnutls_session_t state;
	char portname[6];
	socket_st hd;
	char app_proto[32] = "";

	cmd_parser(argc, argv);

#ifndef _WIN32
	signal(SIGPIPE, SIG_IGN);
#endif

	sockets_init();

	if (gnutls_global_init() < 0) {
		fprintf(stderr, "global state initialization error\n");
		exit(1);
	}

	gnutls_global_set_log_function(tls_log_func);
	gnutls_global_set_log_level(debug);

	/* get server name */
	snprintf(portname, sizeof(portname), "%d", port);

	/* X509 stuff */
	if (gnutls_certificate_allocate_credentials(&xcred) < 0) {	/* space for 2 certificates */
		fprintf(stderr, "memory error\n");
		exit(1);
	}

	/* SRP stuff */
#ifdef ENABLE_SRP
	if (gnutls_srp_allocate_client_credentials(&srp_cred) < 0) {
		fprintf(stderr, "memory error\n");
		exit(1);
	}
#endif

#ifdef ENABLE_ANON
	/* ANON stuff */
	if (gnutls_anon_allocate_client_credentials(&anon_cred) < 0) {
		fprintf(stderr, "memory error\n");
		exit(1);
	}
#endif

	if (HAVE_OPT(STARTTLS_PROTO)) {
		snprintf(app_proto, sizeof(app_proto), "%s", OPT_ARG(STARTTLS_PROTO));
	}

	if (app_proto[0] == 0) {
		snprintf(app_proto, sizeof(app_proto), "%s", port_to_service(portname, "tcp"));
	}

	sockets_init();

	i = 0;

	printf("GnuTLS debug client %s\n", gnutls_check_version(NULL));
	printf("Checking %s:%s\n", hostname, portname);
	do {

		if (tls_tests[i].test_name == NULL)
			break;	/* finished */

		/* if neither of SSL3 and TLSv1 are supported, exit
		 */
		if (i > 6 && tls1_2_ok == 0 && tls1_1_ok == 0 && tls1_ok == 0
		    && ssl3_ok == 0) {
			fprintf(stderr,
				"\nServer does not support any of SSL 3.0, TLS 1.0 and TLS 1.1 and TLS 1.2\n");
			break;
		}

		socket_open(&hd, hostname, portname, 0, NULL);
		hd.verbose = verbose;

		socket_starttls(&hd, app_proto);

		gnutls_init(&state, GNUTLS_CLIENT | GNUTLS_NO_EXTENSIONS);

		gnutls_transport_set_ptr(state, (gnutls_transport_ptr_t)
					 gl_fd_to_handle(hd.fd));
		set_read_funcs(state);
		if (hostname && is_ip(hostname) == 0)
			gnutls_server_name_set(state, GNUTLS_NAME_DNS,
					       hostname, strlen(hostname));

		do {
			if (strcmp(app_proto, "https") != 0 && tls_tests[i].https_only != 0) {
				i++;
				break;
			}

			ret = tls_tests[i].func(state);

			if (ret != TEST_IGNORE) {
				printf("%58s...", tls_tests[i].test_name);
				fflush(stdout);
			}

			if (ret == TEST_SUCCEED) {
				if (tls_tests[i].suc_str == NULL)
					printf(" %s\n", ext_text);
				else
					printf(" %s\n", tls_tests[i].suc_str);
			} else if (ret == TEST_FAILED)
				printf(" %s\n", tls_tests[i].fail_str);
			else if (ret == TEST_UNSURE)
				printf(" %s\n", tls_tests[i].unsure_str);
			else if (ret == TEST_IGNORE) {
				if (tls_tests[i+1].test_name)
					i++;
				else
					break;
			}
		}
		while (ret == TEST_IGNORE
		       && tls_tests[i].test_name != NULL);

		gnutls_deinit(state);

		socket_bye(&hd);

		i++;
	}
	while (1);

#ifdef ENABLE_SRP
	gnutls_srp_free_client_credentials(srp_cred);
#endif
	gnutls_certificate_free_credentials(xcred);
#ifdef ENABLE_ANON
	gnutls_anon_free_client_credentials(anon_cred);
#endif
	gnutls_global_deinit();

	return 0;
}