source: trunk/instant_messenger/socket/BKP_20071105/BKP_20071026/BKP_20071019/BKP_20071018/BKP_20071009/server_bkp_20071009.c @ 151

Revision 151, 11.2 KB checked in by niltonneto, 16 years ago (diff)

Commit da nova versão do módulo, usando agente em C.
Vide Página do módulo do Trac:
http://www.expressolivre.org/dev/wiki/messenger

A versão anterior encontra-se na subpasta bkp (32/64).

Line 
1#include "server.h"
2
3/* Globally accessible storage for the exception context: */
4struct exception_context the_exception_context[1];
5
6#define HOST "im.celepar.parana"
7#define IP "10.15.20.219"
8#define PORT "5222"
9
10int main(int argc, char ** argv)
11{
12        /* variables to parse arguments */
13        extern int optind,
14                           optopt;
15        extern char * optarg;
16
17        char * log_file;
18        int c           = (int)NULL,
19                errflg  = (int)NULL,
20                verbose = (int)NULL,
21                optval  = 1;
22
23        socklen_t optlen = sizeof(optval);
24
25        /* fd -> file descriptor */
26        int socket_server_fd    = (int)NULL,
27                socket_server_port      = (int)NULL,
28                socket_accept_fd        = (int)NULL,
29                sockaddr_in_size        = sizeof(struct sockaddr_in),
30                err                                     = (int)NULL;
31
32        /* Internet socket address stuct */
33        struct sockaddr_in server_addr,
34                                           accept_addr;
35
36        struct client * clients = (struct client *) NULL,
37                                  * current = (struct client *) NULL;
38
39        SSL_CTX * ctx;
40
41        pthread_t threads;
42
43        // clear screen
44        system(__CLEAR_SCREEN__);
45
46        while ( (c = getopt(argc, argv, ":vp:")) != -1 )
47        {
48                switch ( c )
49                {
50                        case 'p':
51                                if ( socket_server_port = strtol(optarg, 0, 10) == 0 )
52                                {
53                                        fprintf(stderr, "Option -%c requires a valid port and '%s' isn't valid\n", optopt, optarg);
54                                        ++errflg;
55                                }
56                                break;
57                        case 'v':
58                                verbose = 1;
59                                break;
60                        case ':':
61                                // -f or -o without operand
62                                fprintf(stderr, "Option -%c requires an operand\n", optopt);
63                                ++errflg;
64                                break;
65                        case '?':
66                                fprintf(stderr, "Unrecognized option: -%c\n", optopt);
67                                ++errflg;
68                }
69        }
70        if ( errflg )
71        {
72                fprintf(stderr, "usage: . . . \n\n");
73                exit(2);
74        }
75
76        OpenSSL_add_all_algorithms();
77        SSL_library_init();
78        SSL_load_error_strings();
79
80        if ( !(ctx = SSL_CTX_new(SSLv23_method())) )
81        {
82                printf("Error creating the context.\n");
83                exit(0);
84        }
85
86        if ( SSL_CTX_set_cipher_list(ctx, CIPHER_LIST) < 1 )
87        {
88                printf("Error setting the cipher list.\n");
89                exit(0);
90        }
91
92        //Indicate the certificate file to be used
93        if ( SSL_CTX_use_certificate_file(ctx, CERT_FILE, SSL_FILETYPE_PEM) < 1 )
94        {
95                printf("Error setting the certificate file.\n");
96                exit(0);
97        }
98
99        //Load the password for the Private Key
100        SSL_CTX_set_default_passwd_cb_userdata(ctx, KEY_PASSWD);
101
102        //Indicate the key file to be used
103        if ( SSL_CTX_use_PrivateKey_file(ctx, KEY_FILE, SSL_FILETYPE_PEM) < 1 )
104        {
105                printf("Error setting the key file.\n");
106                exit(0);
107        }
108
109        //Make sure the key and certificate file match
110        if ( !SSL_CTX_check_private_key(ctx) )
111        {
112                printf("Private key does not match the certificate public key\n");
113                exit(0);
114        }
115
116        // Set the list of trusted CAs based on the file and/or directory provided
117        if ( SSL_CTX_load_verify_locations(ctx, CA_FILE, CA_DIR) < 1 )
118        {
119                printf("Error setting verify location\n");
120                exit(0);
121        }
122
123        // Set for server verification
124        SSL_CTX_set_verify(ctx, SSL_VERIFY_NONE, NULL);
125
126        /* make a socket */
127        socket_server_fd = socket(AF_INET, SOCK_STREAM, 0);
128        if ( socket_server_fd == __SOCKET_ERROR__ )
129        {
130                printf("\nCould not make a socket\n");
131                return 0;
132        }
133
134        bzero((char *) &server_addr, sockaddr_in_size);
135        bzero((char *) &accept_addr, sockaddr_in_size);
136
137        if ( !socket_server_port )
138                socket_server_port = __DEFAULT_OPEN_PORT__;
139
140        /* fill address struct */
141        server_addr.sin_addr.s_addr     = INADDR_ANY;
142        server_addr.sin_port            = htons(socket_server_port);
143        server_addr.sin_family          = AF_INET;
144        bzero(&(server_addr.sin_zero), 8);
145
146        if ( __DEBUG__  || verbose )
147                printf("\nBinding to port %d...\n", socket_server_port);
148
149        /* bind to a port */
150        if ( bind(socket_server_fd, (struct sockaddr *)&(server_addr), sizeof(server_addr)) == __SOCKET_ERROR__ )
151        {
152                printf("\nCould not connect to host\n");
153                exit(1);
154        }
155
156        /* get port number */
157        getsockname(socket_server_fd, (struct sockaddr *)&(server_addr), (socklen_t *) &(sockaddr_in_size));
158        if ( __DEBUG__  || verbose )
159        {
160                printf("\nopened socket as fd (%d) on port (%d) for stream i/o\n", socket_server_fd, ntohs(server_addr.sin_port));
161
162                printf("Server\n\
163                                sin_family        = %d\n\
164                                sin_addr.s_addr   = %d\n\
165                                sin_port          = %d\n"
166                                , server_addr.sin_family
167                                , server_addr.sin_addr.s_addr
168                                , ntohs(server_addr.sin_port)
169                          );
170                printf("\nMaking a listen queue of %d elements", __QUEUE_SIZE__);
171        }
172
173        /* establish listen queue */
174        if ( listen(socket_server_fd, __QUEUE_SIZE__) == __SOCKET_ERROR__ )
175        {
176                printf("\nCould not listen\n");
177                return 0;
178        }
179
180        for ( ; ; )
181        {
182                if ( __DEBUG__  || verbose )
183                        puts("\nWaiting for a connection\n");
184
185                /* get the connected socket */
186                socket_accept_fd = accept(socket_server_fd, (struct sockaddr *) &(accept_addr), (socklen_t *) &(sockaddr_in_size));
187                fcntl(socket_accept_fd, F_SETFL, fcntl(socket_accept_fd, F_GETFL, 0) | O_NONBLOCK | O_NDELAY);
188
189                if ( socket_accept_fd > -1 )
190                {
191                        if ( clients == (struct client *) NULL )
192                                current = clients;
193                        else
194                                while ( (current = clients->next) != (struct client *) NULL );
195
196                        current                         = (struct client *) malloc(sizeof(struct client));
197                        current->next           = (struct client *) NULL;
198                        current->fd                     = socket_accept_fd;
199                        current->sockaddr       = accept_addr;
200                        current->ctx            = ctx;
201                        current->last           = time(NULL);
202
203                        pthread_create(&(threads), NULL, handler, (void *) current);
204                }
205        }
206        pthread_exit(NULL);
207}
208
209void * handler(void * pClient)
210{
211    char buffer_client[__BUFFER_SIZE__],
212                 buffer_jabber[__BUFFER_SIZE__];
213    struct client * client = (struct client *) pClient;
214    int i = 0, err, e;
215        time_t last;
216
217        int tls = 0;
218
219        char ip[46];
220        unsigned short port;
221        inet_ntop(AF_INET, &(client->sockaddr.sin_addr), ip, sizeof (ip));
222        port = ntohs(client->sockaddr.sin_port);
223        printf("\nGot a connection from %s, port %hu\n", ip, port);
224        /*---------------------------------------------------*/
225
226        int client_is_connected = -1;
227        int jabber_is_connected = -1;
228
229        struct sockaddr_in socketaddr;
230        int socketfd,
231                nHostPort;
232
233        char buff[4096];
234        SSL_CTX  *ctx;
235        SSL  *myssl;
236
237        char * old_host,
238                 * replace_host;
239
240        replace_host = (char *) malloc(__BUFFER_SIZE__*sizeof(char));
241
242        if ( (nHostPort = strtol(PORT, 0, 10)) == 0 )
243        {
244                printf("\n<port>\n\n");
245                printf("\ncould not make a socket\n");
246                return 0;
247        }
248
249        socketfd = socket(AF_INET, SOCK_STREAM, 0);
250
251        socketaddr.sin_family = AF_INET;
252        socketaddr.sin_addr.s_addr = inet_addr(IP);
253        socketaddr.sin_port = htons(nHostPort);
254
255        if ( !(ctx = SSL_CTX_new(SSLv23_method())) )
256        {
257                printf("Error creating the context.\n");
258                exit(0);
259        }
260
261        err = connect(socketfd, (struct sockaddr*)&socketaddr, sizeof(socketaddr));
262        fcntl(socketfd, F_SETFL, fcntl(socketfd, F_GETFL, 0) | O_NONBLOCK | O_NDELAY);
263
264        if ( err < 0 )
265        {
266                printf("Socket returned error #%d,program terminated\n", err);
267                exit(0);
268        }
269
270        while ( client_is_connected != 0 )
271        {
272                // read from client
273                //puts("\tread - client");
274                bzero(buffer_client, __BUFFER_SIZE__);
275                if ( !tls )
276                        client_is_connected = read(client->fd, buffer_client, __BUFFER_SIZE__);
277                else
278                        client_is_connected = SSL_read(client->myssl, buffer_client, __BUFFER_SIZE__);
279
280                if ( client_is_connected != 0 )
281                {
282                        if ( strlen(buffer_jabber) > 0 )
283                        {
284                                puts("\twriting - client");
285                                printf("\t%s\n\n", buffer_jabber);
286                                // write in the client
287                                Try
288                                {
289                                        if ( !tls )
290                                                write(client->fd, buffer_jabber, strlen(buffer_jabber));
291                                        else
292                                                SSL_write(client->myssl, buffer_jabber, strlen(buffer_jabber));
293                                }
294                                Catch(e) fprintf(stderr, "exception %d\n", e);
295                                puts("\twrote - client");
296                        }
297
298                        if ( strstr(buffer_client, "<stream:stream") && (old_host = strstr(buffer_client, "to=")) )
299                        {
300                                bzero(replace_host, __BUFFER_SIZE__);
301                                strncpy(replace_host, buffer_client, (strlen(buffer_client) - strlen(old_host))+4);
302                                strcat(replace_host, HOST);
303                                old_host = strstr(old_host, " ");
304                                old_host--;
305                                strcat(replace_host, old_host);
306                                bzero(buffer_client, __BUFFER_SIZE__);
307                                strcpy(buffer_client, replace_host);
308                        }
309                }
310
311                // read from jabber service
312                //puts("\tread - jabber");
313                bzero(buffer_jabber, __BUFFER_SIZE__);
314
315                if ( !tls )
316                        jabber_is_connected = read(socketfd, buffer_jabber, __BUFFER_SIZE__);
317                else
318                        jabber_is_connected = SSL_read(myssl, buffer_jabber, __BUFFER_SIZE__);
319
320
321                if ( jabber_is_connected != 0 && strlen(buffer_client) > 0 )
322                {
323                        puts("\twriting - jabber");
324                        printf("\t%s\n\n", buffer_client);
325                        // write in the jabber service
326                        Try
327                        {
328                                if ( !tls )
329                                        write(socketfd, buffer_client, strlen(buffer_client));
330                                else
331                                        SSL_write(myssl, buffer_client, strlen(buffer_client));
332                        }
333                        Catch(e) fprintf(stderr, "exception %d\n", e);
334                        puts("\twrote - jabber");
335                }
336
337                if ( strstr(buffer_jabber, "<proceed xmlns='urn:ietf:params:xml:ns:xmpp-tls'/>") )
338                {
339                        puts("\tbegin tls with jabber");
340                        fcntl( socketfd, F_SETFL, fcntl( socketfd, F_GETFL ) & ~O_NONBLOCK & ~O_NDELAY);
341                        SSL_CTX_set_verify(ctx,SSL_VERIFY_NONE,NULL);
342                        //Create new ssl object
343                        myssl = SSL_new(ctx);
344
345                        if ( !myssl )
346                        {
347                                printf("Error creating SSL structure.\n");
348                                exit(0);
349                        }
350
351                        //Bind the socket to the SSL structure
352                        SSL_set_fd(myssl, socketfd);
353
354                        //Connect to the server, SSL layer.
355                        err = SSL_connect(myssl);
356                        //printf("SSL error #%d in accept,program terminated\n",err);
357                        //Check for error in connect.
358                        if ( err < 1 )
359                        {
360                                err = SSL_get_error(myssl,err);
361                                printf("SSL error #%d in accept, program terminated\n",err);
362                                printf("%d -- %d\n\n", SSL_ERROR_WANT_READ, SSL_ERROR_WANT_WRITE);
363
364                                if(err==5){printf("sockerrno is:\n");}
365
366                                SSL_CTX_free(ctx);
367                                client_is_connected = 0;
368                        }
369
370                        fcntl(socketfd, F_SETFL, fcntl(socketfd, F_GETFL, 0) | O_NONBLOCK | O_NDELAY);
371                        puts("\tend tls with jabber");
372
373                        puts("\twriting proceed in the client");
374                        printf("%s - %d\n", buffer_jabber, strlen(buffer_jabber));
375                        write(client->fd, buffer_jabber, strlen(buffer_jabber));
376                        bzero(buffer_jabber, __BUFFER_SIZE__);
377
378                        puts("\tbegin tls with client");
379                        fcntl( client->fd, F_SETFL, fcntl( client->fd, F_GETFL ) & ~O_NONBLOCK & ~O_NDELAY );
380
381                        //Create new ssl object
382                        if( !(client->myssl = SSL_new(client->ctx)) )
383                        {
384                                printf("Error creating SSL structure.\n");
385                                exit(0);
386                        }
387
388                        //Bind the socket to the SSL structure
389                        SSL_set_fd(client->myssl, client->fd);
390
391                        //Connect to the server, SSL layer.
392                        err = SSL_accept(client->myssl);
393
394                        //Check for error in connect.
395                        if ( err < 1 )
396                        {
397                                printf("SSL error #%d in accept,program terminated\n", err);
398                                err = SSL_get_error(client->myssl, 0);
399                                printf("SSL error #%d in accept,program terminated\n", err);
400
401                                switch ( err )
402                                {
403                                        case SSL_ERROR_NONE : puts("SSL_ERROR_NONE");break;
404                                        case SSL_ERROR_SSL : puts("SSL_ERROR_SSL");break;
405                                        case SSL_ERROR_WANT_READ : puts("SSL_ERROR_WANT_READ");
406                                }
407
408                                if ( err == 5 )
409                                        printf("sockerrno is: %d\n", err);
410
411
412                                SSL_CTX_free(client->ctx);
413                                client_is_connected = 0;
414                        }
415                        fcntl(client->fd, F_SETFL, fcntl(client->fd, F_GETFL, 0) | O_NONBLOCK | O_NDELAY);
416                        puts("\tend tls with client");
417
418                        tls = 1;
419                }
420
421                if ( jabber_is_connected == 0 )
422                        client_is_connected = jabber_is_connected;
423
424                //puts("end loop");
425                usleep(1000);
426        }
427        puts("\n=========================\n");
428    if ( close(socketfd) == __SOCKET_ERROR__ )
429    {
430        printf("\nCould not close jabber socket\n");
431        return 0;
432    }
433        //---------------------------------------------------
434    if ( close(client->fd) == __SOCKET_ERROR__ )
435    {
436        printf("\nCould not close socket\n");
437        return 0;
438    }
439
440    fflush(stdin);
441    fflush(stdout);
442        free(client);
443    pthread_exit(NULL);
444}
Note: See TracBrowser for help on using the repository browser.