1ebfedea0SLionel Sambuc /* NOCW */
2ebfedea0SLionel Sambuc /* demos/bio/sconnect.c */
3ebfedea0SLionel Sambuc
4*0a6a1f1dSLionel Sambuc /*-
5*0a6a1f1dSLionel Sambuc * A minimal program to do SSL to a passed host and port.
6ebfedea0SLionel Sambuc * It is actually using non-blocking IO but in a very simple manner
7ebfedea0SLionel Sambuc * sconnect host:port - it does a 'GET / HTTP/1.0'
8ebfedea0SLionel Sambuc *
9ebfedea0SLionel Sambuc * cc -I../../include sconnect.c -L../.. -lssl -lcrypto
10ebfedea0SLionel Sambuc */
11ebfedea0SLionel Sambuc #include <stdio.h>
12ebfedea0SLionel Sambuc #include <stdlib.h>
13ebfedea0SLionel Sambuc #include <unistd.h>
14ebfedea0SLionel Sambuc #include <openssl/err.h>
15ebfedea0SLionel Sambuc #include <openssl/ssl.h>
16ebfedea0SLionel Sambuc
17ebfedea0SLionel Sambuc extern int errno;
18ebfedea0SLionel Sambuc
main(argc,argv)19ebfedea0SLionel Sambuc int main(argc, argv)
20ebfedea0SLionel Sambuc int argc;
21ebfedea0SLionel Sambuc char *argv[];
22ebfedea0SLionel Sambuc {
23ebfedea0SLionel Sambuc char *host;
24ebfedea0SLionel Sambuc BIO *out;
25ebfedea0SLionel Sambuc char buf[1024 * 10], *p;
26ebfedea0SLionel Sambuc SSL_CTX *ssl_ctx = NULL;
27ebfedea0SLionel Sambuc SSL *ssl;
28ebfedea0SLionel Sambuc BIO *ssl_bio;
29ebfedea0SLionel Sambuc int i, len, off, ret = 1;
30ebfedea0SLionel Sambuc
31ebfedea0SLionel Sambuc if (argc <= 1)
32ebfedea0SLionel Sambuc host = "localhost:4433";
33ebfedea0SLionel Sambuc else
34ebfedea0SLionel Sambuc host = argv[1];
35ebfedea0SLionel Sambuc
36ebfedea0SLionel Sambuc #ifdef WATT32
37ebfedea0SLionel Sambuc dbug_init();
38ebfedea0SLionel Sambuc sock_init();
39ebfedea0SLionel Sambuc #endif
40ebfedea0SLionel Sambuc
41ebfedea0SLionel Sambuc /* Lets get nice error messages */
42ebfedea0SLionel Sambuc SSL_load_error_strings();
43ebfedea0SLionel Sambuc
44ebfedea0SLionel Sambuc /* Setup all the global SSL stuff */
45ebfedea0SLionel Sambuc OpenSSL_add_ssl_algorithms();
46ebfedea0SLionel Sambuc ssl_ctx = SSL_CTX_new(SSLv23_client_method());
47ebfedea0SLionel Sambuc
48ebfedea0SLionel Sambuc /* Lets make a SSL structure */
49ebfedea0SLionel Sambuc ssl = SSL_new(ssl_ctx);
50ebfedea0SLionel Sambuc SSL_set_connect_state(ssl);
51ebfedea0SLionel Sambuc
52ebfedea0SLionel Sambuc /* Use it inside an SSL BIO */
53ebfedea0SLionel Sambuc ssl_bio = BIO_new(BIO_f_ssl());
54ebfedea0SLionel Sambuc BIO_set_ssl(ssl_bio, ssl, BIO_CLOSE);
55ebfedea0SLionel Sambuc
56ebfedea0SLionel Sambuc /* Lets use a connect BIO under the SSL BIO */
57ebfedea0SLionel Sambuc out = BIO_new(BIO_s_connect());
58ebfedea0SLionel Sambuc BIO_set_conn_hostname(out, host);
59ebfedea0SLionel Sambuc BIO_set_nbio(out, 1);
60ebfedea0SLionel Sambuc out = BIO_push(ssl_bio, out);
61ebfedea0SLionel Sambuc
62ebfedea0SLionel Sambuc p = "GET / HTTP/1.0\r\n\r\n";
63ebfedea0SLionel Sambuc len = strlen(p);
64ebfedea0SLionel Sambuc
65ebfedea0SLionel Sambuc off = 0;
66*0a6a1f1dSLionel Sambuc for (;;) {
67ebfedea0SLionel Sambuc i = BIO_write(out, &(p[off]), len);
68*0a6a1f1dSLionel Sambuc if (i <= 0) {
69*0a6a1f1dSLionel Sambuc if (BIO_should_retry(out)) {
70ebfedea0SLionel Sambuc fprintf(stderr, "write DELAY\n");
71ebfedea0SLionel Sambuc sleep(1);
72ebfedea0SLionel Sambuc continue;
73*0a6a1f1dSLionel Sambuc } else {
74ebfedea0SLionel Sambuc goto err;
75ebfedea0SLionel Sambuc }
76ebfedea0SLionel Sambuc }
77ebfedea0SLionel Sambuc off += i;
78ebfedea0SLionel Sambuc len -= i;
79*0a6a1f1dSLionel Sambuc if (len <= 0)
80*0a6a1f1dSLionel Sambuc break;
81ebfedea0SLionel Sambuc }
82ebfedea0SLionel Sambuc
83*0a6a1f1dSLionel Sambuc for (;;) {
84ebfedea0SLionel Sambuc i = BIO_read(out, buf, sizeof(buf));
85*0a6a1f1dSLionel Sambuc if (i == 0)
86*0a6a1f1dSLionel Sambuc break;
87*0a6a1f1dSLionel Sambuc if (i < 0) {
88*0a6a1f1dSLionel Sambuc if (BIO_should_retry(out)) {
89ebfedea0SLionel Sambuc fprintf(stderr, "read DELAY\n");
90ebfedea0SLionel Sambuc sleep(1);
91ebfedea0SLionel Sambuc continue;
92ebfedea0SLionel Sambuc }
93ebfedea0SLionel Sambuc goto err;
94ebfedea0SLionel Sambuc }
95ebfedea0SLionel Sambuc fwrite(buf, 1, i, stdout);
96ebfedea0SLionel Sambuc }
97ebfedea0SLionel Sambuc
98ebfedea0SLionel Sambuc ret = 1;
99ebfedea0SLionel Sambuc
100*0a6a1f1dSLionel Sambuc if (0) {
101ebfedea0SLionel Sambuc err:
102*0a6a1f1dSLionel Sambuc if (ERR_peek_error() == 0) { /* system call error */
103ebfedea0SLionel Sambuc fprintf(stderr, "errno=%d ", errno);
104ebfedea0SLionel Sambuc perror("error");
105*0a6a1f1dSLionel Sambuc } else
106ebfedea0SLionel Sambuc ERR_print_errors_fp(stderr);
107ebfedea0SLionel Sambuc }
108ebfedea0SLionel Sambuc BIO_free_all(out);
109*0a6a1f1dSLionel Sambuc if (ssl_ctx != NULL)
110*0a6a1f1dSLionel Sambuc SSL_CTX_free(ssl_ctx);
111ebfedea0SLionel Sambuc exit(!ret);
112ebfedea0SLionel Sambuc return (ret);
113ebfedea0SLionel Sambuc }
114