Esempio n. 1
0
static int
do_handshake (socket_st * socket)
{
  int ret;

  gnutls_transport_set_ptr (socket->session,
			    (gnutls_transport_ptr_t)
			    gl_fd_to_handle (socket->fd));
  do
    {
      ret = gnutls_handshake (socket->session);

      if (ret < 0)
	{
	  handle_error (socket, ret);
	}
    }
  while (ret < 0 && gnutls_error_is_fatal (ret) == 0);

  if (ret == 0)
    {
      /* print some information */
      print_info (socket->session, socket->hostname, info.insecure);


      socket->secure = 1;

    }
  else
    {
      gnutls_alert_send_appropriate (socket->session, ret);
      shutdown (socket->fd, SHUT_RDWR);
    }
  return ret;
}
Esempio n. 2
0
static int handle_ssl_error(struct ssl_proxy *proxy, int error)
{
	if (!gnutls_error_is_fatal(error)) {
		if (!verbose_ssl)
			return 0;

		if (error == GNUTLS_E_WARNING_ALERT_RECEIVED) {
			i_warning("Received SSL warning alert: %s [%s]",
				  get_alert_text(proxy),
				  net_ip2addr(&proxy->ip));
		} else {
			i_warning("Non-fatal SSL error: %s: %s",
				  get_alert_text(proxy),
				  net_ip2addr(&proxy->ip));
		}
		return 0;
	}

	if (verbose_ssl) {
		/* fatal error occurred */
		if (error == GNUTLS_E_FATAL_ALERT_RECEIVED) {
			i_warning("Received SSL fatal alert: %s [%s]",
				  get_alert_text(proxy),
				  net_ip2addr(&proxy->ip));
		} else {
			i_warning("Error reading from SSL client: %s [%s]",
				  gnutls_strerror(error),
				  net_ip2addr(&proxy->ip));
		}
	}

        gnutls_alert_send_appropriate(proxy->session, error);
	ssl_proxy_destroy(proxy);
	return -1;
}
Esempio n. 3
0
static gnutls_session new_tls_session(int sock)
{
        int ret;
        gnutls_session session;
        const int kx_priority[] = {
                GNUTLS_KX_ANON_DH,
#ifdef GNUTLS_SRP_ENABLED
                GNUTLS_KX_SRP, GNUTLS_KX_SRP_DSS, GNUTLS_KX_SRP_RSA,
#endif
                0 };

        gnutls_init(&session, GNUTLS_SERVER);

        gnutls_set_default_priority(session);
        gnutls_kx_set_priority(session, kx_priority);

#ifdef GNUTLS_SRP_ENABLED
        gnutls_credentials_set(session, GNUTLS_CRD_SRP, srpcred);
        gnutls_certificate_server_set_request(session, GNUTLS_CERT_IGNORE);
#endif
        gnutls_credentials_set(session, GNUTLS_CRD_ANON, anoncred);

        gnutls_transport_set_ptr(session, fd_to_ptr(sock));
        gnutls_transport_set_pull_function(session, tls_pull);
        gnutls_transport_set_push_function(session, tls_push);

        ret = gnutls_handshake(session);
        if ( ret < 0 ) {
                fprintf(stderr, "GnuTLS handshake failed: %s.\n", gnutls_strerror(ret));
                gnutls_alert_send_appropriate(session, ret);
                return NULL;
        }

        return session;
}
Esempio n. 4
0
File: cli.c Progetto: nobled/gnutls
static int
do_handshake (socket_st * socket)
{
  int ret;

  gnutls_transport_set_ptr (socket->session,
                            (gnutls_transport_ptr_t)
                            gl_fd_to_handle (socket->fd));
  do
    {
      gnutls_handshake_set_timeout( socket->session, GNUTLS_DEFAULT_HANDSHAKE_TIMEOUT);
      ret = gnutls_handshake (socket->session);

      if (ret < 0)
        {
          handle_error (socket, ret);
        }
    }
  while (ret < 0 && gnutls_error_is_fatal (ret) == 0);

  if (ret == 0)
    {
      /* print some information */
      print_info (socket->session, verbose, 0);
      socket->secure = 1;
    }
  else
    {
      gnutls_alert_send_appropriate (socket->session, ret);
      shutdown (socket->fd, SHUT_RDWR);
    }
  return ret;
}
Esempio n. 5
0
static void f_close_with_alert(liGnuTLSFilter *f, int r) {
	if (f->closing || f->aborted) return;

	if (GNUTLS_E_SUCCESS != gnutls_alert_send_appropriate(f->session, r)) {
		f_abort_gnutls(f);
		return;
	}

	/* push alert to io */
	li_stream_notify(&f->crypt_source);
	f->plain_source.out->is_closed = TRUE;
	f->crypt_drain.out->is_closed = TRUE;
	f_close_gnutls(f);
}
Esempio n. 6
0
static gnutls_session_t new_tls_session(int sock)
{
        int ret;
        gnutls_session_t session;
        const char *err;

#if defined LIBGNUTLS_VERSION_MAJOR && LIBGNUTLS_VERSION_MAJOR >= 3
# define TLS_DH_STR "+ANON-ECDH:+ANON-DH"
#else
# define TLS_DH_STR "+ANON-DH"
#endif

#ifdef GNUTLS_SRP_ENABLED
        const char *pstring = "NORMAL:+SRP:+SRP-DSS:+SRP-RSA:" TLS_DH_STR;
#else
        const char *pstring = "NORMAL:" TLS_DH_STR;
#endif

        gnutls_init(&session, GNUTLS_SERVER);
        gnutls_set_default_priority(session);

        ret = gnutls_priority_set_direct(session, pstring, &err);
        if (ret < 0) {
                fprintf(stderr, "TLS priority syntax error at: %s\n", err);
                return NULL;
        }

#ifdef GNUTLS_SRP_ENABLED
        gnutls_credentials_set(session, GNUTLS_CRD_SRP, srpcred);
        gnutls_certificate_server_set_request(session, GNUTLS_CERT_IGNORE);
#endif
        gnutls_credentials_set(session, GNUTLS_CRD_ANON, anoncred);

        gnutls_transport_set_ptr(session, fd_to_ptr(sock));
        gnutls_transport_set_pull_function(session, tls_pull);
        gnutls_transport_set_push_function(session, tls_push);

        ret = gnutls_handshake(session);
        if ( ret < 0 ) {
                fprintf(stderr, "GnuTLS handshake failed: %s.\n", gnutls_strerror(ret));
                gnutls_alert_send_appropriate(session, ret);
                return NULL;
        }

        return session;
}
Esempio n. 7
0
/** Handles one client.
 * This one connects to the remote server, and proxies every traffic
 * between our client and the server.
 *
 * @param config is the main CryWrap configuration structure.
 * @param insock is the socket through which the client sends input.
 * @param outsock is the socket through which we send output.
 *
 * @note Exits on error.
 */
static int
_crywrap_do_one(const crywrap_config_t * config, int insock, int outsock)
{
	int sock, ret, tls_pending;
	gnutls_session_t session;
	char buffer[_CRYWRAP_MAXBUF + 2];
	fd_set fdset;
	unsigned int status = 0;
	struct sockaddr_storage faddr;
	socklen_t socklen = sizeof(struct sockaddr_storage);
	char peer_name[NI_MAXHOST];

	/* Log the connection */
	if (getpeername(insock, (struct sockaddr *) &faddr, &socklen) != 0)
		cry_error("getpeername(): %s", strerror(errno));
	else {
		getnameinfo((struct sockaddr *) &faddr,
			    sizeof(struct sockaddr_storage), peer_name,
			    sizeof(peer_name), NULL, 0, NI_NUMERICHOST);
		cry_log("Accepted connection from %s on %d to %s/%d",
			peer_name, insock, config->dest.host,
			config->dest.port);
	}

	/* Do the handshake with our peer */
	session = _crywrap_tls_session_create(config);
	gnutls_transport_set_ptr2(session,
				  (gnutls_transport_ptr_t) insock,
				  (gnutls_transport_ptr_t) outsock);

	do {
		ret = gnutls_handshake(session);
	}
	while (ret == GNUTLS_E_AGAIN || ret == GNUTLS_E_INTERRUPTED);

	if (ret < 0) {
		cry_error("Handshake failed: %s", gnutls_strerror(ret));
		gnutls_alert_send_appropriate(session, ret);
		goto error;
	}

	/* Verify the client's certificate, if any. */
	if (config->verify) {
		ret = gnutls_certificate_verify_peers2(session, &status);
		if (ret < 0)
			cry_log
			    ("Error getting certificate from client: %s",
			     gnutls_strerror(ret));

		if (ret == 0 && status != 0) {
			if (status & GNUTLS_CERT_INVALID)
				cry_log("%s",
					"Client certificate not trusted or invalid");
		}

		if (config->verify > 0 && status != 0) {
			ret = -1;
			gnutls_alert_send(session, GNUTLS_AL_FATAL,
					  GNUTLS_A_INSUFFICIENT_SECURITY);
			goto error;
		}
	}

	/* Connect to the remote host */
	sock = _crywrap_remote_connect(config->dest.addr,
				       htons(config->dest.port));

	for (;;) {
		FD_ZERO(&fdset);
		FD_SET(insock, &fdset);
		FD_SET(sock, &fdset);

		memset(buffer, 0, _CRYWRAP_MAXBUF + 1);

		tls_pending = 0;

		if (gnutls_record_check_pending(session) > 0)
			tls_pending = 1;
		else {
			select(sock + 1, &fdset, NULL, NULL, NULL);
			if (FD_ISSET(insock, &fdset))
				tls_pending = 1;
		}
		/* TLS client */
		if (tls_pending != 0) {
			ret =
			    gnutls_record_recv(session, buffer,
					       _CRYWRAP_MAXBUF);
			if (ret == 0) {
				cry_log("%s",
					"Peer has closed the GNUTLS connection");
				break;
			} else if (ret < 0) {
				cry_log("Received corrupted data: %s.",
					gnutls_strerror(ret));
				break;
			} else
				send(sock, buffer, ret, 0);
		}

		/* Remote server */
		if (FD_ISSET(sock, &fdset)) {
			ret = recv(sock, buffer, _CRYWRAP_MAXBUF, 0);
			if (ret == 0) {
				cry_log("%s",
					"Server has closed the connection");
				break;
			} else if (ret < 0) {
				cry_log("Received corrupted data: %s.",
					strerror(errno));
				break;
			} else {
				int r, o = 0;

				do {
					r = gnutls_record_send(session,
							       &buffer[o],
							       ret - o);
					o += r;
				} while (r > 0 && ret > o);

				if (r < 0)
					cry_log
					    ("Received corrupt data: %s",
					     gnutls_strerror(r));
			}
		}
	}

      error:
	gnutls_bye(session, GNUTLS_SHUT_WR);
	gnutls_deinit(session);
	close(insock);
	close(outsock);

	return (ret == 0) ? 0 : 1;
}
int session::send_appropriate_alert (int err)
{
    return RETWRAP (gnutls_alert_send_appropriate (s, err));
}