1 | |
2 | |
3 | #ifdef HAVE_CONFIG_H1 |
4 | #include <config.h> |
5 | #endif |
6 | |
7 | #include <stdio.h> |
8 | #include <stdlib.h> |
9 | #include <errno(*__errno_location ()).h> |
10 | #include <sys/types.h> |
11 | #include <sys/socket.h> |
12 | #include <arpa/inet.h> |
13 | #include <netinet/in.h> |
14 | #include <string.h> |
15 | #include <unistd.h> |
16 | #include <gnutls/gnutls.h> |
17 | |
18 | #define KEYFILE"key.pem" "key.pem" |
19 | #define CERTFILE"cert.pem" "cert.pem" |
20 | #define CAFILE"ca.pem" "ca.pem" |
21 | #define CRLFILE"crl.pem" "crl.pem" |
22 | |
23 | |
24 | |
25 | |
26 | |
27 | #define SAstruct sockaddr struct sockaddr |
28 | #define SOCKET_ERR(err,s)if(err==-1) {perror(s);return(1);} if(err==-1) {perror(s);return(1);} |
29 | #define MAX_BUF1024 1024 |
30 | #define PORT5556 5556 /* listen to 5556 port */ |
31 | #define DH_BITS1024 1024 |
32 | |
33 | |
34 | gnutls_certificate_credentials_t x509_cred; |
35 | gnutls_psk_server_credentials_t psk_cred; |
36 | gnutls_priority_t priority_cache; |
37 | |
38 | static gnutls_session_t |
39 | initialize_tls_session (void) |
40 | { |
41 | gnutls_session_t session; |
42 | |
43 | gnutls_init (&session, GNUTLS_SERVER1); |
44 | |
45 | gnutls_priority_set (session, priority_cache); |
46 | |
47 | gnutls_credentials_set (session, GNUTLS_CRD_CERTIFICATE, x509_cred); |
48 | gnutls_credentials_set (session, GNUTLS_CRD_PSK, psk_cred); |
49 | |
50 | |
51 | |
52 | gnutls_certificate_server_set_request (session, GNUTLS_CERT_REQUEST); |
53 | |
54 | return session; |
55 | } |
56 | |
57 | static gnutls_dh_params_t dh_params; |
58 | |
59 | static int |
60 | generate_dh_params (void) |
61 | { |
62 | |
63 | |
64 | |
65 | |
66 | |
67 | |
68 | |
69 | |
70 | gnutls_dh_params_init (&dh_params); |
71 | gnutls_dh_params_generate2 (dh_params, DH_BITS1024); |
72 | |
73 | return 0; |
74 | } |
75 | |
76 | static int |
77 | pskfunc (gnutls_session_t session, const char *username, gnutls_datum_t * key) |
78 | { |
79 | printf ("psk: username %s\n", username); |
80 | key->data = gnutls_malloc (4); |
81 | key->data[0] = 0xDE; |
82 | key->data[1] = 0xAD; |
83 | key->data[2] = 0xBE; |
84 | key->data[3] = 0xEF; |
85 | key->size = 4; |
86 | return 0; |
87 | } |
88 | |
89 | int |
90 | main (void) |
91 | { |
92 | int err, listen_sd; |
93 | int sd, ret; |
94 | struct sockaddr_in sa_serv; |
95 | struct sockaddr_in sa_cli; |
96 | int client_len; |
97 | char topbuf[512]; |
98 | gnutls_session_t session; |
99 | char buffer[MAX_BUF1024 + 1]; |
100 | int optval = 1; |
101 | int kx; |
102 | |
103 | |
104 | |
105 | gnutls_global_init (); |
106 | |
107 | gnutls_certificate_allocate_credentials (&x509_cred); |
108 | gnutls_certificate_set_x509_trust_file (x509_cred, CAFILE"ca.pem", |
109 | GNUTLS_X509_FMT_PEM); |
110 | |
111 | gnutls_certificate_set_x509_crl_file (x509_cred, CRLFILE"crl.pem", |
112 | GNUTLS_X509_FMT_PEM); |
113 | |
114 | gnutls_certificate_set_x509_key_file (x509_cred, CERTFILE"cert.pem", KEYFILE"key.pem", |
115 | GNUTLS_X509_FMT_PEM); |
116 | |
117 | gnutls_psk_allocate_server_credentials (&psk_cred); |
118 | gnutls_psk_set_server_credentials_function (psk_cred, pskfunc); |
119 | |
120 | generate_dh_params (); |
121 | |
122 | gnutls_priority_init (&priority_cache, "NORMAL:+PSK:+ECDHE-PSK:+DHE-PSK", NULL((void*)0)); |
123 | |
124 | gnutls_certificate_set_dh_params (x509_cred, dh_params); |
125 | |
126 | |
127 | |
128 | listen_sd = socket (AF_INET2, SOCK_STREAMSOCK_STREAM, 0); |
129 | SOCKET_ERR (listen_sd, "socket")if(listen_sd==-1) {perror("socket");return(1);}; |
130 | |
131 | memset (&sa_serv, '\0', sizeof (sa_serv)); |
132 | sa_serv.sin_family = AF_INET2; |
133 | sa_serv.sin_addr.s_addr = INADDR_ANY((in_addr_t) 0x00000000); |
134 | sa_serv.sin_port = htons (PORT5556); |
135 | |
136 | setsockopt (listen_sd, SOL_SOCKET1, SO_REUSEADDR2, (void *) &optval, |
137 | sizeof (int)); |
138 | |
139 | err = bind (listen_sd, (SAstruct sockaddr *) & sa_serv, sizeof (sa_serv)); |
140 | SOCKET_ERR (err, "bind")if(err==-1) {perror("bind");return(1);}; |
141 | err = listen (listen_sd, 1024); |
142 | SOCKET_ERR (err, "listen")if(err==-1) {perror("listen");return(1);}; |
143 | |
144 | printf ("Server ready. Listening to port '%d'.\n\n", PORT5556); |
145 | |
146 | client_len = sizeof (sa_cli); |
147 | for (;;) |
| 1 | Loop condition is true. Entering loop body |
|
148 | { |
149 | session = initialize_tls_session (); |
150 | |
151 | sd = accept (listen_sd, (SAstruct sockaddr *) & sa_cli, &client_len); |
152 | |
153 | printf ("- connection from %s, port %d\n", |
154 | inet_ntop (AF_INET2, &sa_cli.sin_addr, topbuf, |
155 | sizeof (topbuf)), ntohs (sa_cli.sin_port)); |
| 2 | Pass-by-value argument in function call is undefined |
|
156 | |
157 | gnutls_transport_set_ptr (session, (gnutls_transport_ptr_t) sd); |
158 | ret = gnutls_handshake (session); |
159 | if (ret < 0) |
160 | { |
161 | close (sd); |
162 | gnutls_deinit (session); |
163 | fprintf (stderrstderr, "*** Handshake has failed (%s)\n\n", |
164 | gnutls_strerror (ret)); |
165 | continue; |
166 | } |
167 | printf ("- Handshake was completed\n"); |
168 | |
169 | kx = gnutls_kx_get(session); |
170 | if (kx == GNUTLS_KX_PSK || kx == GNUTLS_KX_DHE_PSK || |
171 | kx == GNUTLS_KX_ECDHE_PSK) |
172 | { |
173 | printf("- User %s was connected\n", gnutls_psk_server_get_username(session)); |
174 | } |
175 | |
176 | |
177 | |
178 | |
179 | for (;;) |
180 | { |
181 | memset (buffer, 0, MAX_BUF1024 + 1); |
182 | ret = gnutls_record_recv (session, buffer, MAX_BUF1024); |
183 | |
184 | if (ret == 0) |
185 | { |
186 | printf ("\n- Peer has closed the GnuTLS connection\n"); |
187 | break; |
188 | } |
189 | else if (ret < 0) |
190 | { |
191 | fprintf (stderrstderr, "\n*** Received corrupted " |
192 | "data(%d). Closing the connection.\n\n", ret); |
193 | break; |
194 | } |
195 | else if (ret > 0) |
196 | { |
197 | |
198 | |
199 | gnutls_record_send (session, buffer, strlen (buffer)); |
200 | } |
201 | } |
202 | printf ("\n"); |
203 | |
204 | |
205 | gnutls_bye (session, GNUTLS_SHUT_WR); |
206 | |
207 | close (sd); |
208 | gnutls_deinit (session); |
209 | |
210 | } |
211 | close (listen_sd); |
212 | |
213 | gnutls_certificate_free_credentials (x509_cred); |
214 | gnutls_psk_free_server_credentials (psk_cred); |
215 | |
216 | gnutls_priority_deinit (priority_cache); |
217 | |
218 | gnutls_global_deinit (); |
219 | |
220 | return 0; |
221 | |
222 | } |