aboutsummaryrefslogtreecommitdiff
path: root/sample
diff options
context:
space:
mode:
Diffstat (limited to 'sample')
-rw-r--r--sample/dns-example.c257
-rw-r--r--sample/event-read-fifo.c162
-rw-r--r--sample/hello-world.c141
-rw-r--r--sample/hostcheck.c217
-rw-r--r--sample/hostcheck.h30
-rw-r--r--sample/http-connect.c117
-rw-r--r--sample/http-server.c418
-rw-r--r--sample/https-client.c502
-rw-r--r--sample/include.am53
-rw-r--r--sample/le-proxy.c291
-rw-r--r--sample/openssl_hostname_validation.c177
-rw-r--r--sample/openssl_hostname_validation.h56
-rw-r--r--sample/signal-test.c72
-rw-r--r--sample/time-test.c107
14 files changed, 0 insertions, 2600 deletions
diff --git a/sample/dns-example.c b/sample/dns-example.c
deleted file mode 100644
index fb70566..0000000
--- a/sample/dns-example.c
+++ /dev/null
@@ -1,257 +0,0 @@
-/*
- This example code shows how to use the high-level, low-level, and
- server-level interfaces of evdns.
-
- XXX It's pretty ugly and should probably be cleaned up.
- */
-
-#include <event2/event-config.h>
-
-/* Compatibility for possible missing IPv6 declarations */
-#include "../ipv6-internal.h"
-
-#include <sys/types.h>
-
-#ifdef EVENT__HAVE_UNISTD_H
-#include <unistd.h>
-#endif
-
-#ifdef _WIN32
-#include <winsock2.h>
-#include <ws2tcpip.h>
-#include <getopt.h>
-#else
-#include <sys/socket.h>
-#include <netinet/in.h>
-#include <arpa/inet.h>
-#endif
-
-#include <event2/event.h>
-#include <event2/dns.h>
-#include <event2/dns_struct.h>
-#include <event2/util.h>
-
-#ifdef EVENT__HAVE_NETINET_IN6_H
-#include <netinet/in6.h>
-#endif
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#define u32 ev_uint32_t
-#define u8 ev_uint8_t
-
-static const char *
-debug_ntoa(u32 address)
-{
- static char buf[32];
- u32 a = ntohl(address);
- evutil_snprintf(buf, sizeof(buf), "%d.%d.%d.%d",
- (int)(u8)((a>>24)&0xff),
- (int)(u8)((a>>16)&0xff),
- (int)(u8)((a>>8 )&0xff),
- (int)(u8)((a )&0xff));
- return buf;
-}
-
-static void
-main_callback(int result, char type, int count, int ttl,
- void *addrs, void *orig) {
- char *n = (char*)orig;
- int i;
- for (i = 0; i < count; ++i) {
- if (type == DNS_IPv4_A) {
- printf("%s: %s\n", n, debug_ntoa(((u32*)addrs)[i]));
- } else if (type == DNS_PTR) {
- printf("%s: %s\n", n, ((char**)addrs)[i]);
- }
- }
- if (!count) {
- printf("%s: No answer (%d)\n", n, result);
- }
- fflush(stdout);
-}
-
-static void
-gai_callback(int err, struct evutil_addrinfo *ai, void *arg)
-{
- const char *name = arg;
- int i;
- if (err) {
- printf("%s: %s\n", name, evutil_gai_strerror(err));
- }
- if (ai && ai->ai_canonname)
- printf(" %s ==> %s\n", name, ai->ai_canonname);
- for (i=0; ai; ai = ai->ai_next, ++i) {
- char buf[128];
- if (ai->ai_family == PF_INET) {
- struct sockaddr_in *sin =
- (struct sockaddr_in*)ai->ai_addr;
- evutil_inet_ntop(AF_INET, &sin->sin_addr, buf,
- sizeof(buf));
- printf("[%d] %s: %s\n",i,name,buf);
- } else {
- struct sockaddr_in6 *sin6 =
- (struct sockaddr_in6*)ai->ai_addr;
- evutil_inet_ntop(AF_INET6, &sin6->sin6_addr, buf,
- sizeof(buf));
- printf("[%d] %s: %s\n",i,name,buf);
- }
- }
-}
-
-static void
-evdns_server_callback(struct evdns_server_request *req, void *data)
-{
- int i, r;
- (void)data;
- /* dummy; give 192.168.11.11 as an answer for all A questions,
- * give foo.bar.example.com as an answer for all PTR questions. */
- for (i = 0; i < req->nquestions; ++i) {
- u32 ans = htonl(0xc0a80b0bUL);
- if (req->questions[i]->type == EVDNS_TYPE_A &&
- req->questions[i]->dns_question_class == EVDNS_CLASS_INET) {
- printf(" -- replying for %s (A)\n", req->questions[i]->name);
- r = evdns_server_request_add_a_reply(req, req->questions[i]->name,
- 1, &ans, 10);
- if (r<0)
- printf("eeep, didn't work.\n");
- } else if (req->questions[i]->type == EVDNS_TYPE_PTR &&
- req->questions[i]->dns_question_class == EVDNS_CLASS_INET) {
- printf(" -- replying for %s (PTR)\n", req->questions[i]->name);
- r = evdns_server_request_add_ptr_reply(req, NULL, req->questions[i]->name,
- "foo.bar.example.com", 10);
- if (r<0)
- printf("ugh, no luck");
- } else {
- printf(" -- skipping %s [%d %d]\n", req->questions[i]->name,
- req->questions[i]->type, req->questions[i]->dns_question_class);
- }
- }
-
- r = evdns_server_request_respond(req, 0);
- if (r<0)
- printf("eeek, couldn't send reply.\n");
-}
-
-static int verbose = 0;
-
-static void
-logfn(int is_warn, const char *msg) {
- if (!is_warn && !verbose)
- return;
- fprintf(stderr, "%s: %s\n", is_warn?"WARN":"INFO", msg);
-}
-
-int
-main(int c, char **v) {
- struct options {
- int reverse;
- int use_getaddrinfo;
- int servertest;
- const char *resolv_conf;
- const char *ns;
- };
- struct options o;
- char opt;
- struct event_base *event_base = NULL;
- struct evdns_base *evdns_base = NULL;
-
- memset(&o, 0, sizeof(o));
-
- if (c < 2) {
- fprintf(stderr, "syntax: %s [-x] [-v] [-c resolv.conf] [-s ns] hostname\n", v[0]);
- fprintf(stderr, "syntax: %s [-T]\n", v[0]);
- return 1;
- }
-
- while ((opt = getopt(c, v, "xvc:Ts:")) != -1) {
- switch (opt) {
- case 'x': o.reverse = 1; break;
- case 'v': ++verbose; break;
- case 'g': o.use_getaddrinfo = 1; break;
- case 'T': o.servertest = 1; break;
- case 'c': o.resolv_conf = optarg; break;
- case 's': o.ns = optarg; break;
- default : fprintf(stderr, "Unknown option %c\n", opt); break;
- }
- }
-
-#ifdef _WIN32
- {
- WSADATA WSAData;
- WSAStartup(0x101, &WSAData);
- }
-#endif
-
- event_base = event_base_new();
- evdns_base = evdns_base_new(event_base, EVDNS_BASE_DISABLE_WHEN_INACTIVE);
- evdns_set_log_fn(logfn);
-
- if (o.servertest) {
- evutil_socket_t sock;
- struct sockaddr_in my_addr;
- sock = socket(PF_INET, SOCK_DGRAM, 0);
- if (sock == -1) {
- perror("socket");
- exit(1);
- }
- evutil_make_socket_nonblocking(sock);
- my_addr.sin_family = AF_INET;
- my_addr.sin_port = htons(10053);
- my_addr.sin_addr.s_addr = INADDR_ANY;
- if (bind(sock, (struct sockaddr*)&my_addr, sizeof(my_addr))<0) {
- perror("bind");
- exit(1);
- }
- evdns_add_server_port_with_base(event_base, sock, 0, evdns_server_callback, NULL);
- }
- if (optind < c) {
- int res;
-#ifdef _WIN32
- if (o.resolv_conf == NULL && !o.ns)
- res = evdns_base_config_windows_nameservers(evdns_base);
- else
-#endif
- if (o.ns)
- res = evdns_base_nameserver_ip_add(evdns_base, o.ns);
- else
- res = evdns_base_resolv_conf_parse(evdns_base,
- DNS_OPTION_NAMESERVERS, o.resolv_conf);
-
- if (res < 0) {
- fprintf(stderr, "Couldn't configure nameservers");
- return 1;
- }
- }
-
- printf("EVUTIL_AI_CANONNAME in example = %d\n", EVUTIL_AI_CANONNAME);
- for (; optind < c; ++optind) {
- if (o.reverse) {
- struct in_addr addr;
- if (evutil_inet_pton(AF_INET, v[optind], &addr)!=1) {
- fprintf(stderr, "Skipping non-IP %s\n", v[optind]);
- continue;
- }
- fprintf(stderr, "resolving %s...\n",v[optind]);
- evdns_base_resolve_reverse(evdns_base, &addr, 0, main_callback, v[optind]);
- } else if (o.use_getaddrinfo) {
- struct evutil_addrinfo hints;
- memset(&hints, 0, sizeof(hints));
- hints.ai_family = PF_UNSPEC;
- hints.ai_protocol = IPPROTO_TCP;
- hints.ai_flags = EVUTIL_AI_CANONNAME;
- fprintf(stderr, "resolving (fwd) %s...\n",v[optind]);
- evdns_getaddrinfo(evdns_base, v[optind], NULL, &hints,
- gai_callback, v[optind]);
- } else {
- fprintf(stderr, "resolving (fwd) %s...\n",v[optind]);
- evdns_base_resolve_ipv4(evdns_base, v[optind], 0, main_callback, v[optind]);
- }
- }
- fflush(stdout);
- event_base_dispatch(event_base);
- return 0;
-}
-
diff --git a/sample/event-read-fifo.c b/sample/event-read-fifo.c
deleted file mode 100644
index 27b0b53..0000000
--- a/sample/event-read-fifo.c
+++ /dev/null
@@ -1,162 +0,0 @@
-/*
- * This sample code shows how to use Libevent to read from a named pipe.
- * XXX This code could make better use of the Libevent interfaces.
- *
- * XXX This does not work on Windows; ignore everything inside the _WIN32 block.
- *
- * On UNIX, compile with:
- * cc -I/usr/local/include -o event-read-fifo event-read-fifo.c \
- * -L/usr/local/lib -levent
- */
-
-#include <event2/event-config.h>
-
-#include <sys/types.h>
-#include <sys/stat.h>
-#ifndef _WIN32
-#include <sys/queue.h>
-#include <unistd.h>
-#include <sys/time.h>
-#include <signal.h>
-#else
-#include <winsock2.h>
-#include <windows.h>
-#endif
-#include <fcntl.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-#include <errno.h>
-
-#include <event2/event.h>
-
-static void
-fifo_read(evutil_socket_t fd, short event, void *arg)
-{
- char buf[255];
- int len;
- struct event *ev = arg;
-#ifdef _WIN32
- DWORD dwBytesRead;
-#endif
-
- fprintf(stderr, "fifo_read called with fd: %d, event: %d, arg: %p\n",
- (int)fd, event, arg);
-#ifdef _WIN32
- len = ReadFile((HANDLE)fd, buf, sizeof(buf) - 1, &dwBytesRead, NULL);
-
- /* Check for end of file. */
- if (len && dwBytesRead == 0) {
- fprintf(stderr, "End Of File");
- event_del(ev);
- return;
- }
-
- buf[dwBytesRead] = '\0';
-#else
- len = read(fd, buf, sizeof(buf) - 1);
-
- if (len <= 0) {
- if (len == -1)
- perror("read");
- else if (len == 0)
- fprintf(stderr, "Connection closed\n");
- event_del(ev);
- event_base_loopbreak(event_get_base(ev));
- return;
- }
-
- buf[len] = '\0';
-#endif
- fprintf(stdout, "Read: %s\n", buf);
-}
-
-/* On Unix, cleanup event.fifo if SIGINT is received. */
-#ifndef _WIN32
-static void
-signal_cb(evutil_socket_t fd, short event, void *arg)
-{
- struct event_base *base = arg;
- event_base_loopbreak(base);
-}
-#endif
-
-int
-main(int argc, char **argv)
-{
- struct event *evfifo;
- struct event_base* base;
-#ifdef _WIN32
- HANDLE socket;
- /* Open a file. */
- socket = CreateFileA("test.txt", /* open File */
- GENERIC_READ, /* open for reading */
- 0, /* do not share */
- NULL, /* no security */
- OPEN_EXISTING, /* existing file only */
- FILE_ATTRIBUTE_NORMAL, /* normal file */
- NULL); /* no attr. template */
-
- if (socket == INVALID_HANDLE_VALUE)
- return 1;
-
-#else
- struct event *signal_int;
- struct stat st;
- const char *fifo = "event.fifo";
- int socket;
-
- if (lstat(fifo, &st) == 0) {
- if ((st.st_mode & S_IFMT) == S_IFREG) {
- errno = EEXIST;
- perror("lstat");
- exit(1);
- }
- }
-
- unlink(fifo);
- if (mkfifo(fifo, 0600) == -1) {
- perror("mkfifo");
- exit(1);
- }
-
- socket = open(fifo, O_RDONLY | O_NONBLOCK, 0);
-
- if (socket == -1) {
- perror("open");
- exit(1);
- }
-
- fprintf(stderr, "Write data to %s\n", fifo);
-#endif
- /* Initalize the event library */
- base = event_base_new();
-
- /* Initalize one event */
-#ifdef _WIN32
- evfifo = event_new(base, (evutil_socket_t)socket, EV_READ|EV_PERSIST, fifo_read,
- event_self_cbarg());
-#else
- /* catch SIGINT so that event.fifo can be cleaned up */
- signal_int = evsignal_new(base, SIGINT, signal_cb, base);
- event_add(signal_int, NULL);
-
- evfifo = event_new(base, socket, EV_READ|EV_PERSIST, fifo_read,
- event_self_cbarg());
-#endif
-
- /* Add it to the active events, without a timeout */
- event_add(evfifo, NULL);
-
- event_base_dispatch(base);
- event_base_free(base);
-#ifdef _WIN32
- CloseHandle(socket);
-#else
- close(socket);
- unlink(fifo);
-#endif
- libevent_global_shutdown();
- return (0);
-}
-
diff --git a/sample/hello-world.c b/sample/hello-world.c
deleted file mode 100644
index 2023cd6..0000000
--- a/sample/hello-world.c
+++ /dev/null
@@ -1,141 +0,0 @@
-/*
- This example program provides a trivial server program that listens for TCP
- connections on port 9995. When they arrive, it writes a short message to
- each client connection, and closes each connection once it is flushed.
-
- Where possible, it exits cleanly in response to a SIGINT (ctrl-c).
-*/
-
-
-#include <string.h>
-#include <errno.h>
-#include <stdio.h>
-#include <signal.h>
-#ifndef _WIN32
-#include <netinet/in.h>
-# ifdef _XOPEN_SOURCE_EXTENDED
-# include <arpa/inet.h>
-# endif
-#include <sys/socket.h>
-#endif
-
-#include <event2/bufferevent.h>
-#include <event2/buffer.h>
-#include <event2/listener.h>
-#include <event2/util.h>
-#include <event2/event.h>
-
-static const char MESSAGE[] = "Hello, World!\n";
-
-static const int PORT = 9995;
-
-static void listener_cb(struct evconnlistener *, evutil_socket_t,
- struct sockaddr *, int socklen, void *);
-static void conn_writecb(struct bufferevent *, void *);
-static void conn_eventcb(struct bufferevent *, short, void *);
-static void signal_cb(evutil_socket_t, short, void *);
-
-int
-main(int argc, char **argv)
-{
- struct event_base *base;
- struct evconnlistener *listener;
- struct event *signal_event;
-
- struct sockaddr_in sin;
-#ifdef _WIN32
- WSADATA wsa_data;
- WSAStartup(0x0201, &wsa_data);
-#endif
-
- base = event_base_new();
- if (!base) {
- fprintf(stderr, "Could not initialize libevent!\n");
- return 1;
- }
-
- memset(&sin, 0, sizeof(sin));
- sin.sin_family = AF_INET;
- sin.sin_port = htons(PORT);
-
- listener = evconnlistener_new_bind(base, listener_cb, (void *)base,
- LEV_OPT_REUSEABLE|LEV_OPT_CLOSE_ON_FREE, -1,
- (struct sockaddr*)&sin,
- sizeof(sin));
-
- if (!listener) {
- fprintf(stderr, "Could not create a listener!\n");
- return 1;
- }
-
- signal_event = evsignal_new(base, SIGINT, signal_cb, (void *)base);
-
- if (!signal_event || event_add(signal_event, NULL)<0) {
- fprintf(stderr, "Could not create/add a signal event!\n");
- return 1;
- }
-
- event_base_dispatch(base);
-
- evconnlistener_free(listener);
- event_free(signal_event);
- event_base_free(base);
-
- printf("done\n");
- return 0;
-}
-
-static void
-listener_cb(struct evconnlistener *listener, evutil_socket_t fd,
- struct sockaddr *sa, int socklen, void *user_data)
-{
- struct event_base *base = user_data;
- struct bufferevent *bev;
-
- bev = bufferevent_socket_new(base, fd, BEV_OPT_CLOSE_ON_FREE);
- if (!bev) {
- fprintf(stderr, "Error constructing bufferevent!");
- event_base_loopbreak(base);
- return;
- }
- bufferevent_setcb(bev, NULL, conn_writecb, conn_eventcb, NULL);
- bufferevent_enable(bev, EV_WRITE);
- bufferevent_disable(bev, EV_READ);
-
- bufferevent_write(bev, MESSAGE, strlen(MESSAGE));
-}
-
-static void
-conn_writecb(struct bufferevent *bev, void *user_data)
-{
- struct evbuffer *output = bufferevent_get_output(bev);
- if (evbuffer_get_length(output) == 0) {
- printf("flushed answer\n");
- bufferevent_free(bev);
- }
-}
-
-static void
-conn_eventcb(struct bufferevent *bev, short events, void *user_data)
-{
- if (events & BEV_EVENT_EOF) {
- printf("Connection closed.\n");
- } else if (events & BEV_EVENT_ERROR) {
- printf("Got an error on the connection: %s\n",
- strerror(errno));/*XXX win32*/
- }
- /* None of the other events can happen here, since we haven't enabled
- * timeouts */
- bufferevent_free(bev);
-}
-
-static void
-signal_cb(evutil_socket_t sig, short events, void *user_data)
-{
- struct event_base *base = user_data;
- struct timeval delay = { 2, 0 };
-
- printf("Caught an interrupt signal; exiting cleanly in two seconds.\n");
-
- event_base_loopexit(base, &delay);
-}
diff --git a/sample/hostcheck.c b/sample/hostcheck.c
deleted file mode 100644
index 5070936..0000000
--- a/sample/hostcheck.c
+++ /dev/null
@@ -1,217 +0,0 @@
-/***************************************************************************
- * _ _ ____ _
- * Project ___| | | | _ \| |
- * / __| | | | |_) | |
- * | (__| |_| | _ <| |___
- * \___|\___/|_| \_\_____|
- *
- * Copyright (C) 1998 - 2012, Daniel Stenberg, <daniel@haxx.se>, et al.
- *
- * This software is licensed as described in the file COPYING, which
- * you should have received as part of this distribution. The terms
- * are also available at http://curl.haxx.se/docs/copyright.html.
- *
- * You may opt to use, copy, modify, merge, publish, distribute and/or sell
- * copies of the Software, and permit persons to whom the Software is
- * furnished to do so, under the terms of the COPYING file.
- *
- * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
- * KIND, either express or implied.
- *
- ***************************************************************************/
-
-/* This file is an amalgamation of hostcheck.c and most of rawstr.c
- from cURL. The contents of the COPYING file mentioned above are:
-
-COPYRIGHT AND PERMISSION NOTICE
-
-Copyright (c) 1996 - 2013, Daniel Stenberg, <daniel@haxx.se>.
-
-All rights reserved.
-
-Permission to use, copy, modify, and distribute this software for any purpose
-with or without fee is hereby granted, provided that the above copyright
-notice and this permission notice appear in all copies.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. IN
-NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
-DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
-OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE
-OR OTHER DEALINGS IN THE SOFTWARE.
-
-Except as contained in this notice, the name of a copyright holder shall not
-be used in advertising or otherwise to promote the sale, use or other dealings
-in this Software without prior written authorization of the copyright holder.
-*/
-
-#include "hostcheck.h"
-#include <string.h>
-
-/* Portable, consistent toupper (remember EBCDIC). Do not use toupper() because
- its behavior is altered by the current locale. */
-static char Curl_raw_toupper(char in)
-{
- switch (in) {
- case 'a':
- return 'A';
- case 'b':
- return 'B';
- case 'c':
- return 'C';
- case 'd':
- return 'D';
- case 'e':
- return 'E';
- case 'f':
- return 'F';
- case 'g':
- return 'G';
- case 'h':
- return 'H';
- case 'i':
- return 'I';
- case 'j':
- return 'J';
- case 'k':
- return 'K';
- case 'l':
- return 'L';
- case 'm':
- return 'M';
- case 'n':
- return 'N';
- case 'o':
- return 'O';
- case 'p':
- return 'P';
- case 'q':
- return 'Q';
- case 'r':
- return 'R';
- case 's':
- return 'S';
- case 't':
- return 'T';
- case 'u':
- return 'U';
- case 'v':
- return 'V';
- case 'w':
- return 'W';
- case 'x':
- return 'X';
- case 'y':
- return 'Y';
- case 'z':
- return 'Z';
- }
- return in;
-}
-
-/*
- * Curl_raw_equal() is for doing "raw" case insensitive strings. This is meant
- * to be locale independent and only compare strings we know are safe for
- * this. See http://daniel.haxx.se/blog/2008/10/15/strcasecmp-in-turkish/ for
- * some further explanation to why this function is necessary.
- *
- * The function is capable of comparing a-z case insensitively even for
- * non-ascii.
- */
-
-static int Curl_raw_equal(const char *first, const char *second)
-{
- while(*first && *second) {
- if(Curl_raw_toupper(*first) != Curl_raw_toupper(*second))
- /* get out of the loop as soon as they don't match */
- break;
- first++;
- second++;
- }
- /* we do the comparison here (possibly again), just to make sure that if the
- loop above is skipped because one of the strings reached zero, we must not
- return this as a successful match */
- return (Curl_raw_toupper(*first) == Curl_raw_toupper(*second));
-}
-
-static int Curl_raw_nequal(const char *first, const char *second, size_t max)
-{
- while(*first && *second && max) {
- if(Curl_raw_toupper(*first) != Curl_raw_toupper(*second)) {
- break;
- }
- max--;
- first++;
- second++;
- }
- if(0 == max)
- return 1; /* they are equal this far */
-
- return Curl_raw_toupper(*first) == Curl_raw_toupper(*second);
-}
-
-/*
- * Match a hostname against a wildcard pattern.
- * E.g.
- * "foo.host.com" matches "*.host.com".
- *
- * We use the matching rule described in RFC6125, section 6.4.3.
- * http://tools.ietf.org/html/rfc6125#section-6.4.3
- */
-
-static int hostmatch(const char *hostname, const char *pattern)
-{
- const char *pattern_label_end, *pattern_wildcard, *hostname_label_end;
- int wildcard_enabled;
- size_t prefixlen, suffixlen;
- pattern_wildcard = strchr(pattern, '*');
- if(pattern_wildcard == NULL)
- return Curl_raw_equal(pattern, hostname) ?
- CURL_HOST_MATCH : CURL_HOST_NOMATCH;
-
- /* We require at least 2 dots in pattern to avoid too wide wildcard
- match. */
- wildcard_enabled = 1;
- pattern_label_end = strchr(pattern, '.');
- if(pattern_label_end == NULL || strchr(pattern_label_end+1, '.') == NULL ||
- pattern_wildcard > pattern_label_end ||
- Curl_raw_nequal(pattern, "xn--", 4)) {
- wildcard_enabled = 0;
- }
- if(!wildcard_enabled)
- return Curl_raw_equal(pattern, hostname) ?
- CURL_HOST_MATCH : CURL_HOST_NOMATCH;
-
- hostname_label_end = strchr(hostname, '.');
- if(hostname_label_end == NULL ||
- !Curl_raw_equal(pattern_label_end, hostname_label_end))
- return CURL_HOST_NOMATCH;
-
- /* The wildcard must match at least one character, so the left-most
- label of the hostname is at least as large as the left-most label
- of the pattern. */
- if(hostname_label_end - hostname < pattern_label_end - pattern)
- return CURL_HOST_NOMATCH;
-
- prefixlen = pattern_wildcard - pattern;
- suffixlen = pattern_label_end - (pattern_wildcard+1);
- return Curl_raw_nequal(pattern, hostname, prefixlen) &&
- Curl_raw_nequal(pattern_wildcard+1, hostname_label_end - suffixlen,
- suffixlen) ?
- CURL_HOST_MATCH : CURL_HOST_NOMATCH;
-}
-
-int Curl_cert_hostcheck(const char *match_pattern, const char *hostname)
-{
- if(!match_pattern || !*match_pattern ||
- !hostname || !*hostname) /* sanity check */
- return 0;
-
- if(Curl_raw_equal(hostname, match_pattern)) /* trivial case */
- return 1;
-
- if(hostmatch(hostname,match_pattern) == CURL_HOST_MATCH)
- return 1;
- return 0;
-}
diff --git a/sample/hostcheck.h b/sample/hostcheck.h
deleted file mode 100644
index f40bc43..0000000
--- a/sample/hostcheck.h
+++ /dev/null
@@ -1,30 +0,0 @@
-#ifndef HEADER_CURL_HOSTCHECK_H
-#define HEADER_CURL_HOSTCHECK_H
-/***************************************************************************
- * _ _ ____ _
- * Project ___| | | | _ \| |
- * / __| | | | |_) | |
- * | (__| |_| | _ <| |___
- * \___|\___/|_| \_\_____|
- *
- * Copyright (C) 1998 - 2012, Daniel Stenberg, <daniel@haxx.se>, et al.
- *
- * This software is licensed as described in the file COPYING, which
- * you should have received as part of this distribution. The terms
- * are also available at http://curl.haxx.se/docs/copyright.html.
- *
- * You may opt to use, copy, modify, merge, publish, distribute and/or sell
- * copies of the Software, and permit persons to whom the Software is
- * furnished to do so, under the terms of the COPYING file.
- *
- * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
- * KIND, either express or implied.
- *
- ***************************************************************************/
-
-#define CURL_HOST_NOMATCH 0
-#define CURL_HOST_MATCH 1
-int Curl_cert_hostcheck(const char *match_pattern, const char *hostname);
-
-#endif /* HEADER_CURL_HOSTCHECK_H */
-
diff --git a/sample/http-connect.c b/sample/http-connect.c
deleted file mode 100644
index a44d001..0000000
--- a/sample/http-connect.c
+++ /dev/null
@@ -1,117 +0,0 @@
-#include "event2/event-config.h"
-
-#include <event2/event.h>
-#include <event2/http.h>
-#include <event2/http_struct.h>
-#include <event2/buffer.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <limits.h>
-
-#define VERIFY(cond) do { \
- if (!(cond)) { \
- fprintf(stderr, "[error] %s\n", #cond); \
- } \
-} while (0); \
-
-#define URL_MAX 4096
-
-struct connect_base
-{
- struct evhttp_connection *evcon;
- struct evhttp_uri *location;
-};
-
-static void get_cb(struct evhttp_request *req, void *arg)
-{
- ev_ssize_t len;
- struct evbuffer *evbuf;
-
- VERIFY(req);
-
- evbuf = evhttp_request_get_input_buffer(req);
- len = evbuffer_get_length(evbuf);
- fwrite(evbuffer_pullup(evbuf, len), len, 1, stdout);
- evbuffer_drain(evbuf, len);
-}
-
-static void connect_cb(struct evhttp_request *proxy_req, void *arg)
-{
- char buffer[URL_MAX];
-
- struct connect_base *base = arg;
- struct evhttp_connection *evcon = base->evcon;
- struct evhttp_uri *location = base->location;
-
- VERIFY(proxy_req);
- if (evcon) {
- struct evhttp_request *req = evhttp_request_new(get_cb, NULL);
- evhttp_add_header(req->output_headers, "Connection", "close");
- VERIFY(!evhttp_make_request(evcon, req, EVHTTP_REQ_GET,
- evhttp_uri_join(location, buffer, URL_MAX)));
- }
-}
-
-int main(int argc, const char **argv)
-{
- char buffer[URL_MAX];
-
- struct evhttp_uri *host_port;
- struct evhttp_uri *location;
- struct evhttp_uri *proxy;
-
- struct event_base *base;
- struct evhttp_connection *evcon;
- struct evhttp_request *req;
-
- struct connect_base connect_base;
-
- if (argc != 3) {
- printf("Usage: %s proxy url\n", argv[0]);
- return 1;
- }
-
- {
- proxy = evhttp_uri_parse(argv[1]);
- VERIFY(evhttp_uri_get_host(proxy));
- VERIFY(evhttp_uri_get_port(proxy) > 0);
- }
- {
- host_port = evhttp_uri_parse(argv[2]);
- evhttp_uri_set_scheme(host_port, NULL);
- evhttp_uri_set_userinfo(host_port, NULL);
- evhttp_uri_set_path(host_port, NULL);
- evhttp_uri_set_query(host_port, NULL);
- evhttp_uri_set_fragment(host_port, NULL);
- VERIFY(evhttp_uri_get_host(host_port));
- VERIFY(evhttp_uri_get_port(host_port) > 0);
- }
- {
- location = evhttp_uri_parse(argv[2]);
- evhttp_uri_set_scheme(location, NULL);
- evhttp_uri_set_userinfo(location, 0);
- evhttp_uri_set_host(location, NULL);
- evhttp_uri_set_port(location, -1);
- }
-
- VERIFY(base = event_base_new());
- VERIFY(evcon = evhttp_connection_base_new(base, NULL,
- evhttp_uri_get_host(proxy), evhttp_uri_get_port(proxy)));
- connect_base.evcon = evcon;
- connect_base.location = location;
- VERIFY(req = evhttp_request_new(connect_cb, &connect_base));
-
- evhttp_add_header(req->output_headers, "Connection", "keep-alive");
- evhttp_add_header(req->output_headers, "Proxy-Connection", "keep-alive");
- evutil_snprintf(buffer, URL_MAX, "%s:%d",
- evhttp_uri_get_host(host_port), evhttp_uri_get_port(host_port));
- evhttp_make_request(evcon, req, EVHTTP_REQ_CONNECT, buffer);
-
- event_base_dispatch(base);
- evhttp_connection_free(evcon);
- event_base_free(base);
- evhttp_uri_free(proxy);
- evhttp_uri_free(host_port);
- evhttp_uri_free(location);
- return 0;
-}
diff --git a/sample/http-server.c b/sample/http-server.c
deleted file mode 100644
index 579feea..0000000
--- a/sample/http-server.c
+++ /dev/null
@@ -1,418 +0,0 @@
-/*
- A trivial static http webserver using Libevent's evhttp.
-
- This is not the best code in the world, and it does some fairly stupid stuff
- that you would never want to do in a production webserver. Caveat hackor!
-
- */
-
-/* Compatibility for possible missing IPv6 declarations */
-#include "../util-internal.h"
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include <sys/types.h>
-#include <sys/stat.h>
-
-#ifdef _WIN32
-#include <winsock2.h>
-#include <ws2tcpip.h>
-#include <windows.h>
-#include <io.h>
-#include <fcntl.h>
-#ifndef S_ISDIR
-#define S_ISDIR(x) (((x) & S_IFMT) == S_IFDIR)
-#endif
-#else
-#include <sys/stat.h>
-#include <sys/socket.h>
-#include <signal.h>
-#include <fcntl.h>
-#include <unistd.h>
-#include <dirent.h>
-#endif
-
-#include <event2/event.h>
-#include <event2/http.h>
-#include <event2/buffer.h>
-#include <event2/util.h>
-#include <event2/keyvalq_struct.h>
-
-#ifdef EVENT__HAVE_NETINET_IN_H
-#include <netinet/in.h>
-# ifdef _XOPEN_SOURCE_EXTENDED
-# include <arpa/inet.h>
-# endif
-#endif
-
-#ifdef _WIN32
-#ifndef stat
-#define stat _stat
-#endif
-#ifndef fstat
-#define fstat _fstat
-#endif
-#ifndef open
-#define open _open
-#endif
-#ifndef close
-#define close _close
-#endif
-#ifndef O_RDONLY
-#define O_RDONLY _O_RDONLY
-#endif
-#endif
-
-char uri_root[512];
-
-static const struct table_entry {
- const char *extension;
- const char *content_type;
-} content_type_table[] = {
- { "txt", "text/plain" },
- { "c", "text/plain" },
- { "h", "text/plain" },
- { "html", "text/html" },
- { "htm", "text/htm" },
- { "css", "text/css" },
- { "gif", "image/gif" },
- { "jpg", "image/jpeg" },
- { "jpeg", "image/jpeg" },
- { "png", "image/png" },
- { "pdf", "application/pdf" },
- { "ps", "application/postscript" },
- { NULL, NULL },
-};
-
-/* Try to guess a good content-type for 'path' */
-static const char *
-guess_content_type(const char *path)
-{
- const char *last_period, *extension;
- const struct table_entry *ent;
- last_period = strrchr(path, '.');
- if (!last_period || strchr(last_period, '/'))
- goto not_found; /* no exension */
- extension = last_period + 1;
- for (ent = &content_type_table[0]; ent->extension; ++ent) {
- if (!evutil_ascii_strcasecmp(ent->extension, extension))
- return ent->content_type;
- }
-
-not_found:
- return "application/misc";
-}
-
-/* Callback used for the /dump URI, and for every non-GET request:
- * dumps all information to stdout and gives back a trivial 200 ok */
-static void
-dump_request_cb(struct evhttp_request *req, void *arg)
-{
- const char *cmdtype;
- struct evkeyvalq *headers;
- struct evkeyval *header;
- struct evbuffer *buf;
-
- switch (evhttp_request_get_command(req)) {
- case EVHTTP_REQ_GET: cmdtype = "GET"; break;
- case EVHTTP_REQ_POST: cmdtype = "POST"; break;
- case EVHTTP_REQ_HEAD: cmdtype = "HEAD"; break;
- case EVHTTP_REQ_PUT: cmdtype = "PUT"; break;
- case EVHTTP_REQ_DELETE: cmdtype = "DELETE"; break;
- case EVHTTP_REQ_OPTIONS: cmdtype = "OPTIONS"; break;
- case EVHTTP_REQ_TRACE: cmdtype = "TRACE"; break;
- case EVHTTP_REQ_CONNECT: cmdtype = "CONNECT"; break;
- case EVHTTP_REQ_PATCH: cmdtype = "PATCH"; break;
- default: cmdtype = "unknown"; break;
- }
-
- printf("Received a %s request for %s\nHeaders:\n",
- cmdtype, evhttp_request_get_uri(req));
-
- headers = evhttp_request_get_input_headers(req);
- for (header = headers->tqh_first; header;
- header = header->next.tqe_next) {
- printf(" %s: %s\n", header->key, header->value);
- }
-
- buf = evhttp_request_get_input_buffer(req);
- puts("Input data: <<<");
- while (evbuffer_get_length(buf)) {
- int n;
- char cbuf[128];
- n = evbuffer_remove(buf, cbuf, sizeof(cbuf));
- if (n > 0)
- (void) fwrite(cbuf, 1, n, stdout);
- }
- puts(">>>");
-
- evhttp_send_reply(req, 200, "OK", NULL);
-}
-
-/* This callback gets invoked when we get any http request that doesn't match
- * any other callback. Like any evhttp server callback, it has a simple job:
- * it must eventually call evhttp_send_error() or evhttp_send_reply().
- */
-static void
-send_document_cb(struct evhttp_request *req, void *arg)
-{
- struct evbuffer *evb = NULL;
- const char *docroot = arg;
- const char *uri = evhttp_request_get_uri(req);
- struct evhttp_uri *decoded = NULL;
- const char *path;
- char *decoded_path;
- char *whole_path = NULL;
- size_t len;
- int fd = -1;
- struct stat st;
-
- if (evhttp_request_get_command(req) != EVHTTP_REQ_GET) {
- dump_request_cb(req, arg);
- return;
- }
-
- printf("Got a GET request for <%s>\n", uri);
-
- /* Decode the URI */
- decoded = evhttp_uri_parse(uri);
- if (!decoded) {
- printf("It's not a good URI. Sending BADREQUEST\n");
- evhttp_send_error(req, HTTP_BADREQUEST, 0);
- return;
- }
-
- /* Let's see what path the user asked for. */
- path = evhttp_uri_get_path(decoded);
- if (!path) path = "/";
-
- /* We need to decode it, to see what path the user really wanted. */
- decoded_path = evhttp_uridecode(path, 0, NULL);
- if (decoded_path == NULL)
- goto err;
- /* Don't allow any ".."s in the path, to avoid exposing stuff outside
- * of the docroot. This test is both overzealous and underzealous:
- * it forbids aceptable paths like "/this/one..here", but it doesn't
- * do anything to prevent symlink following." */
- if (strstr(decoded_path, ".."))
- goto err;
-
- len = strlen(decoded_path)+strlen(docroot)+2;
- if (!(whole_path = malloc(len))) {
- perror("malloc");
- goto err;
- }
- evutil_snprintf(whole_path, len, "%s/%s", docroot, decoded_path);
-
- if (stat(whole_path, &st)<0) {
- goto err;
- }
-
- /* This holds the content we're sending. */
- evb = evbuffer_new();
-
- if (S_ISDIR(st.st_mode)) {
- /* If it's a directory, read the comments and make a little
- * index page */
-#ifdef _WIN32
- HANDLE d;
- WIN32_FIND_DATAA ent;
- char *pattern;
- size_t dirlen;
-#else
- DIR *d;
- struct dirent *ent;
-#endif
- const char *trailing_slash = "";
-
- if (!strlen(path) || path[strlen(path)-1] != '/')
- trailing_slash = "/";
-
-#ifdef _WIN32
- dirlen = strlen(whole_path);
- pattern = malloc(dirlen+3);
- memcpy(pattern, whole_path, dirlen);
- pattern[dirlen] = '\\';
- pattern[dirlen+1] = '*';
- pattern[dirlen+2] = '\0';
- d = FindFirstFileA(pattern, &ent);
- free(pattern);
- if (d == INVALID_HANDLE_VALUE)
- goto err;
-#else
- if (!(d = opendir(whole_path)))
- goto err;
-#endif
-
- evbuffer_add_printf(evb,
- "<!DOCTYPE html>\n"
- "<html>\n <head>\n"
- " <meta charset='utf-8'>\n"
- " <title>%s</title>\n"
- " <base href='%s%s'>\n"
- " </head>\n"
- " <body>\n"
- " <h1>%s</h1>\n"
- " <ul>\n",
- decoded_path, /* XXX html-escape this. */
- path, /* XXX html-escape this? */
- trailing_slash,
- decoded_path /* XXX html-escape this */);
-#ifdef _WIN32
- do {
- const char *name = ent.cFileName;
-#else
- while ((ent = readdir(d))) {
- const char *name = ent->d_name;
-#endif
- evbuffer_add_printf(evb,
- " <li><a href=\"%s\">%s</a>\n",
- name, name);/* XXX escape this */
-#ifdef _WIN32
- } while (FindNextFileA(d, &ent));
-#else
- }
-#endif
- evbuffer_add_printf(evb, "</ul></body></html>\n");
-#ifdef _WIN32
- FindClose(d);
-#else
- closedir(d);
-#endif
- evhttp_add_header(evhttp_request_get_output_headers(req),
- "Content-Type", "text/html");
- } else {
- /* Otherwise it's a file; add it to the buffer to get
- * sent via sendfile */
- const char *type = guess_content_type(decoded_path);
- if ((fd = open(whole_path, O_RDONLY)) < 0) {
- perror("open");
- goto err;
- }
-
- if (fstat(fd, &st)<0) {
- /* Make sure the length still matches, now that we
- * opened the file :/ */
- perror("fstat");
- goto err;
- }
- evhttp_add_header(evhttp_request_get_output_headers(req),
- "Content-Type", type);
- evbuffer_add_file(evb, fd, 0, st.st_size);
- }
-
- evhttp_send_reply(req, 200, "OK", evb);
- goto done;
-err:
- evhttp_send_error(req, 404, "Document was not found");
- if (fd>=0)
- close(fd);
-done:
- if (decoded)
- evhttp_uri_free(decoded);
- if (decoded_path)
- free(decoded_path);
- if (whole_path)
- free(whole_path);
- if (evb)
- evbuffer_free(evb);
-}
-
-static void
-syntax(void)
-{
- fprintf(stdout, "Syntax: http-server <docroot>\n");
-}
-
-int
-main(int argc, char **argv)
-{
- struct event_base *base;
- struct evhttp *http;
- struct evhttp_bound_socket *handle;
-
- ev_uint16_t port = 0;
-#ifdef _WIN32
- WSADATA WSAData;
- WSAStartup(0x101, &WSAData);
-#else
- if (signal(SIGPIPE, SIG_IGN) == SIG_ERR)
- return (1);
-#endif
- if (argc < 2) {
- syntax();
- return 1;
- }
-
- base = event_base_new();
- if (!base) {
- fprintf(stderr, "Couldn't create an event_base: exiting\n");
- return 1;
- }
-
- /* Create a new evhttp object to handle requests. */
- http = evhttp_new(base);
- if (!http) {
- fprintf(stderr, "couldn't create evhttp. Exiting.\n");
- return 1;
- }
-
- /* The /dump URI will dump all requests to stdout and say 200 ok. */
- evhttp_set_cb(http, "/dump", dump_request_cb, NULL);
-
- /* We want to accept arbitrary requests, so we need to set a "generic"
- * cb. We can also add callbacks for specific paths. */
- evhttp_set_gencb(http, send_document_cb, argv[1]);
-
- /* Now we tell the evhttp what port to listen on */
- handle = evhttp_bind_socket_with_handle(http, "0.0.0.0", port);
- if (!handle) {
- fprintf(stderr, "couldn't bind to port %d. Exiting.\n",
- (int)port);
- return 1;
- }
-
- {
- /* Extract and display the address we're listening on. */
- struct sockaddr_storage ss;
- evutil_socket_t fd;
- ev_socklen_t socklen = sizeof(ss);
- char addrbuf[128];
- void *inaddr;
- const char *addr;
- int got_port = -1;
- fd = evhttp_bound_socket_get_fd(handle);
- memset(&ss, 0, sizeof(ss));
- if (getsockname(fd, (struct sockaddr *)&ss, &socklen)) {
- perror("getsockname() failed");
- return 1;
- }
- if (ss.ss_family == AF_INET) {
- got_port = ntohs(((struct sockaddr_in*)&ss)->sin_port);
- inaddr = &((struct sockaddr_in*)&ss)->sin_addr;
- } else if (ss.ss_family == AF_INET6) {
- got_port = ntohs(((struct sockaddr_in6*)&ss)->sin6_port);
- inaddr = &((struct sockaddr_in6*)&ss)->sin6_addr;
- } else {
- fprintf(stderr, "Weird address family %d\n",
- ss.ss_family);
- return 1;
- }
- addr = evutil_inet_ntop(ss.ss_family, inaddr, addrbuf,
- sizeof(addrbuf));
- if (addr) {
- printf("Listening on %s:%d\n", addr, got_port);
- evutil_snprintf(uri_root, sizeof(uri_root),
- "http://%s:%d",addr,got_port);
- } else {
- fprintf(stderr, "evutil_inet_ntop failed\n");
- return 1;
- }
- }
-
- event_base_dispatch(base);
-
- return 0;
-}
diff --git a/sample/https-client.c b/sample/https-client.c
deleted file mode 100644
index 7483956..0000000
--- a/sample/https-client.c
+++ /dev/null
@@ -1,502 +0,0 @@
-/*
- This is an example of how to hook up evhttp with bufferevent_ssl
-
- It just GETs an https URL given on the command-line and prints the response
- body to stdout.
-
- Actually, it also accepts plain http URLs to make it easy to compare http vs
- https code paths.
-
- Loosely based on le-proxy.c.
- */
-
-// Get rid of OSX 10.7 and greater deprecation warnings.
-#if defined(__APPLE__) && defined(__clang__)
-#pragma clang diagnostic ignored "-Wdeprecated-declarations"
-#endif
-
-#include <stdio.h>
-#include <assert.h>
-#include <stdlib.h>
-#include <string.h>
-#include <errno.h>
-
-#ifdef _WIN32
-#include <winsock2.h>
-#include <ws2tcpip.h>
-
-#define snprintf _snprintf
-#define strcasecmp _stricmp
-#else
-#include <sys/socket.h>
-#include <netinet/in.h>
-#endif
-
-#include <event2/bufferevent_ssl.h>
-#include <event2/bufferevent.h>
-#include <event2/buffer.h>
-#include <event2/listener.h>
-#include <event2/util.h>
-#include <event2/http.h>
-
-#include <openssl/ssl.h>
-#include <openssl/err.h>
-#include <openssl/rand.h>
-
-#include "openssl_hostname_validation.h"
-
-static struct event_base *base;
-static int ignore_cert = 0;
-
-static void
-http_request_done(struct evhttp_request *req, void *ctx)
-{
- char buffer[256];
- int nread;
-
- if (req == NULL) {
- /* If req is NULL, it means an error occurred, but
- * sadly we are mostly left guessing what the error
- * might have been. We'll do our best... */
- struct bufferevent *bev = (struct bufferevent *) ctx;
- unsigned long oslerr;
- int printed_err = 0;
- int errcode = EVUTIL_SOCKET_ERROR();
- fprintf(stderr, "some request failed - no idea which one though!\n");
- /* Print out the OpenSSL error queue that libevent
- * squirreled away for us, if any. */
- while ((oslerr = bufferevent_get_openssl_error(bev))) {
- ERR_error_string_n(oslerr, buffer, sizeof(buffer));
- fprintf(stderr, "%s\n", buffer);
- printed_err = 1;
- }
- /* If the OpenSSL error queue was empty, maybe it was a
- * socket error; let's try printing that. */
- if (! printed_err)
- fprintf(stderr, "socket error = %s (%d)\n",
- evutil_socket_error_to_string(errcode),
- errcode);
- return;
- }
-
- fprintf(stderr, "Response line: %d %s\n",
- evhttp_request_get_response_code(req),
- evhttp_request_get_response_code_line(req));
-
- while ((nread = evbuffer_remove(evhttp_request_get_input_buffer(req),
- buffer, sizeof(buffer)))
- > 0) {
- /* These are just arbitrary chunks of 256 bytes.
- * They are not lines, so we can't treat them as such. */
- fwrite(buffer, nread, 1, stdout);
- }
-}
-
-static void
-syntax(void)
-{
- fputs("Syntax:\n", stderr);
- fputs(" https-client -url <https-url> [-data data-file.bin] [-ignore-cert] [-retries num] [-timeout sec] [-crt crt]\n", stderr);
- fputs("Example:\n", stderr);
- fputs(" https-client -url https://ip.appspot.com/\n", stderr);
-}
-
-static void
-err(const char *msg)
-{
- fputs(msg, stderr);
-}
-
-static void
-err_openssl(const char *func)
-{
- fprintf (stderr, "%s failed:\n", func);
-
- /* This is the OpenSSL function that prints the contents of the
- * error stack to the specified file handle. */
- ERR_print_errors_fp (stderr);
-
- exit(1);
-}
-
-#ifndef _WIN32
-/* See http://archives.seul.org/libevent/users/Jan-2013/msg00039.html */
-static int cert_verify_callback(X509_STORE_CTX *x509_ctx, void *arg)
-{
- char cert_str[256];
- const char *host = (const char *) arg;
- const char *res_str = "X509_verify_cert failed";
- HostnameValidationResult res = Error;
-
- /* This is the function that OpenSSL would call if we hadn't called
- * SSL_CTX_set_cert_verify_callback(). Therefore, we are "wrapping"
- * the default functionality, rather than replacing it. */
- int ok_so_far = 0;
-
- X509 *server_cert = NULL;
-
- if (ignore_cert) {
- return 1;
- }
-
- ok_so_far = X509_verify_cert(x509_ctx);
-
- server_cert = X509_STORE_CTX_get_current_cert(x509_ctx);
-
- if (ok_so_far) {
- res = validate_hostname(host, server_cert);
-
- switch (res) {
- case MatchFound:
- res_str = "MatchFound";
- break;
- case MatchNotFound:
- res_str = "MatchNotFound";
- break;
- case NoSANPresent:
- res_str = "NoSANPresent";
- break;
- case MalformedCertificate:
- res_str = "MalformedCertificate";
- break;
- case Error:
- res_str = "Error";
- break;
- default:
- res_str = "WTF!";
- break;
- }
- }
-
- X509_NAME_oneline(X509_get_subject_name (server_cert),
- cert_str, sizeof (cert_str));
-
- if (res == MatchFound) {
- printf("https server '%s' has this certificate, "
- "which looks good to me:\n%s\n",
- host, cert_str);
- return 1;
- } else {
- printf("Got '%s' for hostname '%s' and certificate:\n%s\n",
- res_str, host, cert_str);
- return 0;
- }
-}
-#endif
-
-int
-main(int argc, char **argv)
-{
- int r;
-
- struct evhttp_uri *http_uri = NULL;
- const char *url = NULL, *data_file = NULL;
- const char *crt = "/etc/ssl/certs/ca-certificates.crt";
- const char *scheme, *host, *path, *query;
- char uri[256];
- int port;
- int retries = 0;
- int timeout = -1;
-
- SSL_CTX *ssl_ctx = NULL;
- SSL *ssl = NULL;
- struct bufferevent *bev;
- struct evhttp_connection *evcon = NULL;
- struct evhttp_request *req;
- struct evkeyvalq *output_headers;
- struct evbuffer *output_buffer;
-
- int i;
- int ret = 0;
- enum { HTTP, HTTPS } type = HTTP;
-
- for (i = 1; i < argc; i++) {
- if (!strcmp("-url", argv[i])) {
- if (i < argc - 1) {
- url = argv[i + 1];
- } else {
- syntax();
- goto error;
- }
- } else if (!strcmp("-crt", argv[i])) {
- if (i < argc - 1) {
- crt = argv[i + 1];
- } else {
- syntax();
- goto error;
- }
- } else if (!strcmp("-ignore-cert", argv[i])) {
- ignore_cert = 1;
- } else if (!strcmp("-data", argv[i])) {
- if (i < argc - 1) {
- data_file = argv[i + 1];
- } else {
- syntax();
- goto error;
- }
- } else if (!strcmp("-retries", argv[i])) {
- if (i < argc - 1) {
- retries = atoi(argv[i + 1]);
- } else {
- syntax();
- goto error;
- }
- } else if (!strcmp("-timeout", argv[i])) {
- if (i < argc - 1) {
- timeout = atoi(argv[i + 1]);
- } else {
- syntax();
- goto error;
- }
- } else if (!strcmp("-help", argv[i])) {
- syntax();
- goto error;
- }
- }
-
- if (!url) {
- syntax();
- goto error;
- }
-
-#ifdef _WIN32
- {
- WORD wVersionRequested;
- WSADATA wsaData;
- int err;
-
- wVersionRequested = MAKEWORD(2, 2);
-
- err = WSAStartup(wVersionRequested, &wsaData);
- if (err != 0) {
- printf("WSAStartup failed with error: %d\n", err);
- goto error;
- }
- }
-#endif // _WIN32
-
- http_uri = evhttp_uri_parse(url);
- if (http_uri == NULL) {
- err("malformed url");
- goto error;
- }
-
- scheme = evhttp_uri_get_scheme(http_uri);
- if (scheme == NULL || (strcasecmp(scheme, "https") != 0 &&
- strcasecmp(scheme, "http") != 0)) {
- err("url must be http or https");
- goto error;
- }
-
- host = evhttp_uri_get_host(http_uri);
- if (host == NULL) {
- err("url must have a host");
- goto error;
- }
-
- port = evhttp_uri_get_port(http_uri);
- if (port == -1) {
- port = (strcasecmp(scheme, "http") == 0) ? 80 : 443;
- }
-
- path = evhttp_uri_get_path(http_uri);
- if (strlen(path) == 0) {
- path = "/";
- }
-
- query = evhttp_uri_get_query(http_uri);
- if (query == NULL) {
- snprintf(uri, sizeof(uri) - 1, "%s", path);
- } else {
- snprintf(uri, sizeof(uri) - 1, "%s?%s", path, query);
- }
- uri[sizeof(uri) - 1] = '\0';
-
-#if OPENSSL_VERSION_NUMBER < 0x10100000L
- // Initialize OpenSSL
- SSL_library_init();
- ERR_load_crypto_strings();
- SSL_load_error_strings();
- OpenSSL_add_all_algorithms();
-#endif
-
- /* This isn't strictly necessary... OpenSSL performs RAND_poll
- * automatically on first use of random number generator. */
- r = RAND_poll();
- if (r == 0) {
- err_openssl("RAND_poll");
- goto error;
- }
-
- /* Create a new OpenSSL context */
- ssl_ctx = SSL_CTX_new(SSLv23_method());
- if (!ssl_ctx) {
- err_openssl("SSL_CTX_new");
- goto error;
- }
-
-#ifndef _WIN32
- /* TODO: Add certificate loading on Windows as well */
-
- /* Attempt to use the system's trusted root certificates.
- * (This path is only valid for Debian-based systems.) */
- if (1 != SSL_CTX_load_verify_locations(ssl_ctx, crt, NULL)) {
- err_openssl("SSL_CTX_load_verify_locations");
- goto error;
- }
- /* Ask OpenSSL to verify the server certificate. Note that this
- * does NOT include verifying that the hostname is correct.
- * So, by itself, this means anyone with any legitimate
- * CA-issued certificate for any website, can impersonate any
- * other website in the world. This is not good. See "The
- * Most Dangerous Code in the World" article at
- * https://crypto.stanford.edu/~dabo/pubs/abstracts/ssl-client-bugs.html
- */
- SSL_CTX_set_verify(ssl_ctx, SSL_VERIFY_PEER, NULL);
- /* This is how we solve the problem mentioned in the previous
- * comment. We "wrap" OpenSSL's validation routine in our
- * own routine, which also validates the hostname by calling
- * the code provided by iSECPartners. Note that even though
- * the "Everything You've Always Wanted to Know About
- * Certificate Validation With OpenSSL (But Were Afraid to
- * Ask)" paper from iSECPartners says very explicitly not to
- * call SSL_CTX_set_cert_verify_callback (at the bottom of
- * page 2), what we're doing here is safe because our
- * cert_verify_callback() calls X509_verify_cert(), which is
- * OpenSSL's built-in routine which would have been called if
- * we hadn't set the callback. Therefore, we're just
- * "wrapping" OpenSSL's routine, not replacing it. */
- SSL_CTX_set_cert_verify_callback(ssl_ctx, cert_verify_callback,
- (void *) host);
-#else // _WIN32
- (void)crt;
-#endif // _WIN32
-
- // Create event base
- base = event_base_new();
- if (!base) {
- perror("event_base_new()");
- goto error;
- }
-
- // Create OpenSSL bufferevent and stack evhttp on top of it
- ssl = SSL_new(ssl_ctx);
- if (ssl == NULL) {
- err_openssl("SSL_new()");
- goto error;
- }
-
- #ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
- // Set hostname for SNI extension
- SSL_set_tlsext_host_name(ssl, host);
- #endif
-
- if (strcasecmp(scheme, "http") == 0) {
- bev = bufferevent_socket_new(base, -1, BEV_OPT_CLOSE_ON_FREE);
- } else {
- type = HTTPS;
- bev = bufferevent_openssl_socket_new(base, -1, ssl,
- BUFFEREVENT_SSL_CONNECTING,
- BEV_OPT_CLOSE_ON_FREE|BEV_OPT_DEFER_CALLBACKS);
- }
-
- if (bev == NULL) {
- fprintf(stderr, "bufferevent_openssl_socket_new() failed\n");
- goto error;
- }
-
- bufferevent_openssl_set_allow_dirty_shutdown(bev, 1);
-
- // For simplicity, we let DNS resolution block. Everything else should be
- // asynchronous though.
- evcon = evhttp_connection_base_bufferevent_new(base, NULL, bev,
- host, port);
- if (evcon == NULL) {
- fprintf(stderr, "evhttp_connection_base_bufferevent_new() failed\n");
- goto error;
- }
-
- if (retries > 0) {
- evhttp_connection_set_retries(evcon, retries);
- }
- if (timeout >= 0) {
- evhttp_connection_set_timeout(evcon, timeout);
- }
-
- // Fire off the request
- req = evhttp_request_new(http_request_done, bev);
- if (req == NULL) {
- fprintf(stderr, "evhttp_request_new() failed\n");
- goto error;
- }
-
- output_headers = evhttp_request_get_output_headers(req);
- evhttp_add_header(output_headers, "Host", host);
- evhttp_add_header(output_headers, "Connection", "close");
-
- if (data_file) {
- /* NOTE: In production code, you'd probably want to use
- * evbuffer_add_file() or evbuffer_add_file_segment(), to
- * avoid needless copying. */
- FILE * f = fopen(data_file, "rb");
- char buf[1024];
- size_t s;
- size_t bytes = 0;
-
- if (!f) {
- syntax();
- goto error;
- }
-
- output_buffer = evhttp_request_get_output_buffer(req);
- while ((s = fread(buf, 1, sizeof(buf), f)) > 0) {
- evbuffer_add(output_buffer, buf, s);
- bytes += s;
- }
- evutil_snprintf(buf, sizeof(buf)-1, "%lu", (unsigned long)bytes);
- evhttp_add_header(output_headers, "Content-Length", buf);
- fclose(f);
- }
-
- r = evhttp_make_request(evcon, req, data_file ? EVHTTP_REQ_POST : EVHTTP_REQ_GET, uri);
- if (r != 0) {
- fprintf(stderr, "evhttp_make_request() failed\n");
- goto error;
- }
-
- event_base_dispatch(base);
- goto cleanup;
-
-error:
- ret = 1;
-cleanup:
- if (evcon)
- evhttp_connection_free(evcon);
- if (http_uri)
- evhttp_uri_free(http_uri);
- event_base_free(base);
-
- if (ssl_ctx)
- SSL_CTX_free(ssl_ctx);
- if (type == HTTP && ssl)
- SSL_free(ssl);
-#if OPENSSL_VERSION_NUMBER < 0x10100000L
- EVP_cleanup();
- ERR_free_strings();
-
-#ifdef EVENT__HAVE_ERR_REMOVE_THREAD_STATE
- ERR_remove_thread_state(NULL);
-#else
- ERR_remove_state(0);
-#endif
- CRYPTO_cleanup_all_ex_data();
-
- sk_SSL_COMP_free(SSL_COMP_get_compression_methods());
-#endif /*OPENSSL_VERSION_NUMBER < 0x10100000L */
-
-#ifdef _WIN32
- WSACleanup();
-#endif
-
- return ret;
-}
diff --git a/sample/include.am b/sample/include.am
deleted file mode 100644
index d1a7242..0000000
--- a/sample/include.am
+++ /dev/null
@@ -1,53 +0,0 @@
-# sample/include.am for libevent
-# Copyright 2000-2007 Niels Provos
-# Copyright 2007-2012 Niels Provos and Nick Mathewson
-#
-# See LICENSE for copying information.
-
-SAMPLES = \
- sample/dns-example \
- sample/event-read-fifo \
- sample/hello-world \
- sample/http-server \
- sample/http-connect \
- sample/signal-test \
- sample/time-test
-
-if OPENSSL
-SAMPLES += sample/le-proxy
-sample_le_proxy_SOURCES = sample/le-proxy.c
-sample_le_proxy_LDADD = libevent.la libevent_openssl.la ${OPENSSL_LIBS} ${OPENSSL_LIBADD}
-sample_le_proxy_INCLUDES = $(OPENSSL_INCS)
-
-SAMPLES += sample/https-client
-sample_https_client_SOURCES = \
- sample/https-client.c \
- sample/hostcheck.c \
- sample/openssl_hostname_validation.c
-sample_https_client_LDADD = libevent.la libevent_openssl.la ${OPENSSL_LIBS} ${OPENSSL_LIBADD}
-sample_https_client_INCLUDES = $(OPENSSL_INCS)
-noinst_HEADERS += \
- sample/hostcheck.h \
- sample/openssl_hostname_validation.h
-endif
-
-if BUILD_SAMPLES
-noinst_PROGRAMS += $(SAMPLES)
-endif
-
-$(SAMPLES) : libevent.la
-
-sample_event_read_fifo_SOURCES = sample/event-read-fifo.c
-sample_event_read_fifo_LDADD = $(LIBEVENT_GC_SECTIONS) libevent.la
-sample_time_test_SOURCES = sample/time-test.c
-sample_time_test_LDADD = $(LIBEVENT_GC_SECTIONS) libevent.la
-sample_signal_test_SOURCES = sample/signal-test.c
-sample_signal_test_LDADD = $(LIBEVENT_GC_SECTIONS) libevent.la
-sample_dns_example_SOURCES = sample/dns-example.c
-sample_dns_example_LDADD = $(LIBEVENT_GC_SECTIONS) libevent.la
-sample_hello_world_SOURCES = sample/hello-world.c
-sample_hello_world_LDADD = $(LIBEVENT_GC_SECTIONS) libevent.la
-sample_http_server_SOURCES = sample/http-server.c
-sample_http_server_LDADD = $(LIBEVENT_GC_SECTIONS) libevent.la
-sample_http_connect_SOURCES = sample/http-connect.c
-sample_http_connect_LDADD = $(LIBEVENT_GC_SECTIONS) libevent.la
diff --git a/sample/le-proxy.c b/sample/le-proxy.c
deleted file mode 100644
index 8d9b529..0000000
--- a/sample/le-proxy.c
+++ /dev/null
@@ -1,291 +0,0 @@
-/*
- This example code shows how to write an (optionally encrypting) SSL proxy
- with Libevent's bufferevent layer.
-
- XXX It's a little ugly and should probably be cleaned up.
- */
-
-// Get rid of OSX 10.7 and greater deprecation warnings.
-#if defined(__APPLE__) && defined(__clang__)
-#pragma clang diagnostic ignored "-Wdeprecated-declarations"
-#endif
-
-#include <stdio.h>
-#include <assert.h>
-#include <stdlib.h>
-#include <string.h>
-#include <errno.h>
-
-#ifdef _WIN32
-#include <winsock2.h>
-#include <ws2tcpip.h>
-#else
-#include <sys/socket.h>
-#include <netinet/in.h>
-#endif
-
-#include <event2/bufferevent_ssl.h>
-#include <event2/bufferevent.h>
-#include <event2/buffer.h>
-#include <event2/listener.h>
-#include <event2/util.h>
-
-#include <openssl/ssl.h>
-#include <openssl/err.h>
-#include <openssl/rand.h>
-#include "openssl-compat.h"
-
-static struct event_base *base;
-static struct sockaddr_storage listen_on_addr;
-static struct sockaddr_storage connect_to_addr;
-static int connect_to_addrlen;
-static int use_wrapper = 1;
-
-static SSL_CTX *ssl_ctx = NULL;
-
-#define MAX_OUTPUT (512*1024)
-
-static void drained_writecb(struct bufferevent *bev, void *ctx);
-static void eventcb(struct bufferevent *bev, short what, void *ctx);
-
-static void
-readcb(struct bufferevent *bev, void *ctx)
-{
- struct bufferevent *partner = ctx;
- struct evbuffer *src, *dst;
- size_t len;
- src = bufferevent_get_input(bev);
- len = evbuffer_get_length(src);
- if (!partner) {
- evbuffer_drain(src, len);
- return;
- }
- dst = bufferevent_get_output(partner);
- evbuffer_add_buffer(dst, src);
-
- if (evbuffer_get_length(dst) >= MAX_OUTPUT) {
- /* We're giving the other side data faster than it can
- * pass it on. Stop reading here until we have drained the
- * other side to MAX_OUTPUT/2 bytes. */
- bufferevent_setcb(partner, readcb, drained_writecb,
- eventcb, bev);
- bufferevent_setwatermark(partner, EV_WRITE, MAX_OUTPUT/2,
- MAX_OUTPUT);
- bufferevent_disable(bev, EV_READ);
- }
-}
-
-static void
-drained_writecb(struct bufferevent *bev, void *ctx)
-{
- struct bufferevent *partner = ctx;
-
- /* We were choking the other side until we drained our outbuf a bit.
- * Now it seems drained. */
- bufferevent_setcb(bev, readcb, NULL, eventcb, partner);
- bufferevent_setwatermark(bev, EV_WRITE, 0, 0);
- if (partner)
- bufferevent_enable(partner, EV_READ);
-}
-
-static void
-close_on_finished_writecb(struct bufferevent *bev, void *ctx)
-{
- struct evbuffer *b = bufferevent_get_output(bev);
-
- if (evbuffer_get_length(b) == 0) {
- bufferevent_free(bev);
- }
-}
-
-static void
-eventcb(struct bufferevent *bev, short what, void *ctx)
-{
- struct bufferevent *partner = ctx;
-
- if (what & (BEV_EVENT_EOF|BEV_EVENT_ERROR)) {
- if (what & BEV_EVENT_ERROR) {
- unsigned long err;
- while ((err = (bufferevent_get_openssl_error(bev)))) {
- const char *msg = (const char*)
- ERR_reason_error_string(err);
- const char *lib = (const char*)
- ERR_lib_error_string(err);
- const char *func = (const char*)
- ERR_func_error_string(err);
- fprintf(stderr,
- "%s in %s %s\n", msg, lib, func);
- }
- if (errno)
- perror("connection error");
- }
-
- if (partner) {
- /* Flush all pending data */
- readcb(bev, ctx);
-
- if (evbuffer_get_length(
- bufferevent_get_output(partner))) {
- /* We still have to flush data from the other
- * side, but when that's done, close the other
- * side. */
- bufferevent_setcb(partner,
- NULL, close_on_finished_writecb,
- eventcb, NULL);
- bufferevent_disable(partner, EV_READ);
- } else {
- /* We have nothing left to say to the other
- * side; close it. */
- bufferevent_free(partner);
- }
- }
- bufferevent_free(bev);
- }
-}
-
-static void
-syntax(void)
-{
- fputs("Syntax:\n", stderr);
- fputs(" le-proxy [-s] [-W] <listen-on-addr> <connect-to-addr>\n", stderr);
- fputs("Example:\n", stderr);
- fputs(" le-proxy 127.0.0.1:8888 1.2.3.4:80\n", stderr);
-
- exit(1);
-}
-
-static void
-accept_cb(struct evconnlistener *listener, evutil_socket_t fd,
- struct sockaddr *a, int slen, void *p)
-{
- struct bufferevent *b_out, *b_in;
- /* Create two linked bufferevent objects: one to connect, one for the
- * new connection */
- b_in = bufferevent_socket_new(base, fd,
- BEV_OPT_CLOSE_ON_FREE|BEV_OPT_DEFER_CALLBACKS);
-
- if (!ssl_ctx || use_wrapper)
- b_out = bufferevent_socket_new(base, -1,
- BEV_OPT_CLOSE_ON_FREE|BEV_OPT_DEFER_CALLBACKS);
- else {
- SSL *ssl = SSL_new(ssl_ctx);
- b_out = bufferevent_openssl_socket_new(base, -1, ssl,
- BUFFEREVENT_SSL_CONNECTING,
- BEV_OPT_CLOSE_ON_FREE|BEV_OPT_DEFER_CALLBACKS);
- }
-
- assert(b_in && b_out);
-
- if (bufferevent_socket_connect(b_out,
- (struct sockaddr*)&connect_to_addr, connect_to_addrlen)<0) {
- perror("bufferevent_socket_connect");
- bufferevent_free(b_out);
- bufferevent_free(b_in);
- return;
- }
-
- if (ssl_ctx && use_wrapper) {
- struct bufferevent *b_ssl;
- SSL *ssl = SSL_new(ssl_ctx);
- b_ssl = bufferevent_openssl_filter_new(base,
- b_out, ssl, BUFFEREVENT_SSL_CONNECTING,
- BEV_OPT_CLOSE_ON_FREE|BEV_OPT_DEFER_CALLBACKS);
- if (!b_ssl) {
- perror("Bufferevent_openssl_new");
- bufferevent_free(b_out);
- bufferevent_free(b_in);
- }
- b_out = b_ssl;
- }
-
- bufferevent_setcb(b_in, readcb, NULL, eventcb, b_out);
- bufferevent_setcb(b_out, readcb, NULL, eventcb, b_in);
-
- bufferevent_enable(b_in, EV_READ|EV_WRITE);
- bufferevent_enable(b_out, EV_READ|EV_WRITE);
-}
-
-int
-main(int argc, char **argv)
-{
- int i;
- int socklen;
-
- int use_ssl = 0;
- struct evconnlistener *listener;
-
- if (argc < 3)
- syntax();
-
- for (i=1; i < argc; ++i) {
- if (!strcmp(argv[i], "-s")) {
- use_ssl = 1;
- } else if (!strcmp(argv[i], "-W")) {
- use_wrapper = 0;
- } else if (argv[i][0] == '-') {
- syntax();
- } else
- break;
- }
-
- if (i+2 != argc)
- syntax();
-
- memset(&listen_on_addr, 0, sizeof(listen_on_addr));
- socklen = sizeof(listen_on_addr);
- if (evutil_parse_sockaddr_port(argv[i],
- (struct sockaddr*)&listen_on_addr, &socklen)<0) {
- int p = atoi(argv[i]);
- struct sockaddr_in *sin = (struct sockaddr_in*)&listen_on_addr;
- if (p < 1 || p > 65535)
- syntax();
- sin->sin_port = htons(p);
- sin->sin_addr.s_addr = htonl(0x7f000001);
- sin->sin_family = AF_INET;
- socklen = sizeof(struct sockaddr_in);
- }
-
- memset(&connect_to_addr, 0, sizeof(connect_to_addr));
- connect_to_addrlen = sizeof(connect_to_addr);
- if (evutil_parse_sockaddr_port(argv[i+1],
- (struct sockaddr*)&connect_to_addr, &connect_to_addrlen)<0)
- syntax();
-
- base = event_base_new();
- if (!base) {
- perror("event_base_new()");
- return 1;
- }
-
- if (use_ssl) {
- int r;
-#if OPENSSL_VERSION_NUMBER < 0x10100000L
- SSL_library_init();
- ERR_load_crypto_strings();
- SSL_load_error_strings();
- OpenSSL_add_all_algorithms();
-#endif
- r = RAND_poll();
- if (r == 0) {
- fprintf(stderr, "RAND_poll() failed.\n");
- return 1;
- }
- ssl_ctx = SSL_CTX_new(TLS_method());
- }
-
- listener = evconnlistener_new_bind(base, accept_cb, NULL,
- LEV_OPT_CLOSE_ON_FREE|LEV_OPT_CLOSE_ON_EXEC|LEV_OPT_REUSEABLE,
- -1, (struct sockaddr*)&listen_on_addr, socklen);
-
- if (! listener) {
- fprintf(stderr, "Couldn't open listener.\n");
- event_base_free(base);
- return 1;
- }
- event_base_dispatch(base);
-
- evconnlistener_free(listener);
- event_base_free(base);
-
- return 0;
-}
diff --git a/sample/openssl_hostname_validation.c b/sample/openssl_hostname_validation.c
deleted file mode 100644
index 40312f2..0000000
--- a/sample/openssl_hostname_validation.c
+++ /dev/null
@@ -1,177 +0,0 @@
-/* Obtained from: https://github.com/iSECPartners/ssl-conservatory */
-
-/*
-Copyright (C) 2012, iSEC Partners.
-
-Permission is hereby granted, free of charge, to any person obtaining a copy of
-this software and associated documentation files (the "Software"), to deal in
-the Software without restriction, including without limitation the rights to
-use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
-of the Software, and to permit persons to whom the Software is furnished to do
-so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in all
-copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-SOFTWARE.
- */
-
-/*
- * Helper functions to perform basic hostname validation using OpenSSL.
- *
- * Please read "everything-you-wanted-to-know-about-openssl.pdf" before
- * attempting to use this code. This whitepaper describes how the code works,
- * how it should be used, and what its limitations are.
- *
- * Author: Alban Diquet
- * License: See LICENSE
- *
- */
-
-// Get rid of OSX 10.7 and greater deprecation warnings.
-#if defined(__APPLE__) && defined(__clang__)
-#pragma clang diagnostic ignored "-Wdeprecated-declarations"
-#endif
-
-#include <openssl/x509v3.h>
-#include <openssl/ssl.h>
-#include <string.h>
-
-#include "openssl_hostname_validation.h"
-#include "hostcheck.h"
-
-#define HOSTNAME_MAX_SIZE 255
-
-#if OPENSSL_VERSION_NUMBER < 0x10100000L
-#define ASN1_STRING_get0_data ASN1_STRING_data
-#endif
-
-/**
-* Tries to find a match for hostname in the certificate's Common Name field.
-*
-* Returns MatchFound if a match was found.
-* Returns MatchNotFound if no matches were found.
-* Returns MalformedCertificate if the Common Name had a NUL character embedded in it.
-* Returns Error if the Common Name could not be extracted.
-*/
-static HostnameValidationResult matches_common_name(const char *hostname, const X509 *server_cert) {
- int common_name_loc = -1;
- X509_NAME_ENTRY *common_name_entry = NULL;
- ASN1_STRING *common_name_asn1 = NULL;
- const char *common_name_str = NULL;
-
- // Find the position of the CN field in the Subject field of the certificate
- common_name_loc = X509_NAME_get_index_by_NID(X509_get_subject_name((X509 *) server_cert), NID_commonName, -1);
- if (common_name_loc < 0) {
- return Error;
- }
-
- // Extract the CN field
- common_name_entry = X509_NAME_get_entry(X509_get_subject_name((X509 *) server_cert), common_name_loc);
- if (common_name_entry == NULL) {
- return Error;
- }
-
- // Convert the CN field to a C string
- common_name_asn1 = X509_NAME_ENTRY_get_data(common_name_entry);
- if (common_name_asn1 == NULL) {
- return Error;
- }
- common_name_str = (char *) ASN1_STRING_get0_data(common_name_asn1);
-
- // Make sure there isn't an embedded NUL character in the CN
- if ((size_t)ASN1_STRING_length(common_name_asn1) != strlen(common_name_str)) {
- return MalformedCertificate;
- }
-
- // Compare expected hostname with the CN
- if (Curl_cert_hostcheck(common_name_str, hostname) == CURL_HOST_MATCH) {
- return MatchFound;
- }
- else {
- return MatchNotFound;
- }
-}
-
-
-/**
-* Tries to find a match for hostname in the certificate's Subject Alternative Name extension.
-*
-* Returns MatchFound if a match was found.
-* Returns MatchNotFound if no matches were found.
-* Returns MalformedCertificate if any of the hostnames had a NUL character embedded in it.
-* Returns NoSANPresent if the SAN extension was not present in the certificate.
-*/
-static HostnameValidationResult matches_subject_alternative_name(const char *hostname, const X509 *server_cert) {
- HostnameValidationResult result = MatchNotFound;
- int i;
- int san_names_nb = -1;
- STACK_OF(GENERAL_NAME) *san_names = NULL;
-
- // Try to extract the names within the SAN extension from the certificate
- san_names = X509_get_ext_d2i((X509 *) server_cert, NID_subject_alt_name, NULL, NULL);
- if (san_names == NULL) {
- return NoSANPresent;
- }
- san_names_nb = sk_GENERAL_NAME_num(san_names);
-
- // Check each name within the extension
- for (i=0; i<san_names_nb; i++) {
- const GENERAL_NAME *current_name = sk_GENERAL_NAME_value(san_names, i);
-
- if (current_name->type == GEN_DNS) {
- // Current name is a DNS name, let's check it
- const char *dns_name = (char *) ASN1_STRING_get0_data(current_name->d.dNSName);
-
- // Make sure there isn't an embedded NUL character in the DNS name
- if ((size_t)ASN1_STRING_length(current_name->d.dNSName) != strlen(dns_name)) {
- result = MalformedCertificate;
- break;
- }
- else { // Compare expected hostname with the DNS name
- if (Curl_cert_hostcheck(dns_name, hostname)
- == CURL_HOST_MATCH) {
- result = MatchFound;
- break;
- }
- }
- }
- }
- sk_GENERAL_NAME_pop_free(san_names, GENERAL_NAME_free);
-
- return result;
-}
-
-
-/**
-* Validates the server's identity by looking for the expected hostname in the
-* server's certificate. As described in RFC 6125, it first tries to find a match
-* in the Subject Alternative Name extension. If the extension is not present in
-* the certificate, it checks the Common Name instead.
-*
-* Returns MatchFound if a match was found.
-* Returns MatchNotFound if no matches were found.
-* Returns MalformedCertificate if any of the hostnames had a NUL character embedded in it.
-* Returns Error if there was an error.
-*/
-HostnameValidationResult validate_hostname(const char *hostname, const X509 *server_cert) {
- HostnameValidationResult result;
-
- if((hostname == NULL) || (server_cert == NULL))
- return Error;
-
- // First try the Subject Alternative Names extension
- result = matches_subject_alternative_name(hostname, server_cert);
- if (result == NoSANPresent) {
- // Extension was not found: try the Common Name
- result = matches_common_name(hostname, server_cert);
- }
-
- return result;
-}
diff --git a/sample/openssl_hostname_validation.h b/sample/openssl_hostname_validation.h
deleted file mode 100644
index 54aa1c4..0000000
--- a/sample/openssl_hostname_validation.h
+++ /dev/null
@@ -1,56 +0,0 @@
-/* Obtained from: https://github.com/iSECPartners/ssl-conservatory */
-
-/*
-Copyright (C) 2012, iSEC Partners.
-
-Permission is hereby granted, free of charge, to any person obtaining a copy of
-this software and associated documentation files (the "Software"), to deal in
-the Software without restriction, including without limitation the rights to
-use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
-of the Software, and to permit persons to whom the Software is furnished to do
-so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in all
-copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-SOFTWARE.
- */
-
-/*
- * Helper functions to perform basic hostname validation using OpenSSL.
- *
- * Please read "everything-you-wanted-to-know-about-openssl.pdf" before
- * attempting to use this code. This whitepaper describes how the code works,
- * how it should be used, and what its limitations are.
- *
- * Author: Alban Diquet
- * License: See LICENSE
- *
- */
-
-typedef enum {
- MatchFound,
- MatchNotFound,
- NoSANPresent,
- MalformedCertificate,
- Error
-} HostnameValidationResult;
-
-/**
-* Validates the server's identity by looking for the expected hostname in the
-* server's certificate. As described in RFC 6125, it first tries to find a match
-* in the Subject Alternative Name extension. If the extension is not present in
-* the certificate, it checks the Common Name instead.
-*
-* Returns MatchFound if a match was found.
-* Returns MatchNotFound if no matches were found.
-* Returns MalformedCertificate if any of the hostnames had a NUL character embedded in it.
-* Returns Error if there was an error.
-*/
-HostnameValidationResult validate_hostname(const char *hostname, const X509 *server_cert);
diff --git a/sample/signal-test.c b/sample/signal-test.c
deleted file mode 100644
index 1866835..0000000
--- a/sample/signal-test.c
+++ /dev/null
@@ -1,72 +0,0 @@
-/*
- * Compile with:
- * cc -I/usr/local/include -o signal-test \
- * signal-test.c -L/usr/local/lib -levent
- */
-
-#include <sys/types.h>
-
-#include <event2/event-config.h>
-
-#include <sys/stat.h>
-#ifndef _WIN32
-#include <sys/queue.h>
-#include <unistd.h>
-#include <sys/time.h>
-#else
-#include <winsock2.h>
-#include <windows.h>
-#endif
-#include <signal.h>
-#include <fcntl.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-#include <errno.h>
-
-#include <event2/event.h>
-
-int called = 0;
-
-static void
-signal_cb(evutil_socket_t fd, short event, void *arg)
-{
- struct event *signal = arg;
-
- printf("signal_cb: got signal %d\n", event_get_signal(signal));
-
- if (called >= 2)
- event_del(signal);
-
- called++;
-}
-
-int
-main(int argc, char **argv)
-{
- struct event *signal_int;
- struct event_base* base;
-#ifdef _WIN32
- WORD wVersionRequested;
- WSADATA wsaData;
-
- wVersionRequested = MAKEWORD(2, 2);
-
- (void) WSAStartup(wVersionRequested, &wsaData);
-#endif
-
- /* Initalize the event library */
- base = event_base_new();
-
- /* Initalize one event */
- signal_int = evsignal_new(base, SIGINT, signal_cb, event_self_cbarg());
-
- event_add(signal_int, NULL);
-
- event_base_dispatch(base);
- event_free(signal_int);
- event_base_free(base);
-
- return (0);
-}
-
diff --git a/sample/time-test.c b/sample/time-test.c
deleted file mode 100644
index c94c18a..0000000
--- a/sample/time-test.c
+++ /dev/null
@@ -1,107 +0,0 @@
-/*
- * XXX This sample code was once meant to show how to use the basic Libevent
- * interfaces, but it never worked on non-Unix platforms, and some of the
- * interfaces have changed since it was first written. It should probably
- * be removed or replaced with something better.
- *
- * Compile with:
- * cc -I/usr/local/include -o time-test time-test.c -L/usr/local/lib -levent
- */
-
-#include <sys/types.h>
-
-#include <event2/event-config.h>
-
-#include <sys/stat.h>
-#ifndef _WIN32
-#include <sys/queue.h>
-#include <unistd.h>
-#endif
-#include <time.h>
-#ifdef EVENT__HAVE_SYS_TIME_H
-#include <sys/time.h>
-#endif
-#include <fcntl.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-#include <errno.h>
-
-#include <event2/event.h>
-#include <event2/event_struct.h>
-#include <event2/util.h>
-
-#ifdef _WIN32
-#include <winsock2.h>
-#endif
-
-struct timeval lasttime;
-
-int event_is_persistent;
-
-static void
-timeout_cb(evutil_socket_t fd, short event, void *arg)
-{
- struct timeval newtime, difference;
- struct event *timeout = arg;
- double elapsed;
-
- evutil_gettimeofday(&newtime, NULL);
- evutil_timersub(&newtime, &lasttime, &difference);
- elapsed = difference.tv_sec +
- (difference.tv_usec / 1.0e6);
-
- printf("timeout_cb called at %d: %.3f seconds elapsed.\n",
- (int)newtime.tv_sec, elapsed);
- lasttime = newtime;
-
- if (! event_is_persistent) {
- struct timeval tv;
- evutil_timerclear(&tv);
- tv.tv_sec = 2;
- event_add(timeout, &tv);
- }
-}
-
-int
-main(int argc, char **argv)
-{
- struct event timeout;
- struct timeval tv;
- struct event_base *base;
- int flags;
-
-#ifdef _WIN32
- WORD wVersionRequested;
- WSADATA wsaData;
-
- wVersionRequested = MAKEWORD(2, 2);
-
- (void)WSAStartup(wVersionRequested, &wsaData);
-#endif
-
- if (argc == 2 && !strcmp(argv[1], "-p")) {
- event_is_persistent = 1;
- flags = EV_PERSIST;
- } else {
- event_is_persistent = 0;
- flags = 0;
- }
-
- /* Initalize the event library */
- base = event_base_new();
-
- /* Initalize one event */
- event_assign(&timeout, base, -1, flags, timeout_cb, (void*) &timeout);
-
- evutil_timerclear(&tv);
- tv.tv_sec = 2;
- event_add(&timeout, &tv);
-
- evutil_gettimeofday(&lasttime, NULL);
-
- event_base_dispatch(base);
-
- return (0);
-}
-