]> git.sur5r.net Git - freertos/blob - FreeRTOS-Plus/CyaSSL/examples/echoserver/echoserver.c
Add FreeRTOS-Plus directory.
[freertos] / FreeRTOS-Plus / CyaSSL / examples / echoserver / echoserver.c
1 /* echoserver.c
2  *
3  * Copyright (C) 2006-2012 Sawtooth Consulting Ltd.
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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
20  */
21
22 #ifdef HAVE_CONFIG_H
23     #include <config.h>
24 #endif
25
26 #include <cyassl/ssl.h>
27 #include <cyassl/test.h>
28
29 #ifndef NO_MAIN_DRIVER
30     #define ECHO_OUT
31 #endif
32
33
34 #ifdef SESSION_STATS
35     CYASSL_API void PrintSessionStats(void);
36 #endif
37
38
39 static void SignalReady(void* args)
40 {
41 #if defined(_POSIX_THREADS) && defined(NO_MAIN_DRIVER)
42     /* signal ready to tcp_accept */
43     func_args* server_args = (func_args*)args;
44     tcp_ready* ready = server_args->signal;
45     pthread_mutex_lock(&ready->mutex);
46     ready->ready = 1;
47     pthread_cond_signal(&ready->cond);
48     pthread_mutex_unlock(&ready->mutex);
49 #endif
50 }
51
52
53 THREAD_RETURN CYASSL_THREAD echoserver_test(void* args)
54 {
55     SOCKET_T       sockfd = 0;
56     CYASSL_METHOD* method = 0;
57     CYASSL_CTX*    ctx    = 0;
58
59     int    outCreated = 0;
60     int    shutdown = 0;
61     int    argc = ((func_args*)args)->argc;
62     char** argv = ((func_args*)args)->argv;
63
64 #ifdef ECHO_OUT
65     FILE* fout = stdout;
66     if (argc >= 2) {
67         fout = fopen(argv[1], "w");
68         outCreated = 1;
69     }
70     if (!fout) err_sys("can't open output file");
71 #endif
72
73     ((func_args*)args)->return_code = -1; /* error state */
74
75     tcp_listen(&sockfd);
76
77 #if defined(CYASSL_DTLS)
78     method  = CyaDTLSv1_server_method();
79 #elif  !defined(NO_TLS)
80     method = CyaSSLv23_server_method();
81 #else
82     method = CyaSSLv3_server_method();
83 #endif
84     ctx    = CyaSSL_CTX_new(method);
85     /* CyaSSL_CTX_set_session_cache_mode(ctx, SSL_SESS_CACHE_OFF); */
86
87 #ifdef OPENSSL_EXTRA
88     CyaSSL_CTX_set_default_passwd_cb(ctx, PasswordCallBack);
89 #endif
90
91 #ifndef NO_FILESYSTEM
92     #ifdef HAVE_NTRU
93         /* ntru */
94         if (CyaSSL_CTX_use_certificate_file(ctx, ntruCert, SSL_FILETYPE_PEM)
95                 != SSL_SUCCESS)
96             err_sys("can't load ntru cert file, "
97                     "Please run from CyaSSL home dir");
98
99         if (CyaSSL_CTX_use_NTRUPrivateKey_file(ctx, ntruKey)
100                 != SSL_SUCCESS)
101             err_sys("can't load ntru key file, "
102                     "Please run from CyaSSL home dir");
103     #elif HAVE_ECC
104         /* ecc */
105         if (CyaSSL_CTX_use_certificate_file(ctx, eccCert, SSL_FILETYPE_PEM)
106                 != SSL_SUCCESS)
107             err_sys("can't load server cert file, "
108                     "Please run from CyaSSL home dir");
109
110         if (CyaSSL_CTX_use_PrivateKey_file(ctx, eccKey, SSL_FILETYPE_PEM)
111                 != SSL_SUCCESS)
112             err_sys("can't load server key file, "
113                     "Please run from CyaSSL home dir");
114     #else
115         /* normal */
116         if (CyaSSL_CTX_use_certificate_file(ctx, svrCert, SSL_FILETYPE_PEM)
117                 != SSL_SUCCESS)
118             err_sys("can't load server cert file, "
119                     "Please run from CyaSSL home dir");
120
121         if (CyaSSL_CTX_use_PrivateKey_file(ctx, svrKey, SSL_FILETYPE_PEM)
122                 != SSL_SUCCESS)
123             err_sys("can't load server key file, "
124                     "Please run from CyaSSL home dir");
125     #endif
126 #else
127     load_buffer(ctx, svrCert, CYASSL_CERT);
128     load_buffer(ctx, svrKey,  CYASSL_KEY);
129 #endif
130
131     SignalReady(args);
132
133     while (!shutdown) {
134         CYASSL* ssl = 0;
135         char    command[1024];
136         int     echoSz = 0;
137         int     clientfd;
138         int     firstRead = 1;
139         int     gotFirstG = 0;
140                 
141 #ifndef CYASSL_DTLS 
142         SOCKADDR_IN_T client;
143         socklen_t     client_len = sizeof(client);
144         clientfd = accept(sockfd, (struct sockaddr*)&client,
145                          (ACCEPT_THIRD_T)&client_len);
146 #else
147         clientfd = udp_read_connect(sockfd);
148 #endif
149         if (clientfd == -1) err_sys("tcp accept failed");
150
151         ssl = CyaSSL_new(ctx);
152         if (ssl == NULL) err_sys("SSL_new failed");
153         CyaSSL_set_fd(ssl, clientfd);
154         #if !defined(NO_FILESYSTEM) && defined(OPENSSL_EXTRA)
155             CyaSSL_SetTmpDH_file(ssl, dhParam, SSL_FILETYPE_PEM);
156         #else
157             SetDH(ssl);  /* will repick suites with DHE, higher than PSK */
158         #endif
159         if (CyaSSL_accept(ssl) != SSL_SUCCESS) {
160             printf("SSL_accept failed\n");
161             CyaSSL_free(ssl);
162             CloseSocket(clientfd);
163             continue;
164         }
165 #if defined(PEER_INFO)
166         showPeer(ssl);
167 #endif
168
169         while ( (echoSz = CyaSSL_read(ssl, command, sizeof(command))) > 0) {
170
171             if (firstRead == 1) {
172                 firstRead = 0;  /* browser may send 1 byte 'G' to start */
173                 if (echoSz == 1 && command[0] == 'G') {
174                     gotFirstG = 1;
175                     continue;
176                 }
177             }
178             else if (gotFirstG == 1 && strncmp(command, "ET /", 4) == 0) {
179                 strncpy(command, "GET", 4);
180                 /* fall through to normal GET */
181             }
182            
183             if ( strncmp(command, "quit", 4) == 0) {
184                 printf("client sent quit command: shutting down!\n");
185                 shutdown = 1;
186                 break;
187             }
188             if ( strncmp(command, "break", 5) == 0) {
189                 printf("client sent break command: closing session!\n");
190                 break;
191             }
192 #ifdef SESSION_STATS
193             if ( strncmp(command, "printstats", 10) == 0) {
194                 PrintSessionStats();
195                 break;
196             }
197 #endif
198             if ( strncmp(command, "GET", 3) == 0) {
199                 char type[]   = "HTTP/1.0 200 ok\r\nContent-type:"
200                                 " text/html\r\n\r\n";
201                 char header[] = "<html><body BGCOLOR=\"#ffffff\">\n<pre>\n";
202                 char body[]   = "greetings from CyaSSL\n";
203                 char footer[] = "</body></html>\r\n\r\n";
204             
205                 strncpy(command, type, sizeof(type));
206                 echoSz = sizeof(type) - 1;
207
208                 strncpy(&command[echoSz], header, sizeof(header));
209                 echoSz += sizeof(header) - 1;
210                 strncpy(&command[echoSz], body, sizeof(body));
211                 echoSz += sizeof(body) - 1;
212                 strncpy(&command[echoSz], footer, sizeof(footer));
213                 echoSz += sizeof(footer);
214
215                 if (CyaSSL_write(ssl, command, echoSz) != echoSz)
216                     err_sys("SSL_write failed");
217                 break;
218             }
219             command[echoSz] = 0;
220
221             #ifdef ECHO_OUT
222                 fputs(command, fout);
223             #endif
224
225             if (CyaSSL_write(ssl, command, echoSz) != echoSz)
226                 err_sys("SSL_write failed");
227         }
228 #ifndef CYASSL_DTLS
229         CyaSSL_shutdown(ssl);
230 #endif
231         CyaSSL_free(ssl);
232         CloseSocket(clientfd);
233 #ifdef CYASSL_DTLS
234         tcp_listen(&sockfd);
235         SignalReady(args);
236 #endif
237     }
238
239     CloseSocket(sockfd);
240     CyaSSL_CTX_free(ctx);
241
242 #ifdef ECHO_OUT
243     if (outCreated)
244         fclose(fout);
245 #endif
246
247     ((func_args*)args)->return_code = 0;
248     return 0;
249 }
250
251
252 /* so overall tests can pull in test function */
253 #ifndef NO_MAIN_DRIVER
254
255     int main(int argc, char** argv)
256     {
257         func_args args;
258
259         StartTCP();
260
261         args.argc = argc;
262         args.argv = argv;
263
264         CyaSSL_Init();
265 #ifdef DEBUG_CYASSL
266         CyaSSL_Debugging_ON();
267 #endif
268         if (CurrentDir("echoserver") || CurrentDir("build"))
269             ChangeDirBack(2);
270         echoserver_test(&args);
271         CyaSSL_Cleanup();
272
273         return args.return_code;
274     }
275
276 #endif /* NO_MAIN_DRIVER */
277
278
279