5 #include <libubox/usock.h>
6 #include <libubox/uloop.h>
7 #include "ustream-ssl.h"
9 static struct uloop_fd fd;
11 static struct ustream_fd stream, s_input;
12 static struct ustream_ssl ssl;
13 static const char *host, *port;
17 static void client_teardown(void)
19 if (s_input.fd.registered)
20 ustream_free(&s_input.stream);
22 ustream_free(&ssl.stream);
23 ustream_free(&stream.stream);
28 static void client_input_notify_read(struct ustream *s, int bytes)
33 buf = ustream_get_read_buf(s, &len);
34 ustream_write(&ssl.stream, buf, len, false);
35 ustream_consume(s, len);
38 static void client_ssl_notify_read(struct ustream *s, int bytes)
43 buf = ustream_get_read_buf(s, &len);
44 fwrite(buf, len, 1, stdout);
46 ustream_consume(s, len);
49 static void client_ssl_notify_write(struct ustream *s, int bytes)
51 fprintf(stderr, "Wrote %d bytes, pending %d\n", bytes, s->w.data_bytes);
54 static void client_notify_connected(struct ustream_ssl *ssl)
56 fprintf(stderr, "SSL connection established (CN verified: %d)\n", ssl->valid_cn);
57 s_input.stream.notify_read = client_input_notify_read;
58 ustream_fd_init(&s_input, 0);
61 static void client_notify_error(struct ustream_ssl *ssl, int error, const char *str)
63 fprintf(stderr, "SSL connection error(%d): %s\n", error, str);
67 static void client_notify_verify_error(struct ustream_ssl *ssl, int error, const char *str)
69 fprintf(stderr, "WARNING: SSL certificate error(%d): %s\n", error, str);
72 static void client_notify_state(struct ustream *us)
74 if (!us->write_error && !us->eof)
77 fprintf(stderr, "Connection closed\n");
81 static void example_connect_ssl(int fd)
83 fprintf(stderr, "Starting SSL negnotiation\n");
85 ssl.notify_error = client_notify_error;
86 ssl.notify_verify_error = client_notify_verify_error;
87 ssl.notify_connected = client_notify_connected;
88 ssl.stream.notify_read = client_ssl_notify_read;
89 ssl.stream.notify_write = client_ssl_notify_write;
90 ssl.stream.notify_state = client_notify_state;
92 ustream_fd_init(&stream, fd);
93 ustream_ssl_init(&ssl, &stream.stream, ctx, false);
94 ustream_ssl_set_peer_cn(&ssl, host);
97 static void example_connect_cb(struct uloop_fd *f, unsigned int events)
99 if (fd.eof || fd.error) {
100 fprintf(stderr, "Connection failed\n");
105 fprintf(stderr, "Connection established\n");
106 uloop_fd_delete(&fd);
107 example_connect_ssl(fd.fd);
110 static void connect_client(void)
112 fd.fd = usock(USOCK_TCP | USOCK_NONBLOCK, host, port);
113 fd.cb = example_connect_cb;
114 uloop_fd_add(&fd, ULOOP_WRITE | ULOOP_EDGE_TRIGGER);
117 static int usage(const char *progname)
120 "Usage: %s [options] <hostname> <port>\n"
122 " -c <cert>: Load CA certificates from file <cert>\n"
127 int main(int argc, char **argv)
129 const char *progname = argv[0];
132 ctx = ustream_ssl_context_new(false);
134 while ((ch = getopt(argc, argv, "c:")) != -1) {
137 ustream_ssl_context_add_ca_crt_file(ctx, optarg);
140 return usage(progname);
148 return usage(progname);