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 negotiation\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
);