示例#1
0
void
server_start (void)
{
  /* this must be called once in the program
   */
  gnutls_global_init ();

  gnutls_global_set_log_function (tls_log_func);
//  gnutls_global_set_log_level (99);

  generate_dh_params ();

  gnutls_psk_allocate_server_credentials (&server_pskcred);
  gnutls_psk_set_server_credentials_function (server_pskcred, pskfunc);
  gnutls_psk_set_server_dh_params (server_pskcred, dh_params);

  success ("Launched, generating DH parameters...\n");

  /* Socket operations
   */
  listen_sd = socket (AF_INET, SOCK_STREAM, 0);
  if (err == -1)
    {
      perror ("socket");
      fail ("server: socket failed\n");
      return;
    }

  memset (&sa_serv, '\0', sizeof (sa_serv));
  sa_serv.sin_family = AF_INET;
  sa_serv.sin_addr.s_addr = INADDR_ANY;
  sa_serv.sin_port = htons (PORT);	/* Server Port number */

  setsockopt (listen_sd, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof (int));

  err = bind (listen_sd, (SA *) & sa_serv, sizeof (sa_serv));
  if (err == -1)
    {
      perror ("bind");
      fail ("server: bind failed\n");
      return;
    }

  err = listen (listen_sd, 1024);
  if (err == -1)
    {
      perror ("listen");
      fail ("server: listen failed\n");
      return;
    }

  success ("server: ready. Listening to port '%d'.\n", PORT);
}
示例#2
0
static void
server (void)
{
  /* this must be called once in the program
   */
  gnutls_global_init ();

  gnutls_global_set_log_function (tls_log_func);
  if (debug)
    gnutls_global_set_log_level (4711);

  generate_dh_params ();

  gnutls_psk_allocate_server_credentials (&server_pskcred);
  gnutls_psk_set_server_credentials_function (server_pskcred, pskfunc);
  gnutls_psk_set_server_dh_params (server_pskcred, dh_params);

  client_len = sizeof (sa_cli);

  session = initialize_tls_session ();

  sd = accept (listen_sd, (SA *) & sa_cli, &client_len);

  if (debug)
    success ("server: connection from %s, port %d\n",
	     inet_ntop (AF_INET, &sa_cli.sin_addr, topbuf,
			sizeof (topbuf)), ntohs (sa_cli.sin_port));

  gnutls_transport_set_ptr (session, (gnutls_transport_ptr_t) sd);
  ret = gnutls_handshake (session);
  if (ret < 0)
    {
      close (sd);
      gnutls_deinit (session);
      fail ("server: Handshake has failed (%s)\n\n", gnutls_strerror (ret));
      return;
    }
  if (debug)
    success ("server: Handshake was completed\n");

  /* see the Getting peer's information example */
  /* print_info(session); */

  i = 0;
  for (;;)
    {
      memset (buffer, 0, MAX_BUF + 1);
      ret = gnutls_record_recv (session, buffer, MAX_BUF);

      if (ret == 0)
	{
	  if (debug)
	    success ("server: Peer has closed the GnuTLS connection\n");
	  break;
	}
      else if (ret < 0)
	{
	  fail ("server: Received corrupted data(%d). Closing...\n", ret);
	  break;
	}
      else if (ret > 0)
	{
	  /* echo data back to the client
	   */
	  gnutls_record_send (session, buffer, strlen (buffer));
	}
    }
  /* do not wait for the peer to close the connection.
   */
  gnutls_bye (session, GNUTLS_SHUT_WR);

  close (sd);
  gnutls_deinit (session);

  close (listen_sd);

  gnutls_psk_free_server_credentials (server_pskcred);

  gnutls_dh_params_deinit (dh_params);

  gnutls_global_deinit ();

  if (debug)
    success ("server: finished\n");
}
示例#3
0
int
main (void)
{
  int err, listen_sd, i;
  int sd, ret;
  struct sockaddr_in sa_serv;
  struct sockaddr_in sa_cli;
  int client_len;
  char topbuf[512];
  gnutls_session_t session;
  char buffer[MAX_BUF + 1];
  int optval = 1;

  /* to disallow usage of the blocking /dev/random 
   */
  gcry_control (GCRYCTL_ENABLE_QUICK_RANDOM, 0);

  /* this must be called once in the program
   */
  gnutls_global_init ();

  gnutls_certificate_allocate_credentials (&x509_cred);
  gnutls_certificate_set_x509_trust_file (x509_cred, CAFILE,
					  GNUTLS_X509_FMT_PEM);

  gnutls_certificate_set_x509_crl_file (x509_cred, CRLFILE,
					GNUTLS_X509_FMT_PEM);

  gnutls_certificate_set_x509_key_file (x509_cred, CERTFILE, KEYFILE,
					GNUTLS_X509_FMT_PEM);

  gnutls_psk_allocate_server_credentials (&psk_cred);
  gnutls_psk_set_server_credentials_function (psk_cred, pskfunc);

  generate_dh_params ();

  gnutls_priority_init (&priority_cache, "NORMAL:PSK", NULL);


  gnutls_certificate_set_dh_params (x509_cred, dh_params);

  /* Socket operations
   */
  listen_sd = socket (AF_INET, SOCK_STREAM, 0);
  SOCKET_ERR (listen_sd, "socket");

  memset (&sa_serv, '\0', sizeof (sa_serv));
  sa_serv.sin_family = AF_INET;
  sa_serv.sin_addr.s_addr = INADDR_ANY;
  sa_serv.sin_port = htons (PORT);	/* Server Port number */

  setsockopt (listen_sd, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof (int));

  err = bind (listen_sd, (SA *) & sa_serv, sizeof (sa_serv));
  SOCKET_ERR (err, "bind");
  err = listen (listen_sd, 1024);
  SOCKET_ERR (err, "listen");

  printf ("Server ready. Listening to port '%d'.\n\n", PORT);

  client_len = sizeof (sa_cli);
  for (;;)
    {
      session = initialize_tls_session ();

      sd = accept (listen_sd, (SA *) & sa_cli, &client_len);

      printf ("- connection from %s, port %d\n",
	      inet_ntop (AF_INET, &sa_cli.sin_addr, topbuf,
			 sizeof (topbuf)), ntohs (sa_cli.sin_port));

      gnutls_transport_set_ptr (session, (gnutls_transport_ptr_t) sd);
      ret = gnutls_handshake (session);
      if (ret < 0)
	{
	  close (sd);
	  gnutls_deinit (session);
	  fprintf (stderr, "*** Handshake has failed (%s)\n\n",
		   gnutls_strerror (ret));
	  continue;
	}
      printf ("- Handshake was completed\n");

      /* see the Getting peer's information example */
      /* print_info(session); */

      i = 0;
      for (;;)
	{
	  memset (buffer, 0, MAX_BUF + 1);
	  ret = gnutls_record_recv (session, buffer, MAX_BUF);

	  if (ret == 0)
	    {
	      printf ("\n- Peer has closed the GNUTLS connection\n");
	      break;
	    }
	  else if (ret < 0)
	    {
	      fprintf (stderr, "\n*** Received corrupted "
		       "data(%d). Closing the connection.\n\n", ret);
	      break;
	    }
	  else if (ret > 0)
	    {
	      /* echo data back to the client
	       */
	      gnutls_record_send (session, buffer, strlen (buffer));
	    }
	}
      printf ("\n");
      /* do not wait for the peer to close the connection.
       */
      gnutls_bye (session, GNUTLS_SHUT_WR);

      close (sd);
      gnutls_deinit (session);

    }
  close (listen_sd);

  gnutls_certificate_free_credentials (x509_cred);
  gnutls_psk_free_server_credentials (psk_cred);

  gnutls_priority_deinit (priority_cache);

  gnutls_global_deinit ();

  return 0;

}
示例#4
0
int
lrmd_init_remote_tls_server()
{
    int rc;
    int filter;
    int port = crm_default_remote_port();
    struct addrinfo hints, *res = NULL, *iter;
    char port_str[6]; // at most "65535"
    gnutls_datum_t psk_key = { NULL, 0 };

    static struct mainloop_fd_callbacks remote_listen_fd_callbacks = {
        .dispatch = lrmd_remote_listen,
        .destroy = lrmd_remote_connection_destroy,
    };

    crm_notice("Starting TLS listener on port %d", port);
    crm_gnutls_global_init();
    gnutls_global_set_log_function(debug_log);

    if (pcmk__init_tls_dh(&dh_params) != GNUTLS_E_SUCCESS) {
        return -1;
    }
    gnutls_psk_allocate_server_credentials(&psk_cred_s);
    gnutls_psk_set_server_credentials_function(psk_cred_s, lrmd_tls_server_key_cb);
    gnutls_psk_set_server_dh_params(psk_cred_s, dh_params);

    /* The key callback won't get called until the first client connection
     * attempt. Do it once here, so we can warn the user at start-up if we can't
     * read the key. We don't error out, though, because it's fine if the key is
     * going to be added later.
     */
    rc = lrmd_tls_set_key(&psk_key);
    if (rc != 0) {
        crm_warn("A cluster connection will not be possible until the key is available");
    }
    gnutls_free(psk_key.data);

    memset(&hints, 0, sizeof(struct addrinfo));
    /* Bind to the wildcard address (INADDR_ANY or IN6ADDR_ANY_INIT).
     * @TODO allow user to specify a specific address
     */
    hints.ai_flags = AI_PASSIVE;
    hints.ai_family = AF_UNSPEC; /* Return IPv6 or IPv4 */
    hints.ai_socktype = SOCK_STREAM;
    hints.ai_protocol = IPPROTO_TCP;

    snprintf(port_str, sizeof(port_str), "%d", port);
    rc = getaddrinfo(NULL, port_str, &hints, &res);
    if (rc) {
        crm_err("Unable to get IP address info for local node: %s",
                gai_strerror(rc));
        return -1;
    }

    iter = res;
    filter = AF_INET6;
    /* Try IPv6 addresses first, then IPv4 */
    while (iter) {
        if (iter->ai_family == filter) {
            ssock = bind_and_listen(iter);
        }
        if (ssock != -1) {
            break;
        }

        iter = iter->ai_next;
        if (iter == NULL && filter == AF_INET6) {
            iter = res;
            filter = AF_INET;
        }
    }

    if (ssock < 0) {
        goto init_remote_cleanup;
    }

    mainloop_add_fd("pacemaker-remote-server", G_PRIORITY_DEFAULT, ssock, NULL,
                    &remote_listen_fd_callbacks);

    rc = ssock;

  init_remote_cleanup:
    if (rc < 0) {
        close(ssock);
        ssock = 0;
    } else {
        crm_debug("Started TLS listener on port %d", port);
    }
    freeaddrinfo(res);
    return rc;
}
示例#5
0
int
lrmd_init_remote_tls_server(int port)
{
    int rc;
    int filter;
    struct addrinfo hints, *res = NULL, *iter;
    char port_str[16];

    static struct mainloop_fd_callbacks remote_listen_fd_callbacks = {
        .dispatch = lrmd_remote_listen,
        .destroy = lrmd_remote_connection_destroy,
    };

    crm_notice("Starting a tls listener on port %d.", port);
    crm_gnutls_global_init();
    gnutls_global_set_log_function(debug_log);

    gnutls_dh_params_init(&dh_params);
    gnutls_dh_params_generate2(dh_params, 1024);
    gnutls_psk_allocate_server_credentials(&psk_cred_s);
    gnutls_psk_set_server_credentials_function(psk_cred_s, lrmd_tls_server_key_cb);
    gnutls_psk_set_server_dh_params(psk_cred_s, dh_params);

    memset(&hints, 0, sizeof(struct addrinfo));
    hints.ai_flags = AI_PASSIVE; /* Only return socket addresses with wildcard INADDR_ANY or IN6ADDR_ANY_INIT */
    hints.ai_family = AF_UNSPEC; /* Return IPv6 or IPv4 */
    hints.ai_socktype = SOCK_STREAM;
    hints.ai_protocol = IPPROTO_TCP;

    snprintf(port_str, sizeof(port_str), "%d", port);
    rc = getaddrinfo(NULL, port_str, &hints, &res);
    if (rc) {
        crm_err("getaddrinfo: %s", gai_strerror(rc));
        return -1;
    }

    iter = res;
    filter = AF_INET6;
    /* Try IPv6 addresses first, then IPv4 */
    while (iter) {
        if (iter->ai_family == filter) {
            ssock = bind_and_listen(iter);
        }
        if (ssock != -1) {
            break;
        }

        iter = iter->ai_next;
        if (iter == NULL && filter == AF_INET6) {
            iter = res;
            filter = AF_INET;
        }
    }

    if (ssock < 0) {
        crm_err("unable to bind to address");
        goto init_remote_cleanup;
    }

    mainloop_add_fd("lrmd-remote", G_PRIORITY_DEFAULT, ssock, NULL, &remote_listen_fd_callbacks);

    rc = ssock;
  init_remote_cleanup:
    if (rc < 0) {
        close(ssock);
        ssock = 0;
    }
    freeaddrinfo(res);
    return rc;

}
示例#6
0
static void server(int sd, const char *prio)
{
gnutls_psk_server_credentials_t server_pskcred;
int ret;
gnutls_session_t session;
char buffer[MAX_BUF + 1];

	/* this must be called once in the program
	 */
	global_init();
	gnutls_global_set_log_function(tls_log_func);
	if (debug)
		gnutls_global_set_log_level(4711);

	side = "server";


	gnutls_psk_allocate_server_credentials(&server_pskcred);
	gnutls_psk_set_server_credentials_hint(server_pskcred, "hint");
	gnutls_psk_set_server_credentials_function(server_pskcred,
						   pskfunc);

	gnutls_psk_set_server_dh_params(server_pskcred, dh_params);

	gnutls_init(&session, GNUTLS_SERVER);

	/* avoid calling all the priority functions, since the defaults
	 * are adequate.
	 */
	gnutls_priority_set_direct(session, prio, NULL);

	gnutls_credentials_set(session, GNUTLS_CRD_PSK, server_pskcred);

	gnutls_transport_set_int(session, sd);
	ret = gnutls_handshake(session);
	if (ret < 0) {
		close(sd);
		gnutls_deinit(session);
		fail("server: Handshake has failed (%s)\n\n",
		     gnutls_strerror(ret));
		return;
	}
	if (debug)
		success("server: Handshake was completed\n");

	/* see the Getting peer's information example */
	/* print_info(session); */

	for (;;) {
		memset(buffer, 0, MAX_BUF + 1);
		gnutls_record_set_timeout(session, 10000);
		ret = gnutls_record_recv(session, buffer, MAX_BUF);

		if (ret == 0) {
			if (debug)
				success
				    ("server: Peer has closed the GnuTLS connection\n");
			break;
		} else if (ret < 0) {
			fail("server: Received corrupted data(%d). Closing...\n", ret);
			break;
		} else if (ret > 0) {
			/* echo data back to the client
			 */
			gnutls_record_send(session, buffer,
					   strlen(buffer));
		}
	}
	/* do not wait for the peer to close the connection.
	 */
	gnutls_bye(session, GNUTLS_SHUT_WR);

	close(sd);
	gnutls_deinit(session);

	gnutls_psk_free_server_credentials(server_pskcred);

	gnutls_global_deinit();

	if (debug)
		success("server: finished\n");
}
示例#7
0
int dtls_gnutls_accept(struct conn *conn)
{
	char sock_buf[SOCK_ADDR_BUFSIZE];
	char cookie_buf[SOCK_ADDR_BUFSIZE];
	struct dtls_gnutls_data *d;
	uint8_t buffer[2048];
	int tlen, rc;
	time_t c_timer;
	int bits;

	gnutls_datum_t cookie_key;
	gnutls_dtls_prestate_st prestate;




	gnutls_key_generate(&cookie_key, GNUTLS_COOKIE_KEY_SIZE);
	cw_dbg(DBG_DTLS, "Session cookie for %s generated: %s",
	       sock_addr2str(&conn->addr, sock_buf),
	       sock_hwaddrtostr((uint8_t *) (&cookie_key),
				sizeof(cookie_key), cookie_buf, ""));


	memset(&prestate, 0, sizeof(prestate));

	tlen = dtls_gnutls_bio_read(conn, buffer, sizeof(buffer));

	gnutls_dtls_cookie_send(&cookie_key, &conn->addr, sizeof(conn->addr),
				&prestate, (gnutls_transport_ptr_t) conn,
				dtls_gnutls_bio_write);

	rc = -1;



	c_timer = cw_timer_start(10);

	while (!cw_timer_timeout(c_timer)) {

		tlen = conn_q_recv_packet_peek(conn, buffer, sizeof(buffer));

		if (tlen < 0 && errno == EAGAIN)
			continue;
		if (tlen < 0) {
			/* something went wrong, we should log a message */
			continue;
		}

		rc = gnutls_dtls_cookie_verify(&cookie_key,
					       &conn->addr,
					       sizeof(conn->addr), buffer + 4, tlen - 4,
					       &prestate);

		if (rc < 0) {
			cw_dbg(DBG_DTLS, "Cookie couldn't be verified: %s",
			       gnutls_strerror(rc));
			dtls_gnutls_bio_read(conn, buffer, sizeof(buffer));
			continue;
		}

		break;

	}

	if (rc < 0) {
		cw_log(LOG_ERR, "Cookie couldn't be verified: %s", gnutls_strerror(rc));
		return 0;
	}


	cw_dbg(DBG_DTLS, "Cookie verified! Starting handshake with %s ...",
	       sock_addr2str(&conn->addr, sock_buf));



	d = dtls_gnutls_data_create(conn, GNUTLS_SERVER | GNUTLS_DATAGRAM);
	if (!d)
		return 0;


	if (conn->dtls_psk_enable) {
		gnutls_psk_server_credentials_t cred;
		rc = gnutls_psk_allocate_server_credentials(&cred);
		if (rc != 0) {
			cw_log(LOG_ERR,"gnutls_psk_allocate_server_credentials() failed.");
		}
		/* GnuTLS will call psk_creds to ask for the key associated with the
		client's username.*/
		gnutls_psk_set_server_credentials_function(cred, psk_creds);
		/* // Pass the "credentials" to the GnuTLS session. GnuTLS does NOT make an
		// internal copy of the information, so we have to keep the 'cred' structure
		// in memory (and not modify it) until we're done with this session.*/
		rc = gnutls_credentials_set(d->session, GNUTLS_CRD_PSK, cred);
		if (rc != 0) {
			cw_log(LOG_ERR,"gnutls_credentials_set() failed.\n");
		}

	}




	/* Generate Diffie-Hellman parameters - for use with DHE
	 * kx algorithms. When short bit length is used, it might
	 * be wise to regenerate parameters often.
	 */
	/*bits = gnutls_sec_param_to_pk_bits(GNUTLS_PK_DH, GNUTLS_SEC_PARAM_LEGACY); */
	bits = conn->dtls_dhbits;

	gnutls_dh_params_init(&d->dh_params);

	cw_dbg(DBG_DTLS, "Generating DH params, %d", bits);
	gnutls_dh_params_generate2(d->dh_params, bits);
	cw_dbg(DBG_DTLS, "DH params generated, %d", bits);
	gnutls_certificate_set_dh_params(d->x509_cred, d->dh_params);

	gnutls_certificate_server_set_request(d->session, GNUTLS_CERT_REQUEST);
	gnutls_dtls_prestate_set(d->session, &prestate);

	c_timer = cw_timer_start(10);
	do {
		rc = gnutls_handshake(d->session);
	} while (!cw_timer_timeout(c_timer) && rc == GNUTLS_E_AGAIN);



	if (rc < 0) {
		cw_log(LOG_ERR, "Error in handshake with %s: %s",
		       sock_addr2str(&conn->addr, sock_buf), gnutls_strerror(rc));
		return 0;
	}


	cw_dbg(DBG_DTLS, "Handshake with %s successful.",
	       sock_addr2str(&conn->addr, sock_buf));

	conn->dtls_data = d;
	conn->read = dtls_gnutls_read;
	conn->write = dtls_gnutls_write;

	return 1;
}
static void SetupNewSession(int index, NetworkAddress * networkAddress, bool client)
{
    DTLS_Session * session = &sessions[index];
    session->NetworkAddress = networkAddress;
    unsigned int flags;
#if GNUTLS_VERSION_MAJOR >= 3
    if (client)
        flags = GNUTLS_CLIENT | GNUTLS_DATAGRAM | GNUTLS_NONBLOCK;
    else
        flags = GNUTLS_SERVER | GNUTLS_DATAGRAM | GNUTLS_NONBLOCK;
#else
    if (client)
        flags = GNUTLS_CLIENT;
    else
        flags = GNUTLS_SERVER;
#endif
    if (gnutls_init(&session->Session, flags) == GNUTLS_E_SUCCESS)
    {
        gnutls_transport_set_pull_function(session->Session, DecryptCallBack);
        gnutls_transport_set_push_function(session->Session, SSLSendCallBack);
#if GNUTLS_VERSION_MAJOR >= 3
        gnutls_transport_set_pull_timeout_function(session->Session, ReceiveTimeout);
#endif
        gnutls_transport_set_ptr(session->Session, session);

        if (certificate || !pskIdentity)
        {
            if (_CertCredentials)
            {
                gnutls_credentials_set(session->Session, GNUTLS_CRD_CERTIFICATE, _CertCredentials);
            }
            else if (gnutls_certificate_allocate_credentials(&_CertCredentials) == GNUTLS_E_SUCCESS)
            {
                if (certificate)
                {
                    gnutls_datum_t certificateData;
                    certificateData.data = certificate;
                    certificateData.size = certificateLength;
                    int format = GNUTLS_X509_FMT_PEM;
                    if (certificateFormat == AwaCertificateFormat_ASN1)
                        format = GNUTLS_X509_FMT_DER;
    //                if (client)
    //                    gnutls_certificate_set_x509_trust_mem(session->Credentials, &certificateData, format);
    //                else
                    gnutls_certificate_set_x509_key_mem(_CertCredentials, &certificateData, &certificateData, format);
                }
#if GNUTLS_VERSION_MAJOR >= 3
                    gnutls_certificate_set_verify_function(_CertCredentials, CertificateVerify);
                    //gnutls_certificate_set_retrieve_function(xcred, cert_callback);
                    //gnutls_session_set_verify_cert(session->Session, NULL, GNUTLS_VERIFY_DISABLE_CA_SIGN);
#else
                    gnutls_certificate_set_verify_flags(_CertCredentials, GNUTLS_VERIFY_DISABLE_CA_SIGN);
#endif
                gnutls_credentials_set(session->Session, GNUTLS_CRD_CERTIFICATE, _CertCredentials);
            }
        }
        else if (pskIdentity)
        {
            if (client)
            {
                gnutls_psk_client_credentials_t credentials;
                if (gnutls_psk_allocate_client_credentials(&credentials) == GNUTLS_E_SUCCESS)
                {
                    if (gnutls_psk_set_client_credentials(credentials, pskIdentity, &pskKey, GNUTLS_PSK_KEY_RAW) == GNUTLS_E_SUCCESS)
                    {
                        gnutls_credentials_set(session->Session, GNUTLS_CRD_PSK, credentials);
                        session->Credentials = credentials;
                        session->CredentialType = CredentialType_ClientPSK;
                    }
                    else
                    {
                        gnutls_psk_set_client_credentials_function(credentials, PSKClientCallBack);
                        session->Credentials = credentials;
                        session->CredentialType = CredentialType_ClientPSK;
                    }
                }
            }
            else
            {
                gnutls_psk_server_credentials_t credentials;
                if (gnutls_psk_allocate_server_credentials(&credentials) == GNUTLS_E_SUCCESS)
                {
                    gnutls_psk_set_server_credentials_function(credentials, PSKCallBack);
                    gnutls_credentials_set(session->Session, GNUTLS_CRD_PSK, credentials);
                    session->Credentials = credentials;
                    session->CredentialType = CredentialType_ServerPSK;
                }
            }
        }


        gnutls_priority_set(session->Session, _PriorityCache);
        if (!client)
        {
            gnutls_certificate_server_set_request(session->Session, GNUTLS_CERT_REQUEST); // GNUTLS_CERT_IGNORE  Don't require Client Cert
        }

#if GNUTLS_VERSION_MAJOR >= 3
        gnutls_handshake_set_timeout(session->Session, GNUTLS_DEFAULT_HANDSHAKE_TIMEOUT);
#endif
    }
}
示例#9
0
文件: web-server.c 项目: sjlu/httpd
int main (void)
{
   /*
    * Variable init
    */
   int err, listen_sd;
   int sd, ret;
   struct sockaddr_in sa_serv;
   struct sockaddr_in sa_cli;
   int client_len;
   char topbuf[512];
   gnutls_session_t session;
   int optval = 1;

   /*
    * SSL TLS utility init
    * This will add the certificate files properly
    * to the TLS session we are about to create.
    */
   gcry_control (GCRYCTL_ENABLE_QUICK_RANDOM, 0);

   gnutls_global_init ();

   gnutls_certificate_allocate_credentials (&x509_cred);
   gnutls_certificate_set_x509_trust_file (x509_cred, CAFILE, GNUTLS_X509_FMT_PEM);

   gnutls_certificate_set_x509_crl_file (x509_cred, CRLFILE, GNUTLS_X509_FMT_PEM);

   gnutls_certificate_set_x509_key_file (x509_cred, CERTFILE, KEYFILE, GNUTLS_X509_FMT_PEM);

   gnutls_psk_allocate_server_credentials (&psk_cred);
   gnutls_psk_set_server_credentials_function (psk_cred, pskfunc);

   generate_dh_params ();

   gnutls_priority_init (&priority_cache, "NORMAL:PSK", NULL);

   gnutls_certificate_set_dh_params (x509_cred, dh_params);

   /*
    * Web server socket stuff
    */
   listen_sd = socket (AF_INET, SOCK_STREAM, 0);
   SOCKET_ERR (listen_sd, "socket");

   memset (&sa_serv, '\0', sizeof (sa_serv));
   sa_serv.sin_family = AF_INET;
   sa_serv.sin_addr.s_addr = INADDR_ANY;
   sa_serv.sin_port = htons (PORT);	/* Server Port number */

   setsockopt(listen_sd, SOL_SOCKET, SO_REUSEADDR, (void *) &optval, sizeof (int));

   err = bind (listen_sd, (SA *) & sa_serv, sizeof (sa_serv));
   SOCKET_ERR (err, "bind");
   err = listen (listen_sd, 1024);
   SOCKET_ERR (err, "listen");

   /*
    * Listening for clients this will SSLize
    * the incoming connection by properly doing the "handshake"
    */
   client_len = sizeof (sa_cli);
   for (;;)
   {
      session = initialize_tls_session ();

      sd = accept(listen_sd, (SA *) & sa_cli, &client_len);
      pid_t pid = fork();
      if (pid == 0) 
         break; 
      else 
         continue;
   }

   printf ("Connection received from %s:%d\n", 
      inet_ntop (AF_INET, &sa_cli.sin_addr, topbuf, sizeof (topbuf)), 
      ntohs (sa_cli.sin_port));

   gnutls_transport_set_ptr (session, (gnutls_transport_ptr_t) sd);

   ret = gnutls_handshake (session);
   if (ret < 0)
   {
      close (sd);
      gnutls_deinit (session);
      fprintf (stderr, "\tSSL handshake failed!\n\tError: %s\n\n", gnutls_strerror(ret));
   }
   printf ("\tSSL handshake successful!\n");

   /*
    * Send it for processing
    */
   process_request(session);

   printf ("\n");

   /*
   * Closing connection.
   */
   gnutls_bye (session, GNUTLS_SHUT_WR);

//      close (sd);
   gnutls_deinit (session);

   /*
    * Properly closing the TLS connection
    * we created to the web server.
    */
   close (listen_sd);

   gnutls_certificate_free_credentials (x509_cred);
   gnutls_psk_free_server_credentials (psk_cred);

   gnutls_priority_deinit (priority_cache);

   gnutls_global_deinit ();

   return 0;
}
psk_server_credentials::psk_server_credentials ():credentials
    (GNUTLS_CRD_PSK)
{
    RETWRAP (gnutls_psk_allocate_server_credentials (&cred));
    set_ptr (cred);
}
示例#11
0
int main(void)
{
        int err, listen_sd;
        int sd, ret;
        struct sockaddr_in sa_serv;
        struct sockaddr_in sa_cli;
        socklen_t client_len;
        char topbuf[512];
        gnutls_session_t session;
        gnutls_certificate_credentials_t x509_cred;
        gnutls_psk_server_credentials_t psk_cred;
        gnutls_priority_t priority_cache;
        char buffer[MAX_BUF + 1];
        int optval = 1;
        int kx;

        if (gnutls_check_version("3.1.4") == NULL) {
                fprintf(stderr, "GnuTLS 3.1.4 is required for this example\n");
                exit(1);
        }

        gnutls_global_init();

        gnutls_certificate_allocate_credentials(&x509_cred);
        gnutls_certificate_set_x509_trust_file(x509_cred, CAFILE,
                                               GNUTLS_X509_FMT_PEM);

        gnutls_certificate_set_x509_crl_file(x509_cred, CRLFILE,
                                             GNUTLS_X509_FMT_PEM);

        gnutls_certificate_set_x509_key_file(x509_cred, CERTFILE, KEYFILE,
                                             GNUTLS_X509_FMT_PEM);

        gnutls_psk_allocate_server_credentials(&psk_cred);
        gnutls_psk_set_server_credentials_function(psk_cred, pskfunc);

        generate_dh_params();

        gnutls_priority_init(&priority_cache,
                             "NORMAL:+PSK:+ECDHE-PSK:+DHE-PSK",
                             NULL);

        gnutls_certificate_set_dh_params(x509_cred, dh_params);

        /* Socket operations
         */
        listen_sd = socket(AF_INET, SOCK_STREAM, 0);
        SOCKET_ERR(listen_sd, "socket");

        memset(&sa_serv, '\0', sizeof(sa_serv));
        sa_serv.sin_family = AF_INET;
        sa_serv.sin_addr.s_addr = INADDR_ANY;
        sa_serv.sin_port = htons(PORT); /* Server Port number */

        setsockopt(listen_sd, SOL_SOCKET, SO_REUSEADDR, (void *) &optval,
                   sizeof(int));

        err =
            bind(listen_sd, (struct sockaddr *) &sa_serv, sizeof(sa_serv));
        SOCKET_ERR(err, "bind");
        err = listen(listen_sd, 1024);
        SOCKET_ERR(err, "listen");

        printf("Server ready. Listening to port '%d'.\n\n", PORT);

        client_len = sizeof(sa_cli);
        for (;;) {
                gnutls_init(&session, GNUTLS_SERVER);
                gnutls_priority_set(session, priority_cache);
                gnutls_credentials_set(session, GNUTLS_CRD_CERTIFICATE,
                                       x509_cred);
                gnutls_credentials_set(session, GNUTLS_CRD_PSK, psk_cred);

                /* request client certificate if any.
                 */
                gnutls_certificate_server_set_request(session,
                                                      GNUTLS_CERT_REQUEST);

                sd = accept(listen_sd, (struct sockaddr *) &sa_cli,
                            &client_len);

                printf("- connection from %s, port %d\n",
                       inet_ntop(AF_INET, &sa_cli.sin_addr, topbuf,
                                 sizeof(topbuf)), ntohs(sa_cli.sin_port));

                gnutls_transport_set_int(session, sd);
                ret = gnutls_handshake(session);
                if (ret < 0) {
                        close(sd);
                        gnutls_deinit(session);
                        fprintf(stderr,
                                "*** Handshake has failed (%s)\n\n",
                                gnutls_strerror(ret));
                        continue;
                }
                printf("- Handshake was completed\n");

                kx = gnutls_kx_get(session);
                if (kx == GNUTLS_KX_PSK || kx == GNUTLS_KX_DHE_PSK ||
                    kx == GNUTLS_KX_ECDHE_PSK) {
                        printf("- User %s was connected\n",
                               gnutls_psk_server_get_username(session));
                }

                /* see the Getting peer's information example */
                /* print_info(session); */

                for (;;) {
                        ret = gnutls_record_recv(session, buffer, MAX_BUF);

                        if (ret == 0) {
                                printf
                                    ("\n- Peer has closed the GnuTLS connection\n");
                                break;
                        } else if (ret < 0
                                   && gnutls_error_is_fatal(ret) == 0) {
                                fprintf(stderr, "*** Warning: %s\n",
                                        gnutls_strerror(ret));
                        } else if (ret < 0) {
                                fprintf(stderr, "\n*** Received corrupted "
                                        "data(%d). Closing the connection.\n\n",
                                        ret);
                                break;
                        } else if (ret > 0) {
                                /* echo data back to the client
                                 */
                                gnutls_record_send(session, buffer, ret);
                        }
                }
                printf("\n");
                /* do not wait for the peer to close the connection.
                 */
                gnutls_bye(session, GNUTLS_SHUT_WR);

                close(sd);
                gnutls_deinit(session);

        }
        close(listen_sd);

        gnutls_certificate_free_credentials(x509_cred);
        gnutls_psk_free_server_credentials(psk_cred);

        gnutls_priority_deinit(priority_cache);

        gnutls_global_deinit();

        return 0;

}