]> git.sur5r.net Git - freertos/blob - FreeRTOS-Plus/Source/CyaSSL/IDE/MDK5-ARM/Projects/CyaSSL-Full/echoserver.c
Demo application related:
[freertos] / FreeRTOS-Plus / Source / CyaSSL / IDE / MDK5-ARM / Projects / CyaSSL-Full / echoserver.c
1 /* echoserver.c
2  *
3  * Copyright (C) 2006-2014 wolfSSL Inc.
4  *
5  * This file is part of CyaSSL.
6  *
7  * CyaSSL is free software; you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation; either version 2 of the License, or
10  * (at your option) any later version.
11  *
12  * CyaSSL is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program; if not, write to the Free Software
19  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
20  */
21
22 #ifdef HAVE_CONFIG_H
23     #include <config.h>
24 #endif
25
26 #include <cyassl/ctaocrypt/settings.h>
27
28 #if defined(CYASSL_MDK_ARM)
29         #include <stdio.h>
30         #include <string.h>
31
32         #if defined(CYASSL_MDK5)
33             #include "cmsis_os.h"
34             #include "rl_fs.h" 
35             #include "rl_net.h" 
36         #else
37             #include "rtl.h"
38         #endif
39
40         #include "cyassl_MDK_ARM.h"
41 #endif
42
43 #include <cyassl/ssl.h>
44 #include <cyassl/test.h>
45
46 #ifndef NO_MAIN_DRIVER
47     #define ECHO_OUT
48 #endif
49
50 #include "examples/echoserver/echoserver.h"
51
52
53 #ifdef SESSION_STATS
54     CYASSL_API void PrintSessionStats(void);
55 #endif
56
57 #define SVR_COMMAND_SIZE 256
58
59 static void SignalReady(void* args, word16 port)
60 {
61 #if defined(_POSIX_THREADS) && defined(NO_MAIN_DRIVER) && !defined(__MINGW32__)
62     /* signal ready to tcp_accept */
63     func_args* server_args = (func_args*)args;
64     tcp_ready* ready = server_args->signal;
65     pthread_mutex_lock(&ready->mutex);
66     ready->ready = 1;
67     ready->port = port;
68     pthread_cond_signal(&ready->cond);
69     pthread_mutex_unlock(&ready->mutex);
70 #endif
71     (void)args;
72     (void)port;
73 }
74
75
76 THREAD_RETURN CYASSL_THREAD echoserver_test(void* args)
77 {
78     SOCKET_T       sockfd = 0;
79     CYASSL_METHOD* method = 0;
80     CYASSL_CTX*    ctx    = 0;
81
82     int    doDTLS = 0;
83     int    doPSK = 0;
84     int    outCreated = 0;
85     int    shutDown = 0;
86     int    useAnyAddr = 0;
87     word16 port = yasslPort;
88     int    argc = ((func_args*)args)->argc;
89     char** argv = ((func_args*)args)->argv;
90
91 #ifdef ECHO_OUT
92     FILE* fout = stdout;
93     if (argc >= 2) {
94         fout = fopen(argv[1], "w");
95         outCreated = 1;
96     }
97     if (!fout) err_sys("can't open output file");
98 #endif
99     (void)outCreated;
100     (void)argc;
101     (void)argv;
102
103     ((func_args*)args)->return_code = -1; /* error state */
104
105 #ifdef CYASSL_DTLS
106     doDTLS  = 1;
107 #endif
108
109 #ifdef CYASSL_LEANPSK
110     doPSK = 1;
111 #endif
112
113 #if defined(NO_RSA) && !defined(HAVE_ECC)
114     doPSK = 1;
115 #endif
116
117     #if defined(NO_MAIN_DRIVER) && !defined(USE_WINDOWS_API) && \
118                       !defined(CYASSL_SNIFFER) && !defined(CYASSL_MDK_SHELL)
119         port = 0;
120     #endif
121     #if defined(USE_ANY_ADDR)
122         useAnyAddr = 1;
123     #endif
124     tcp_listen(&sockfd, &port, useAnyAddr, doDTLS);
125
126 #if defined(CYASSL_DTLS)
127     method  = CyaDTLSv1_server_method();
128 #elif  !defined(NO_TLS)
129     method = CyaSSLv23_server_method();
130 #else
131     method = CyaSSLv3_server_method();
132 #endif
133     ctx    = CyaSSL_CTX_new(method);
134     /* CyaSSL_CTX_set_session_cache_mode(ctx, SSL_SESS_CACHE_OFF); */
135
136 #if defined(OPENSSL_EXTRA) || defined(HAVE_WEBSERVER)
137     CyaSSL_CTX_set_default_passwd_cb(ctx, PasswordCallBack);
138 #endif
139
140 #ifndef NO_FILESYSTEM
141     if (doPSK == 0) {
142     #ifdef HAVE_NTRU
143         /* ntru */
144         if (CyaSSL_CTX_use_certificate_file(ctx, ntruCert, SSL_FILETYPE_PEM)
145                 != SSL_SUCCESS)
146             err_sys("can't load ntru cert file, "
147                     "Please run from CyaSSL home dir");
148
149         if (CyaSSL_CTX_use_NTRUPrivateKey_file(ctx, ntruKey)
150                 != SSL_SUCCESS)
151             err_sys("can't load ntru key file, "
152                     "Please run from CyaSSL home dir");
153     #elif defined(HAVE_ECC)
154         /* ecc */
155         if (CyaSSL_CTX_use_certificate_file(ctx, eccCert, SSL_FILETYPE_PEM)
156                 != SSL_SUCCESS)
157             err_sys("can't load server cert file, "
158                     "Please run from CyaSSL home dir");
159
160         if (CyaSSL_CTX_use_PrivateKey_file(ctx, eccKey, SSL_FILETYPE_PEM)
161                 != SSL_SUCCESS)
162             err_sys("can't load server key file, "
163                     "Please run from CyaSSL home dir");
164     #elif defined(NO_CERTS)
165         /* do nothing, just don't load cert files */
166     #else
167         /* normal */
168         if (CyaSSL_CTX_use_certificate_file(ctx, svrCert, SSL_FILETYPE_PEM)
169                 != SSL_SUCCESS)
170             err_sys("can't load server cert file, "
171                     "Please run from CyaSSL home dir");
172
173         if (CyaSSL_CTX_use_PrivateKey_file(ctx, svrKey, SSL_FILETYPE_PEM)
174                 != SSL_SUCCESS)
175             err_sys("can't load server key file, "
176                     "Please run from CyaSSL home dir");
177     #endif
178     } /* doPSK */
179 #elif !defined(NO_CERTS)
180     if (!doPSK) {
181         load_buffer(ctx, svrCert, CYASSL_CERT);
182         load_buffer(ctx, svrKey,  CYASSL_KEY);
183     }
184 #endif
185
186 #if defined(CYASSL_SNIFFER) && !defined(HAVE_NTRU) && !defined(HAVE_ECC)
187     /* don't use EDH, can't sniff tmp keys */
188     CyaSSL_CTX_set_cipher_list(ctx, "AES256-SHA");
189 #endif
190
191     if (doPSK) {
192 #ifndef NO_PSK
193         const char *defaultCipherList;
194
195         CyaSSL_CTX_set_psk_server_callback(ctx, my_psk_server_cb);
196         CyaSSL_CTX_use_psk_identity_hint(ctx, "cyassl server");
197         #ifdef HAVE_NULL_CIPHER
198             defaultCipherList = "PSK-NULL-SHA256";
199         #else
200             defaultCipherList = "PSK-AES128-CBC-SHA256";
201         #endif
202         if (CyaSSL_CTX_set_cipher_list(ctx, defaultCipherList) != SSL_SUCCESS)
203             err_sys("server can't set cipher list 2");
204 #endif
205     }
206
207     SignalReady(args, port);
208
209     while (!shutDown) {
210         CYASSL* ssl = 0;
211         char    command[SVR_COMMAND_SIZE+1];
212         int     echoSz = 0;
213         int     clientfd;
214         int     firstRead = 1;
215         int     gotFirstG = 0;
216                 
217 #ifndef CYASSL_DTLS 
218         SOCKADDR_IN_T client;
219         socklen_t     client_len = sizeof(client);
220         clientfd = accept(sockfd, (struct sockaddr*)&client,
221                          (ACCEPT_THIRD_T)&client_len);
222 #else
223         clientfd = udp_read_connect(sockfd);
224 #endif
225         if (clientfd == -1) err_sys("tcp accept failed");
226
227         ssl = CyaSSL_new(ctx);
228         if (ssl == NULL) err_sys("SSL_new failed");
229         CyaSSL_set_fd(ssl, clientfd);
230         #if !defined(NO_FILESYSTEM) && defined(OPENSSL_EXTRA)
231             CyaSSL_SetTmpDH_file(ssl, dhParam, SSL_FILETYPE_PEM);
232         #elif !defined(NO_CERTS)
233             SetDH(ssl);  /* will repick suites with DHE, higher than PSK */
234         #endif
235         if (CyaSSL_accept(ssl) != SSL_SUCCESS) {
236             printf("SSL_accept failed\n");
237             CyaSSL_free(ssl);
238             CloseSocket(clientfd);
239             continue;
240         }
241 #if defined(PEER_INFO)
242         showPeer(ssl);
243 #endif
244
245         while ( (echoSz = CyaSSL_read(ssl, command, sizeof(command)-1)) > 0) {
246
247             if (firstRead == 1) {
248                 firstRead = 0;  /* browser may send 1 byte 'G' to start */
249                 if (echoSz == 1 && command[0] == 'G') {
250                     gotFirstG = 1;
251                     continue;
252                 }
253             }
254             else if (gotFirstG == 1 && strncmp(command, "ET /", 4) == 0) {
255                 strncpy(command, "GET", 4);
256                 /* fall through to normal GET */
257             }
258            
259             if ( strncmp(command, "quit", 4) == 0) {
260                 printf("client sent quit command: shutting down!\n");
261                 shutDown = 1;
262                 break;
263             }
264             if ( strncmp(command, "break", 5) == 0) {
265                 printf("client sent break command: closing session!\n");
266                 break;
267             }
268 #ifdef SESSION_STATS
269             if ( strncmp(command, "printstats", 10) == 0) {
270                 PrintSessionStats();
271                 break;
272             }
273 #endif
274             if ( strncmp(command, "GET", 3) == 0) {
275                 char type[]   = "HTTP/1.0 200 ok\r\nContent-type:"
276                                 " text/html\r\n\r\n";
277                 char header[] = "<html><body BGCOLOR=\"#ffffff\">\n<pre>\n";
278                 char body[]   = "greetings from CyaSSL\n";
279                 char footer[] = "</body></html>\r\n\r\n";
280             
281                 strncpy(command, type, sizeof(type));
282                 echoSz = sizeof(type) - 1;
283
284                 strncpy(&command[echoSz], header, sizeof(header));
285                 echoSz += (int)sizeof(header) - 1;
286                 strncpy(&command[echoSz], body, sizeof(body));
287                 echoSz += (int)sizeof(body) - 1;
288                 strncpy(&command[echoSz], footer, sizeof(footer));
289                 echoSz += (int)sizeof(footer);
290
291                 if (CyaSSL_write(ssl, command, echoSz) != echoSz)
292                     err_sys("SSL_write failed");
293                 break;
294             }
295             command[echoSz] = 0;
296
297             #ifdef ECHO_OUT
298                 fputs(command, fout);
299             #endif
300
301             if (CyaSSL_write(ssl, command, echoSz) != echoSz)
302                 err_sys("SSL_write failed");
303         }
304 #ifndef CYASSL_DTLS
305         CyaSSL_shutdown(ssl);
306 #endif
307         CyaSSL_free(ssl);
308         CloseSocket(clientfd);
309 #ifdef CYASSL_DTLS
310         tcp_listen(&sockfd, &port, useAnyAddr, doDTLS);
311         SignalReady(args, port);
312 #endif
313     }
314
315     CloseSocket(sockfd);
316     CyaSSL_CTX_free(ctx);
317
318 #ifdef ECHO_OUT
319     if (outCreated)
320         fclose(fout);
321 #endif
322
323     ((func_args*)args)->return_code = 0;
324     return 0;
325 }
326
327
328 /* so overall tests can pull in test function */
329 #ifndef NO_MAIN_DRIVER
330
331     int main(int argc, char** argv)
332     {
333         func_args args;
334
335 #ifdef HAVE_CAVIUM
336         int ret = OpenNitroxDevice(CAVIUM_DIRECT, CAVIUM_DEV_ID);
337         if (ret != 0)
338             err_sys("Cavium OpenNitroxDevice failed");
339 #endif /* HAVE_CAVIUM */
340
341         StartTCP();
342
343         args.argc = argc;
344         args.argv = argv;
345
346         CyaSSL_Init();
347 #if defined(DEBUG_CYASSL) && !defined(CYASSL_MDK_SHELL)
348         CyaSSL_Debugging_ON();
349 #endif
350         if (CurrentDir("echoserver"))
351             ChangeDirBack(2);
352         else if (CurrentDir("Debug") || CurrentDir("Release"))
353             ChangeDirBack(3);
354         echoserver_test(&args);
355         CyaSSL_Cleanup();
356
357 #ifdef HAVE_CAVIUM
358         CspShutdown(CAVIUM_DEV_ID);
359 #endif
360         return args.return_code;
361     }
362
363         
364 #endif /* NO_MAIN_DRIVER */
365
366
367
368