1 #include <stdio.h> 2 #include <stdlib.h> 3 #include <unistd.h> 4 5 #include <libubox/usock.h> 6 #include <libubox/uloop.h> 7 #include "ustream-ssl.h" 8 9 static struct uloop_fd fd; 10 11 static struct ustream_fd stream, s_input; 12 static struct ustream_ssl ssl; 13 static const char *host, *port; 14 15 static void *ctx; 16 17 static void client_teardown(void) 18 { 19 if (s_input.fd.registered) 20 ustream_free(&s_input.stream); 21 22 ustream_free(&ssl.stream); 23 ustream_free(&stream.stream); 24 close(stream.fd.fd); 25 uloop_end(); 26 } 27 28 static void client_input_notify_read(struct ustream *s, int bytes) 29 { 30 char *buf; 31 int len; 32 33 buf = ustream_get_read_buf(s, &len); 34 ustream_write(&ssl.stream, buf, len, false); 35 ustream_consume(s, len); 36 } 37 38 static void client_ssl_notify_read(struct ustream *s, int bytes) 39 { 40 char *buf; 41 int len; 42 43 buf = ustream_get_read_buf(s, &len); 44 fwrite(buf, len, 1, stdout); 45 fflush(stdout); 46 ustream_consume(s, len); 47 } 48 49 static void client_ssl_notify_write(struct ustream *s, int bytes) 50 { 51 fprintf(stderr, "Wrote %d bytes, pending %d\n", bytes, s->w.data_bytes); 52 } 53 54 static void client_notify_connected(struct ustream_ssl *ssl) 55 { 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); 59 } 60 61 static void client_notify_error(struct ustream_ssl *ssl, int error, const char *str) 62 { 63 fprintf(stderr, "SSL connection error(%d): %s\n", error, str); 64 client_teardown(); 65 } 66 67 static void client_notify_verify_error(struct ustream_ssl *ssl, int error, const char *str) 68 { 69 fprintf(stderr, "WARNING: SSL certificate error(%d): %s\n", error, str); 70 } 71 72 static void client_notify_state(struct ustream *us) 73 { 74 if (!us->write_error && !us->eof) 75 return; 76 77 fprintf(stderr, "Connection closed\n"); 78 client_teardown(); 79 } 80 81 static void example_connect_ssl(int fd) 82 { 83 fprintf(stderr, "Starting SSL negotiation\n"); 84 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; 91 92 ustream_fd_init(&stream, fd); 93 ustream_ssl_init(&ssl, &stream.stream, ctx, false); 94 ustream_ssl_set_peer_cn(&ssl, host); 95 } 96 97 static void example_connect_cb(struct uloop_fd *f, unsigned int events) 98 { 99 if (fd.eof || fd.error) { 100 fprintf(stderr, "Connection failed\n"); 101 uloop_end(); 102 return; 103 } 104 105 fprintf(stderr, "Connection established\n"); 106 uloop_fd_delete(&fd); 107 example_connect_ssl(fd.fd); 108 } 109 110 static void connect_client(void) 111 { 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); 115 } 116 117 static int usage(const char *progname) 118 { 119 fprintf(stderr, 120 "Usage: %s [options] <hostname> <port>\n" 121 "Options:\n" 122 " -c <cert>: Load CA certificates from file <cert>\n" 123 "\n", progname); 124 return 1; 125 } 126 127 int main(int argc, char **argv) 128 { 129 const char *progname = argv[0]; 130 int ch; 131 132 ctx = ustream_ssl_context_new(false); 133 134 while ((ch = getopt(argc, argv, "c:")) != -1) { 135 switch(ch) { 136 case 'c': 137 ustream_ssl_context_add_ca_crt_file(ctx, optarg); 138 break; 139 default: 140 return usage(progname); 141 } 142 } 143 144 argv += optind; 145 argc -= optind; 146 147 if (argc != 2) 148 return usage(progname); 149 150 uloop_init(); 151 host = argv[0]; 152 port = argv[1]; 153 connect_client(); 154 uloop_run(); 155 156 close(fd.fd); 157 uloop_done(); 158 return 0; 159 } 160
This page was automatically generated by LXR 0.3.1. • OpenWrt