Esempio n. 1
0
static int _init_server(OpenSSL * openssl, char const * name)
{
	String * crt;
	struct sockaddr_in sa;

	if((crt = string_new_append(SYSCONFDIR, "/AppServer/", name, ".crt"))
			== NULL)
		return -1;
	if((openssl->ssl_ctx = SSL_CTX_new(SSLv3_server_method())) == NULL
			|| SSL_CTX_set_cipher_list(openssl->ssl_ctx,
				SSL_DEFAULT_CIPHER_LIST) != 1
			|| SSL_CTX_use_certificate_file(openssl->ssl_ctx, crt,
				SSL_FILETYPE_PEM) == 0
			|| SSL_CTX_use_PrivateKey_file(openssl->ssl_ctx, crt,
				SSL_FILETYPE_PEM) == 0)
	{
		string_delete(crt);
		return -_openssl_error_ssl(1);
	}
	string_delete(crt);
	if((openssl->fd = socket(AF_INET, SOCK_STREAM, 0)) < 0)
		return -_openssl_error("socket", 1);
	sa.sin_family = AF_INET;
	sa.sin_port = htons(4242); /* XXX hard-coded */
	sa.sin_addr.s_addr = htonl(INADDR_ANY);
	if(bind(openssl->fd, (struct sockaddr *)&sa, sizeof(sa)) != 0)
		return -_openssl_error("bind", 1);
	if(listen(openssl->fd, 5) != 0)
		return -_openssl_error("listen", 1);
	event_register_io_read(openssl->helper->event, openssl->fd,
			(EventIOFunc)_openssl_callback_accept, openssl);
	return 0;
}
Esempio n. 2
0
static int _accept_client(SSLTransport * transport, int fd, SSL * ssl,
		struct sockaddr * sa, socklen_t sa_len)
{
	SSLSocket * sslsocket;

#ifdef DEBUG
	fprintf(stderr, "DEBUG: %s(%d)\n", __func__, fd);
#endif
	if((sslsocket = _ssl_socket_new_fd(transport, fd, ssl, sa, sa_len))
			== NULL)
		return -1;
	if(_ssl_server_add_client(transport, sslsocket) != 0)
	{
		/* XXX workaround for a double-close() */
		sslsocket->fd = -1;
		_ssl_socket_delete(sslsocket);
		return -1;
	}
	SSL_set_accept_state(sslsocket->ssl);
	event_register_io_read(transport->helper->event, sslsocket->fd,
			(EventIOFunc)_ssl_socket_callback_read, sslsocket);
#ifdef DEBUG
	fprintf(stderr, "DEBUG: %s(%d) => 0\n", __func__, fd);
#endif
	return 0;
}
Esempio n. 3
0
static int _init_client(SSLTransport * ssl, char const * name)
{
	struct addrinfo * aip;
#ifdef DEBUG
	struct sockaddr_in * sa;
#endif

	ssl->u.client.transport = ssl;
	ssl->u.client.fd = -1;
	/* obtain the remote address */
	if((ssl->ai = _init_address(name, TCP_FAMILY, 0)) == NULL)
		return -1;
	/* connect to the remote host */
	for(aip = ssl->ai; aip != NULL; aip = aip->ai_next)
	{
		ssl->u.client.fd = -1;
		/* initialize the client socket */
		if(_ssl_socket_init(&ssl->u.client, aip->ai_family, ssl) != 0)
			continue;
#ifdef DEBUG
		if(aip->ai_family == AF_INET)
		{
			sa = (struct sockaddr_in *)aip->ai_addr;
			fprintf(stderr, "DEBUG: %s() %s (%s:%u)\n", __func__,
					"connect()", inet_ntoa(sa->sin_addr),
					ntohs(sa->sin_port));
		}
		else
			fprintf(stderr, "DEBUG: %s() %s %d\n", __func__,
					"connect()", aip->ai_family);
#endif
		if(connect(ssl->u.client.fd, aip->ai_addr, aip->ai_addrlen)
				!= 0)
		{
			if(errno != EINPROGRESS)
			{
				close(ssl->u.client.fd);
				ssl->u.client.fd = -1;
				_ssl_error("socket", 1);
				continue;
			}
			event_register_io_write(ssl->helper->event,
					ssl->u.client.fd,
					(EventIOFunc)_ssl_callback_connect,
					ssl);
		}
		else
			/* listen for any incoming message */
			event_register_io_read(ssl->helper->event,
					ssl->u.client.fd,
					(EventIOFunc)_ssl_socket_callback_read,
					&ssl->u.client);
		ssl->ai_addrlen = aip->ai_addrlen;
		break;
	}
	freeaddrinfo(ssl->ai);
	ssl->ai = NULL;
	return (aip != NULL) ? 0 : -1;
}
Esempio n. 4
0
static int _init_server(SSLTransport * ssl, char const * name)
{
	struct addrinfo * aip;
	SSLSocket sslsocket;
#ifdef DEBUG
	struct sockaddr_in * sa;
#endif

	ssl->u.server.fd = -1;
	/* obtain the local address */
	if((ssl->ai = _init_address(name, TCP_FAMILY, AI_PASSIVE)) == NULL)
		return -1;
	for(aip = ssl->ai; aip != NULL; aip = aip->ai_next)
	{
		/* create the socket */
		if(_ssl_socket_init(&sslsocket, aip->ai_family, ssl) != 0)
			continue;
		/* XXX ugly */
		ssl->u.server.fd = sslsocket.fd;
		/* accept incoming connections */
#ifdef DEBUG
		if(aip->ai_family == AF_INET)
		{
			sa = (struct sockaddr_in *)aip->ai_addr;
			fprintf(stderr, "DEBUG: %s() %s (%s:%u)\n", __func__,
					"bind()", inet_ntoa(sa->sin_addr),
					ntohs(sa->sin_port));
		}
		else
			fprintf(stderr, "DEBUG: %s() %s %d\n", __func__,
					"bind()", aip->ai_family);
#endif
		if(bind(ssl->u.server.fd, aip->ai_addr, aip->ai_addrlen) != 0)
		{
			_ssl_error("bind", 1);
			close(ssl->u.server.fd);
			ssl->u.server.fd = -1;
			continue;
		}
#ifdef DEBUG
		fprintf(stderr, "DEBUG: %s() %s\n", __func__, "listen()");
#endif
		if(listen(ssl->u.server.fd, SOMAXCONN) != 0)
		{
			_ssl_error("listen", 1);
			close(ssl->u.server.fd);
			ssl->u.server.fd = -1;
			continue;
		}
		ssl->ai_addrlen = aip->ai_addrlen;
		event_register_io_read(ssl->helper->event, ssl->u.server.fd,
				(EventIOFunc)_ssl_callback_accept, ssl);
		break;
	}
	freeaddrinfo(ssl->ai);
	ssl->ai = NULL;
	return (aip != NULL) ? 0 : -1;
}
Esempio n. 5
0
/* ssl_callback_connect */
static int _ssl_callback_connect(int fd, SSLTransport * transport)
{
	int res;
	socklen_t s = sizeof(res);

#ifdef DEBUG
	fprintf(stderr, "DEBUG: %s(%d)\n", __func__, fd);
#endif
	/* check parameters */
	if(transport->u.client.fd != fd)
		return -1;
	/* obtain the connection status */
	if(getsockopt(fd, SOL_SOCKET, SO_ERROR, &res, &s) != 0)
	{
		error_set_code(1, "%s: %s", "getsockopt", strerror(errno));
		SSL_free(transport->u.client.ssl);
		transport->u.client.ssl = NULL;
		close(fd);
		transport->u.client.fd = -1;
		/* FIXME report error */
#ifdef DEBUG
		fprintf(stderr, "DEBUG: %s() %s\n", __func__, strerror(errno));
#endif
		return -1;
	}
	if(res != 0)
	{
		/* the connection failed */
		error_set_code(1, "%s: %s", "connect", strerror(res));
		SSL_free(transport->u.client.ssl);
		transport->u.client.ssl = NULL;
		close(fd);
		transport->u.client.fd = -1;
		/* FIXME report error */
#ifdef DEBUG
		fprintf(stderr, "DEBUG: %s() %s\n", __func__, strerror(res));
#endif
		return -1;
	}
	SSL_set_connect_state(transport->u.client.ssl);
	/* listen for any incoming message */
	event_register_io_read(transport->helper->event, fd,
			(EventIOFunc)_ssl_socket_callback_read,
			&transport->u.client);
	/* write pending messages if any */
	if(transport->u.client.bufout_cnt > 0)
	{
		event_register_io_write(transport->helper->event, fd,
				(EventIOFunc)_ssl_socket_callback_write,
				&transport->u.client);
		return 0;
	}
	return 1;
}
Esempio n. 6
0
static int _socket_callback_recv(SSLSocket * sslsocket)
{
	const size_t inc = INC;
	int ssize;
	char * p;
	int err;
	char buf[128];

	if((p = realloc(sslsocket->bufin, sslsocket->bufin_cnt + inc)) == NULL)
		return -1;
	sslsocket->bufin = p;
	if((ssize = SSL_read(sslsocket->ssl,
					&sslsocket->bufin[sslsocket->bufin_cnt],
					inc)) <= 0)
	{
		/* FIXME not tested */
		if((err = SSL_get_error(sslsocket->ssl, ssize))
				== SSL_ERROR_WANT_WRITE)
		{
			event_unregister_io_write(
					sslsocket->transport->helper->event,
					sslsocket->fd);
			event_register_io_write(
					sslsocket->transport->helper->event,
					sslsocket->fd,
					(EventIOFunc)_ssl_socket_callback_read,
					sslsocket);
			return 1;
		}
		else if(err == SSL_ERROR_WANT_READ)
		{
			event_register_io_read(
					sslsocket->transport->helper->event,
					sslsocket->fd,
					(EventIOFunc)_ssl_socket_callback_read,
					sslsocket);
			return 1;
		}
		else
		{
			/* XXX report error (and reconnect clients) */
			ERR_error_string(err, buf);
			error_set_code(1, "%s", buf);
			SSL_free(sslsocket->ssl);
			sslsocket->ssl = NULL;
			close(sslsocket->fd);
			sslsocket->fd = -1;
			return -1;
		}
	}
	sslsocket->bufin_cnt += ssize;
	return 0;
}