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

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