/[cvs]/eggdrop1.9/testcode/sslmode.c
ViewVC logotype

Contents of /eggdrop1.9/testcode/sslmode.c

Parent Directory Parent Directory | Revision Log Revision Log | View Revision Graph Revision Graph


Revision 1.2 - (show annotations) (download) (as text)
Thu Jan 10 17:20:55 2002 UTC (17 years, 10 months ago) by stdarg
Branch: MAIN
Changes since 1.1: +1 -1 lines
File MIME type: text/x-chdr
Found the probem with truncated output, I think.

1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <string.h>
4 #include <unistd.h>
5 #include <openssl/ssl.h>
6
7 #include "sockbuf.h"
8
9 typedef struct {
10 BIO *rbio, *wbio;
11 SSL *ssl;
12 int negotiating;
13 sockbuf_iobuf_t old;
14 } sslmode_t;
15
16 static SSL_CTX *global_ctx;
17 static SSL_METHOD *global_method;
18
19 static int rand_offer(sslmode_t *sslinfo, int idx, int level)
20 {
21 char buf[10];
22
23 if (rand() & 1) sslinfo->negotiating = 'S';
24 else sslinfo->negotiating = 'C';
25 buf[0] = sslinfo->negotiating;
26 sockbuf_write_filter(idx, level, buf, 1);
27 }
28
29 static int handle_negotiation(int idx, int level, unsigned char *data, int len, sslmode_t *sslinfo)
30 {
31 char buf[4096];
32 int them, r, i, buflen;
33
34 data[len] = 0;
35 printf("negotiating: %c, %d, %d, %s\n", sslinfo->negotiating, idx, len, data);
36 if (sslinfo->negotiating == 'c') {
37 BIO_write(sslinfo->rbio, data, len);
38 r = SSL_connect(sslinfo->ssl);
39 if (r > 0) {
40 sslinfo->negotiating = 0;
41 return(0);
42 }
43 }
44 else if (sslinfo->negotiating == 's') {
45 BIO_write(sslinfo->rbio, data, len);
46 r = SSL_accept(sslinfo->ssl);
47 if (r > 0) {
48 sslinfo->negotiating = 0;
49 return(0);
50 }
51 }
52 else {
53 r = 0;
54 for (i = 0; i < len; i++) {
55 them = data[i];
56 if (them == sslinfo->negotiating) {
57 rand_offer(sslinfo, idx, level);
58 }
59 else {
60 r = 1;
61 break;
62 }
63 }
64 if (!r) return(1);
65 i++;
66 if (i < len) BIO_write(sslinfo->rbio, data+i, len-i);
67 if (them == 'S') {
68 r = SSL_connect(sslinfo->ssl);
69 if (r > 0) sslinfo->negotiating = 0;
70 else sslinfo->negotiating = 'c';
71 }
72 else {
73 r = SSL_accept(sslinfo->ssl);
74 if (r > 0) sslinfo->negotiating = 0;
75 else sslinfo->negotiating = 's';
76 }
77 }
78 /* Check for new output bytes (like for renegotiation). */
79 while ((buflen = BIO_read(sslinfo->wbio, buf, sizeof(buf))) > 0) {
80 sockbuf_write_filter(idx, level, buf, buflen);
81 }
82 return(sslinfo->negotiating);
83 }
84
85 static int sslmode_read(int idx, int event, int level, sockbuf_iobuf_t *new_data, sslmode_t *sslinfo)
86 {
87 sockbuf_iobuf_t my_iobuf;
88 char buf[4096];
89 int len;
90
91 /*
92 for (len = 0; len < new_data->len; len++) {
93 printf("%d ", new_data->data[len]);
94 }
95 printf("\n");
96 len = 0;
97 */
98 if (sslinfo->negotiating) {
99 if (handle_negotiation(idx, level, new_data->data, new_data->len, sslinfo)) return(0);
100 /* If it's done, fall through to check excess data. */
101 }
102 else {
103 /* Add this data to the ssl's input bio. */
104 BIO_write(sslinfo->rbio, new_data->data, new_data->len);
105 }
106
107 my_iobuf.data = buf;
108 my_iobuf.max = sizeof(buf);
109 while ((len = SSL_read(sslinfo->ssl, buf, sizeof(buf))) > 0) {
110 my_iobuf.len = len;
111 sockbuf_filter(idx, event, level, &my_iobuf);
112 }
113
114 /* Check if old data can be written now. */
115 if (sslinfo->old.len) {
116 len = SSL_write(sslinfo->ssl, sslinfo->old.data, sslinfo->old.len);
117 if (len > 0) {
118 printf("Wrote %d/%d bytes of queued data\n", len, sslinfo->old.len);
119 free(sslinfo->old.data);
120 memset(&sslinfo->old, 0, sizeof(sslinfo->old));
121 }
122 else {
123 //printf("Error sending queued data\n");
124 ERR_print_errors_fp(stderr);
125 }
126 }
127
128 /* Check for new output bytes (like for renegotiation). */
129 while ((len = BIO_read(sslinfo->wbio, buf, sizeof(buf))) > 0) {
130 sockbuf_write_filter(idx, level, buf, len);
131 }
132
133 return(0);
134 }
135
136 static int sslmode_eof_and_err(int idx, int event, int level, void *ignore, sslmode_t *sslinfo)
137 {
138 sockbuf_filter(idx, event, level, ignore);
139 return(0);
140 }
141
142 static int sslmode_write(int idx, int event, int level, sockbuf_iobuf_t *data, sslmode_t *sslinfo)
143 {
144 char buf[4096];
145 int r = -1;
146
147 if (!sslinfo->negotiating) r = SSL_write(sslinfo->ssl, data->data, data->len);
148 if (r < data->len) {
149 /* Save the data for later. */
150 /* Maybe the connection isn't negotiated yet? */
151 //printf("Write error, saving\n");
152 //ERR_print_errors_fp(stderr);
153 if (r < 0) r = 0;
154 sslinfo->old.data = (unsigned char *)realloc(sslinfo->old.data, sslinfo->old.len + data->len - r);
155 memcpy(sslinfo->old.data+sslinfo->old.len, data->data+r, data->len-r);
156 sslinfo->old.len += (data->len - r);
157 sslinfo->old.max = sslinfo->old.len;
158 }
159
160 /* Pass on any output that was produced. */
161 if (!sslinfo->negotiating) while ((r = BIO_read(sslinfo->wbio, buf, sizeof(buf))) > 0) {
162 sockbuf_write_filter(idx, level, buf, r);
163 }
164 return(0);
165 }
166
167 static sockbuf_event_t sslmode_filter = {
168 (Function) 5,
169 (Function) "ssl-mode",
170 sslmode_read,
171 NULL,
172 sslmode_eof_and_err,
173 sslmode_eof_and_err,
174 sslmode_write
175 };
176
177 int sslmode_on(int idx)
178 {
179 sslmode_t *sslinfo;
180 int i;
181 char buf[4096];
182
183 sslinfo = (sslmode_t *)calloc(sizeof(*sslinfo), 1);
184 sslinfo->ssl = SSL_new(global_ctx);
185 sslinfo->rbio = BIO_new(BIO_s_mem());
186 sslinfo->wbio = BIO_new(BIO_s_mem());
187 SSL_set_bio(sslinfo->ssl, sslinfo->rbio, sslinfo->wbio);
188 /* We have to randomly decide who is server and who is client. */
189 rand_offer(sslinfo, idx, -1);
190 sockbuf_attach_filter(idx, sslmode_filter, sslinfo);
191 return(0);
192 }
193
194 int sslmode_off(int idx)
195 {
196 return(0);
197 }
198
199 static unsigned char dh512_p[] = {
200 0xDA,0x58,0x3C,0x16,0xD9,0x85,0x22,0x89,0xD0,0xE4,0xAF,0x75,
201 0x6F,0x4C,0xCA,0x92,0xDD,0x4B,0xE5,0x33,0xB8,0x04,0xFB,0x0F,
202 0xED,0x94,0xEF,0x9C,0x8A,0x44,0x03,0xED,0x57,0x46,0x50,0xD3,
203 0x69,0x99,0xDB,0x29,0xD7,0x76,0x27,0x6B,0xA2,0xD3,0xD4,0x12,
204 0xE2,0x18,0xF4,0xDD,0x1E,0x08,0x4C,0xF6,0xD8,0x00,0x3E,0x7C,
205 0x47,0x74,0xE8,0x33
206 };
207 static unsigned char dh512_g[] = {
208 0x02
209 };
210 static DH *get_dh512(void) {
211 DH *dh=NULL;
212
213 if ((dh=DH_new()) == NULL) return(NULL);
214 dh->p=BN_bin2bn(dh512_p,sizeof(dh512_p),NULL);
215 dh->g=BN_bin2bn(dh512_g,sizeof(dh512_g),NULL);
216 if ((dh->p == NULL) || (dh->g == NULL))
217 return(NULL);
218 return(dh);
219 }
220
221 int sslmode_init()
222 {
223 DH *dh = NULL;
224
225 SSL_load_error_strings();
226 SSL_library_init();
227 global_method = SSLv23_method();
228 //global_method = SSLv23_client_method();
229 global_ctx = SSL_CTX_new(global_method);
230 dh = get_dh512();
231 SSL_CTX_set_tmp_dh(global_ctx, dh);
232 DH_free(dh);
233 if (SSL_CTX_use_certificate_file(global_ctx, "private/cert.pem", SSL_FILETYPE_PEM) < 1) {
234 printf("Can't load certificate file\n");
235 ERR_print_errors_fp(stderr);
236 }
237 if (SSL_CTX_use_PrivateKey_file(global_ctx, "private/key.pem", SSL_FILETYPE_PEM) < 1) {
238 printf("Can't load private key file\n");
239 ERR_print_errors_fp(stderr);
240 }
241 SSL_CTX_set_verify(global_ctx, SSL_VERIFY_NONE, NULL);
242 return(0);
243 }

webmaster@eggheads.org
ViewVC Help
Powered by ViewVC 1.1.23