Beispiel #1
0
static void
eventcb(struct bufferevent *bev, short what, void *ctx)
{
	TT_BLATHER(("Got event %d", (int)what));
	if (what & BEV_EVENT_CONNECTED) {
		SSL *ssl;
		X509 *peer_cert;
		++n_connected;
		ssl = bufferevent_openssl_get_ssl(bev);
		tt_assert(ssl);
		peer_cert = SSL_get_peer_certificate(ssl);
		if (0==strcmp(ctx, "server")) {
			tt_assert(peer_cert == NULL);
		} else {
			tt_assert(peer_cert != NULL);
		}
		if (stop_when_connected) {
			if (--pending_connect_events == 0)
				event_base_loopexit(exit_base, NULL);
		}
	} else if (what & BEV_EVENT_EOF) {
		TT_BLATHER(("Got a good EOF"));
		++got_close;
		bufferevent_free(bev);
	} else if (what & BEV_EVENT_ERROR) {
		TT_BLATHER(("Got an error."));
		++got_error;
		bufferevent_free(bev);
	}
end:
	;
}
Beispiel #2
0
/** Called after the SSL connection and initial handshaking is complete. */
void
ssl_connected(struct conn *c)
{
  X509 *peer;
  SSL *ssl = bufferevent_openssl_get_ssl(c->remote_bev);

#if SSL_DEBUG_LEVEL > 0
  errprintf(stdout,
	    "ssl_slave: SSL connection attempt completed, using %s. Resolving remote host name.\n", SSL_get_version(ssl));
  if (bufferevent_get_openssl_error(c->remote_bev))
    errprintf(stdout, "ssl_slave: ssl error code: %ld\n",
	      bufferevent_get_openssl_error(c->remote_bev));
#endif

  bufferevent_set_timeouts(c->remote_bev, NULL, NULL);
  
  /* Successful accept. Log peer certificate, if any. */
  if ((peer = SSL_get_peer_certificate(ssl))) {
    if (SSL_get_verify_result(ssl) == X509_V_OK) {
      char buf[256];
      /* The client sent a certificate which verified OK */
      X509_NAME_oneline(X509_get_subject_name(peer), buf, 256);
      errprintf(stdout, "ssl_slave: SSL client certificate accepted: %s\n", buf);
    }
  }

  c->state = C_HOSTNAME_LOOKUP;
  c->resolver_req =
    evdns_getnameinfo(resolver, &c->remote_addr.addr, 0, address_resolved, c);
}
Beispiel #3
0
static void
respond_to_number(struct bufferevent *bev, void *ctx)
{
	struct evbuffer *b = bufferevent_get_input(bev);
	char *line;
	int n;
	line = evbuffer_readln(b, NULL, EVBUFFER_EOL_LF);
	if (! line)
		return;
	n = atoi(line);
	if (n <= 0)
		TT_FAIL(("Bad number: %s", line));
	TT_BLATHER(("The number was %d", n));
	if (n == 1001) {
		++test_is_done;
		bufferevent_free(bev); /* Should trigger close on other side. */
		return;
	}
	if (!strcmp(ctx, "client") && n == renegotiate_at) {
		SSL_renegotiate(bufferevent_openssl_get_ssl(bev));
	}
	++n;
	evbuffer_add_printf(bufferevent_get_output(bev),
	    "%d\n", n);
	TT_BLATHER(("Done reading; now writing."));
	bufferevent_enable(bev, EV_WRITE);
	bufferevent_disable(bev, EV_READ);
}
Beispiel #4
0
static void delete_http2_session_data(http2_session_data *session_data) {
  http2_stream_data *stream_data;
  SSL *ssl = bufferevent_openssl_get_ssl(session_data->bev);
  fprintf(stderr, "%s disconnected\n", session_data->client_addr);
  if (ssl) {
    SSL_shutdown(ssl);
  }
  bufferevent_free(session_data->bev);
  nghttp2_session_del(session_data->session);
  for (stream_data = session_data->root.next; stream_data;) {
    http2_stream_data *next = stream_data->next;
    delete_http2_stream_data(stream_data);
    stream_data = next;
  }
  free(session_data->client_addr);
  free(session_data);
}
Beispiel #5
0
/* eventcb for bufferevent. For the purpose of simplicity and
   readability of the example program, we omitted the certificate and
   peer verification. After SSL/TLS handshake is over, initialize
   nghttp2 library session, and send client connection header. Then
   send HTTP request. */
static void eventcb(struct bufferevent *bev, short events, void *ptr) {
  http2_session_data *session_data = (http2_session_data *)ptr;
  if (events & BEV_EVENT_CONNECTED) {
    int fd = bufferevent_getfd(bev);
    int val = 1;
    const unsigned char *alpn = NULL;
    unsigned int alpnlen = 0;
    SSL *ssl;

    fprintf(stderr, "Connected\n");

    ssl = bufferevent_openssl_get_ssl(session_data->bev);

#ifndef OPENSSL_NO_NEXTPROTONEG
    SSL_get0_next_proto_negotiated(ssl, &alpn, &alpnlen);
#endif /* !OPENSSL_NO_NEXTPROTONEG */
#if OPENSSL_VERSION_NUMBER >= 0x10002000L
    if (alpn == NULL) {
      SSL_get0_alpn_selected(ssl, &alpn, &alpnlen);
    }
#endif /* OPENSSL_VERSION_NUMBER >= 0x10002000L */

    if (alpn == NULL || alpnlen != 2 || memcmp("h2", alpn, 2) != 0) {
      fprintf(stderr, "h2 is not negotiated\n");
      delete_http2_session_data(session_data);
      return;
    }

    setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, (char *)&val, sizeof(val));
    initialize_nghttp2_session(session_data);
    send_client_connection_header(session_data);
    submit_request(session_data);
    if (session_send(session_data) != 0) {
      delete_http2_session_data(session_data);
    }
    return;
  }
  if (events & BEV_EVENT_EOF) {
    warnx("Disconnected from the remote host");
  } else if (events & BEV_EVENT_ERROR) {
    warnx("Network error");
  } else if (events & BEV_EVENT_TIMEOUT) {
    warnx("Timeout");
  }
  delete_http2_session_data(session_data);
}
Beispiel #6
0
static void delete_http2_session_data(http2_session_data *session_data) {
  SSL *ssl = bufferevent_openssl_get_ssl(session_data->bev);

  if (ssl) {
    SSL_shutdown(ssl);
  }
  bufferevent_free(session_data->bev);
  session_data->bev = NULL;
  evdns_base_free(session_data->dnsbase, 1);
  session_data->dnsbase = NULL;
  nghttp2_session_del(session_data->session);
  session_data->session = NULL;
  if (session_data->stream_data) {
    delete_http2_stream_data(session_data->stream_data);
    session_data->stream_data = NULL;
  }
  free(session_data);
}
Beispiel #7
0
/* eventcb for bufferevent */
static void eventcb(struct bufferevent *bev, short events, void *ptr) {
  http2_session_data *session_data = (http2_session_data *)ptr;
  if (events & BEV_EVENT_CONNECTED) {
    const unsigned char *alpn = NULL;
    unsigned int alpnlen = 0;
    SSL *ssl;
    (void)bev;

    fprintf(stderr, "%s connected\n", session_data->client_addr);

    ssl = bufferevent_openssl_get_ssl(session_data->bev);

    SSL_get0_next_proto_negotiated(ssl, &alpn, &alpnlen);
#if OPENSSL_VERSION_NUMBER >= 0x10002000L
    if (alpn == NULL) {
      SSL_get0_alpn_selected(ssl, &alpn, &alpnlen);
    }
#endif // OPENSSL_VERSION_NUMBER >= 0x10002000L

    if (alpn == NULL || alpnlen != 2 || memcmp("h2", alpn, 2) != 0) {
      fprintf(stderr, "%s h2 is not negotiated\n", session_data->client_addr);
      delete_http2_session_data(session_data);
      return;
    }

    initialize_nghttp2_session(session_data);

    if (send_server_connection_header(session_data) != 0 ||
        session_send(session_data) != 0) {
      delete_http2_session_data(session_data);
      return;
    }

    return;
  }
  if (events & BEV_EVENT_EOF) {
    fprintf(stderr, "%s EOF\n", session_data->client_addr);
  } else if (events & BEV_EVENT_ERROR) {
    fprintf(stderr, "%s network error\n", session_data->client_addr);
  } else if (events & BEV_EVENT_TIMEOUT) {
    fprintf(stderr, "%s timeout\n", session_data->client_addr);
  }
  delete_http2_session_data(session_data);
}
Beispiel #8
0
/** Called on successful connections and errors */
void
ssl_event_cb(struct bufferevent *bev, short e, void *data)
{
  struct conn *c = data;
  uint32_t error_conditions =
    BEV_EVENT_EOF | BEV_EVENT_ERROR | BEV_EVENT_TIMEOUT;

#if SSL_DEBUG_LEVEL > 1
  errprintf(stdout, "ssl_slave: event callback triggered with flags 0x%hx\n",
            e);
#endif

  if (e & BEV_EVENT_CONNECTED) {
    if (c->local_bev == bev) {
      local_connected(c);
    } else {
      ssl_connected(c);
    }
  } else if (e & BEV_EVENT_TIMEOUT) {
    if (c->state == C_SSL_CONNECTING) {
      /* Handshake timed out. */
#if SSL_DEBUG_LEVEL > 0
      errprintf(stdout, "ssl_slave: SSL handshake timeout.\n");
#endif
      bufferevent_disable(c->remote_bev, EV_READ | EV_WRITE);
      bufferevent_free(c->remote_bev);
      c->remote_bev = NULL;
      c->state = C_SHUTTINGDOWN;
      if (c->local_bev) {
        bufferevent_disable(c->local_bev, EV_READ);
        bufferevent_flush(c->local_bev, EV_WRITE, BEV_FINISHED);
      }
      delete_conn(c);
    } else {
      /* Bug in some versions of libevent cause this to trigger when
         it shouldn't. Ignore. */
      return;
    }
  } else if (e & error_conditions) {
    if (c->local_bev == bev) {
      /* Mush side of the connection went away. Flush SSL buffer and shut down. */
#if SSL_DEBUG_LEVEL > 0
      errprintf(stdout,
                "ssl_slave: Lost local connection. State: %d, reason 0x%hx.\n",
                c->state, e);
#endif
      bufferevent_disable(c->local_bev, EV_READ | EV_WRITE);
      bufferevent_free(c->local_bev);
      c->local_bev = NULL;
      c->state = C_SHUTTINGDOWN;
      if (c->remote_bev) {
        bufferevent_disable(c->remote_bev, EV_READ);
        bufferevent_flush(c->remote_bev, EV_WRITE, BEV_FINISHED);
        SSL_shutdown(bufferevent_openssl_get_ssl(c->remote_bev));
      }
      delete_conn(c);
    } else {
      /* Remote side of the connection went away. Flush mush buffer and shut down. */
#if SSL_DEBUG_LEVEL > 0
      errprintf(stdout,
                "ssl_slave: Lost SSL connection. State: %d, reason 0x%hx.\n",
                c->state, e);
#endif
      bufferevent_disable(c->remote_bev, EV_READ | EV_WRITE);
      bufferevent_free(c->remote_bev);
      c->remote_bev = NULL;
      c->state = C_SHUTTINGDOWN;
      if (c->local_bev) {
        bufferevent_disable(c->local_bev, EV_READ);
        bufferevent_flush(c->local_bev, EV_WRITE, BEV_FINISHED);
      }
      delete_conn(c);
    }
  }
}
Beispiel #9
0
void
server_mc_event_cb(struct bufferevent *bev, short events, void *ctx)
{
    struct server *s = (struct server *)ctx;

    dump_flags(events);
    if (events & BEV_EVENT_CONNECTED)
    {
        struct mc *mc;

        /*
         * If we received the notification that the connection is established,
         * then we move the corresponding struct mc from s->pending_peers to
         * s->peers.
         */

        mc = v_mc_find_if(s->pending_peers, (void *)find_bev, bev);
        if (mc != v_mc_end(s->pending_peers))
        {
            struct mc tmp;
            struct endpoint e;

            endpoint_init(&e, mc->p.address, mc->p.len);
            /* Check for certificate */
            if (mc->ssl_flags & TLS_ENABLE)
            {
                X509 *cert;
                SSL *ssl;
                EVP_PKEY *pubkey;
                char name[512];

                ssl = bufferevent_openssl_get_ssl(mc->bev);
                cert = SSL_get_peer_certificate(ssl);
                if (cert == NULL)
                {
                    log_info("[META] [TLS] %s doesn't share it's certificate.",
                             mc_presentation(mc, name, sizeof name));
                    v_mc_erase(s->pending_peers, mc);
                    mc_close(mc);
                    return ;
                }
                pubkey = X509_get_pubkey(cert); //UNUSED ?
            }
            log_info("[META] [%s] connexion established with %s",
                     mc->ssl_flags & TLS_ENABLE ? "TLS" : "TCP",
                     endpoint_presentation(&e));
            memcpy(&tmp, mc, sizeof(tmp));
            v_mc_erase(s->pending_peers, mc);
            mc = v_mc_insert(s->peers, &tmp);
            mc_hello(mc, s->udp);
            mc_establish_tunnel(mc, s->udp);
        }
    }
    else if (events & BEV_EVENT_EOF)
    {
        /* Disconnected */
        struct mc *mc;
        struct udp_peer *up;

        mc = v_mc_find_if(s->peers, (void *)find_bev, bev);
        if (mc != v_mc_end(s->peers))
        {
            char name[INET6_ADDRSTRLEN];
            struct sockaddr *sock = mc->p.address;

            up = v_udp_find_if(s->udp->udp_peers, find_udppeer, sock);
            if (up != v_udp_end(s->udp->udp_peers))
            {
                v_udp_erase(s->udp->udp_peers, up);
                log_debug("[%s] stop peering with %s",
                          (up->ssl_flags & DTLS_ENABLE) ? "DTLS" : "UDP",
                          endpoint_presentation(&up->peer_addr));
            }
            log_debug("[META] stop the meta-connexion with %s",
                      mc_presentation(mc, name, sizeof(name)));
            mc_close(mc);
            v_mc_erase(s->peers, mc);
        }

    }
    else if (events & BEV_EVENT_ERROR)
    {
        struct mc *mc;
        int everr;
        int sslerr;

        everr = EVUTIL_SOCKET_ERROR();

        if (everr != 0)
        {
            log_warnx("[META] unexpected shutdown of the meta-connexion: (%d) %s",
                       everr, evutil_socket_error_to_string(everr));
        }
        while ((sslerr = bufferevent_get_openssl_error(bev)) != 0)
        {
            log_warnx("[META] SSL error code (%d): %s in %s %s",
                       sslerr, ERR_reason_error_string(sslerr),
                       ERR_lib_error_string(sslerr),
                       ERR_func_error_string(sslerr));
        }
        /*
         * Find if the exception come from a pending peer or a
         * regular peer and close it.
         */
        mc = v_mc_find_if(s->pending_peers, (void *)find_bev, bev);
        if (mc != v_mc_end(s->pending_peers))
        {
            char name[128];

            log_debug("[META] %s removed from the pending list",
                      mc_presentation(mc, name, sizeof name));
            mc_close(mc);
            v_mc_erase(s->pending_peers, mc);
        }
        else
        {
            mc = v_mc_find_if(s->peers, (void *)find_bev, bev);
            if (mc != v_mc_end(s->peers))
            {
                mc_close(mc);
                v_mc_erase(s->peers, mc);
                log_debug("[META] socket removed from the peer list");
            }
        }
    }
}