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

Revision 151, 10.4 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        pthread_t threads;
57
58        /* clear screen */
59        system(__CLEAR_SCREEN__);
60
61        struct sockaddr_in socketaddr;
62        int socketfd,
63                nHostPort;
64
65        char buff[4096];
66        char * xml = (char)NULL;
67        SSL_CTX  *ctx;
68        SSL  *myssl;
69
70        xml = (char *) malloc(sizeof(__CONNECT__));
71
72        while ( (c = getopt(argc, argv, ":vp:")) != -1 )
73        {
74                switch ( c )
75                {
76                        case 'p':
77                                if ( socket_server_port = strtol(optarg, 0, 10) == 0 )
78                                {
79                                        fprintf(stderr, "Option -%c requires a valid port and '%s' isn't valid\n", optopt, optarg);
80                                        ++errflg;
81                                }
82                                break;
83                        case 'v':
84                                verbose = 1;
85                                break;
86                        case ':':
87                                /* -f or -o without operand */
88                                fprintf(stderr, "Option -%c requires an operand\n", optopt);
89                                ++errflg;
90                                break;
91                        case '?':
92                                fprintf(stderr, "Unrecognized option: -%c\n", optopt);
93                                ++errflg;
94                }
95        }
96        if ( errflg )
97        {
98                fprintf(stderr, "usage: . . . \n\n");
99                exit(2);
100        }
101
102        /* make a socket */
103        socket_server_fd = socket(AF_INET, SOCK_STREAM, 0);
104        if ( socket_server_fd == __SOCKET_ERROR__ )
105        {
106                printf("\nCould not make a socket\n");
107                return 0;
108        }
109
110        bzero((char *) &server_addr, sockaddr_in_size);
111        bzero((char *) &accept_addr, sockaddr_in_size);
112
113        if ( !socket_server_port )
114                socket_server_port = __DEFAULT_OPEN_PORT__;
115
116        /* fill address struct */
117        server_addr.sin_addr.s_addr     = INADDR_ANY;
118        server_addr.sin_port            = htons(socket_server_port);
119        server_addr.sin_family          = AF_INET;
120        bzero(&(server_addr.sin_zero), 8);
121
122        if ( __DEBUG__  || verbose )
123                printf("\nBinding to port %d...\n", socket_server_port);
124
125        /* bind to a port */
126        if ( bind(socket_server_fd, (struct sockaddr *)&(server_addr), sizeof(server_addr)) == __SOCKET_ERROR__ )
127        {
128                printf("\nCould not connect to host\n");
129                exit(1);
130        }
131
132        /* get port number */
133        getsockname(socket_server_fd, (struct sockaddr *)&(server_addr), (socklen_t *) &(sockaddr_in_size));
134        if ( __DEBUG__  || verbose )
135        {
136                printf("\nopened socket as fd (%d) on port (%d) for stream i/o\n", socket_server_fd, ntohs(server_addr.sin_port));
137
138                printf("Server\n\
139                                sin_family        = %d\n\
140                                sin_addr.s_addr   = %d\n\
141                                sin_port          = %d\n"
142                                , server_addr.sin_family
143                                , server_addr.sin_addr.s_addr
144                                , ntohs(server_addr.sin_port)
145                          );
146                printf("\nMaking a listen queue of %d elements", __QUEUE_SIZE__);
147        }
148
149        /* establish listen queue */
150        if ( listen(socket_server_fd, __QUEUE_SIZE__) == __SOCKET_ERROR__ )
151        {
152                printf("\nCould not listen\n");
153                return 0;
154        }
155
156        for ( ; ; )
157        {
158                if ( __DEBUG__  || verbose )
159                        puts("\nWaiting for a connection\n");
160
161                /* get the connected socket */
162                socket_accept_fd = accept(socket_server_fd, (struct sockaddr *) &(accept_addr), (socklen_t *) &(sockaddr_in_size));
163                //fcntl(socket_accept_fd, F_SETFL, fcntl(socket_accept_fd, F_GETFL, 0) | O_NDELAY);
164
165                if ( socket_accept_fd > -1 )
166                {
167                        if ( clients == (struct client *) NULL )
168                                current = clients;
169                        else
170                                while ( (current = clients->next) != (struct client *) NULL );
171
172                        current                         = (struct client *) malloc(sizeof(struct client));
173                        current->next           = (struct client *) NULL;
174                        current->fd                     = socket_accept_fd;
175                        current->sockaddr       = accept_addr;
176                        current->last           = time(NULL);
177
178                        if ( (nHostPort = strtol(PORT, 0, 10)) == 0 )
179                        {
180                                printf("\n<port>\n\n");
181                                printf("\ncould not make a socket\n");
182                                return 0;
183                        }
184
185                        socketfd = socket(AF_INET, SOCK_STREAM, 0);
186
187                        socketaddr.sin_family = AF_INET;
188                        //socketaddr.sin_addr.s_addr = INADDR_ANY;//inet_addr(IP);
189                        socketaddr.sin_addr.s_addr = inet_addr(IP);
190                        socketaddr.sin_port = htons(nHostPort);
191
192                        SSL_library_init();
193                        if ( !(ctx = SSL_CTX_new(TLSv1_client_method())) )
194                        {
195                                printf("Error creating the context.\n");
196                                exit(0);
197                        }
198
199                        err = connect(socketfd, (struct sockaddr*)&socketaddr, sizeof(socketaddr));
200
201                        if ( err < 0 )
202                        {
203                                printf("Socket returned error #%d,program terminated\n", err);
204                                exit(0);
205                        }
206
207                        sprintf(xml, __CONNECT__, HOST);
208                        Write(&socketfd, xml, strlen(xml));
209                        int stop = 0;
210                        do
211                        {
212                                Read (&socketfd, buff, sizeof(buff));
213                                if ( strstr(buff, __FEATURES_BEGIN__) )
214                                        stop = 1;
215                                else
216                                        usleep(100);
217                        }
218                        while ( !stop );
219
220                        puts(buff);
221                        stop = 0;
222                        int starttls = 0;
223
224                        if ( strstr(buff, __STARTTLS_SERVER__) )
225                                starttls = 1;
226
227                        if ( starttls )
228                        {
229                                sprintf(xml, __STARTTLS_CLIENT__);
230                                Write(&socketfd, xml, strlen(xml));
231
232                                stop = 0;
233                                do
234                                {
235                                        Read (&socketfd, buff, sizeof(buff));
236                                        if ( strstr(buff, __PROCEED__) )
237                                                stop = 1;
238                                        else
239                                                usleep(100);
240                                }
241                                while ( !stop );
242                                printf("%s\n\n", buff);
243                                bzero(buff, 4096);
244
245                                SSL_CTX_set_verify(ctx,SSL_VERIFY_NONE,NULL);
246                                /*Create new ssl object*/
247                                myssl=SSL_new(ctx);
248
249                                if(!myssl){
250                                        printf("Error creating SSL structure.\n");
251                                        exit(0);
252                                }
253
254                                /*Bind the socket to the SSL structure*/
255                                SSL_set_fd(myssl,socketfd);
256
257                                /*Connect to the server, SSL layer.*/
258                                err=SSL_connect(myssl);
259                                printf("SSL error #%d in accept,program terminated\n",err);
260                                /*Check for error in connect.*/
261                                if (err<1) {
262
263                                        err=SSL_get_error(myssl,err);
264                                        printf("SSL error #%d in accept,program terminated\n",err);
265                                        printf("%d -- %d\n\n", SSL_ERROR_WANT_READ, SSL_ERROR_WANT_WRITE);
266
267                                        if(err==5){printf("sockerrno is:\n");}
268
269                                        close(socketfd);
270                                        SSL_CTX_free(ctx);
271                                        exit(0);
272                                }
273
274                                tls = 1;
275
276                                printf("SSL connection on socket %x,Version: %s, Cipher: %s\n\n\n",
277                                                socketfd,
278                                                SSL_get_version(myssl),
279                                                SSL_get_cipher(myssl));
280
281                                sprintf(xml, __CONNECT__, HOST);
282                                SSL_write(myssl, xml, strlen(xml));
283                                usleep(10000);
284                                SSL_read(myssl, buff, sizeof(buff));
285                                printf("%s\n\n", buff);
286                                bzero(buff, 4096);
287
288                                usleep(10000);
289                                SSL_read(myssl, buff, sizeof(buff));
290                                printf("%s\n\n", buff);
291                                bzero(buff, 4096);
292
293                                SSL_clear(myssl);
294                                SSL_shutdown(myssl);
295                                SSL_free(myssl);
296                                SSL_CTX_free(ctx);
297                        }
298                        fflush(stdin);
299                        fflush(stdout);
300
301
302
303                        //pthread_create(&(threads), NULL, handler, (void *) current);
304                }
305        }
306        pthread_exit(NULL);
307}
308
309void * handler(void * pClient)
310{
311    char buffer_client[__BUFFER_SIZE__],
312                 buffer_jabber[__BUFFER_SIZE__];
313    struct client * client = (struct client *) pClient;
314    int i = 0, err;
315        time_t last;
316
317        char ip[46];
318        unsigned short port;
319        inet_ntop(AF_INET, &(client->sockaddr.sin_addr), ip, sizeof (ip));
320        port = ntohs(client->sockaddr.sin_port);
321        printf("\nGot a connection from %s, port %hu\n", ip, port);
322        /*---------------------------------------------------*/
323
324        int jabber_fd           = (int)NULL,
325                jabber_port             = (int)NULL,
326                jabber_error    = (int)NULL;
327
328        struct sockaddr_in jabber_addr;
329
330        jabber_port = __DEFAULT_JABBER_PORT__;
331        jabber_fd = socket(AF_INET, SOCK_STREAM, 0);
332
333        fcntl(jabber_fd, F_SETFL, fcntl(jabber_fd, F_GETFL, 0) | O_NDELAY);
334
335        jabber_addr.sin_family = AF_INET;
336        inet_aton(__DEFAULT_JABBER_IP__, &jabber_addr.sin_addr);
337        //jabber_addr.sin_addr.s_addr = inet_addr(__DEFAULT_JABBER_IP__);
338        jabber_addr.sin_port = htons(jabber_port);
339
340        jabber_error = connect(jabber_fd, (struct sockaddr *) &(jabber_addr), sizeof(jabber_addr));
341
342        last = time(NULL);
343        int client_is_connected = -1;
344        int jabber_is_connected = -1;
345        int sockaddr_in_size    = sizeof(struct sockaddr_in);
346        while ( client_is_connected != 0 )
347        {
348                /* read from client */
349                puts("\tread - client");
350                bzero(buffer_client, __BUFFER_SIZE__);
351                if ( (client_is_connected = read(client->fd, buffer_client, __BUFFER_SIZE__)) != 0 && strlen(buffer_jabber) > 0 )
352                {
353                        puts("\twrite - client");
354                        printf("\t%s\n", buffer_jabber);
355                        /* write in the client */
356                        write(client->fd, buffer_jabber, strlen(buffer_jabber));
357                }
358
359                /* read from jabber service */
360                puts("\tread - jabber");
361                bzero(buffer_jabber, __BUFFER_SIZE__);
362                if ( (jabber_is_connected = read(jabber_fd, buffer_jabber, __BUFFER_SIZE__))  && strlen(buffer_client) > 0 )
363                {
364                                puts("\twrite - jabber");
365                                printf("\t%s\n", buffer_client);
366                                /* write in the jabber service */
367                                if ( !strstr(buffer_jabber, "<proceed xmlns='urn:ietf:params:xml:ns:xmpp-tls'/>") )
368                                        write(jabber_fd, buffer_client, strlen(buffer_client));
369                }
370                if ( strstr(buffer_jabber, "<proceed xmlns='urn:ietf:params:xml:ns:xmpp-tls'/>") )
371                {
372                        fcntl(jabber_fd, F_SETFL, fcntl(jabber_fd, F_GETFL, 0) | ~O_NDELAY);
373                        //starttls(&jabber_fd, &client->fd);
374                        int err;
375
376                        SSL_CTX * ctx;
377                        SSL * jabberssl;
378
379                        //OpenSSL_add_all_algorithms();
380
381                        SSL_library_init();
382                        SSL_load_error_strings();
383
384                        if ( !(ctx = SSL_CTX_new(TLSv1_server_method())) )
385                        {
386                                printf("Error creating the context.\n");
387                                exit(0);
388                        }
389
390                        SSL_CTX_set_verify(ctx,SSL_VERIFY_NONE,NULL);
391
392                        jabberssl = SSL_new(ctx);
393
394                        puts("#1");
395                        err=SSL_set_fd(jabberssl, jabber_fd);
396                        if ( err < 1 )
397                        {
398                                puts("shsfghdfgh");
399                                SSL_CTX_free(ctx);
400                        }
401
402                        puts("connect");
403                        err = SSL_connect(jabberssl);
404                        if ( err < 1 )
405                        {
406                                puts("client");
407                                err = SSL_get_error(jabberssl, err);
408                                printf("%d\n", err);
409                                char err_str[1024];
410                                ERR_error_string_n(ERR_get_error(), err_str, sizeof(err_str));
411                                printf("%s\n", err_str);
412                                SSL_CTX_free(ctx);
413                        }
414                }
415
416                if ( jabber_is_connected == 0 )
417                        client_is_connected = jabber_is_connected;
418
419                puts("end loop");
420                usleep(500000);
421        }
422
423    if ( close(jabber_fd) == __SOCKET_ERROR__ )
424    {
425        printf("\nCould not close jabber socket\n");
426        return 0;
427    }
428        /*---------------------------------------------------*/
429    if ( close(client->fd) == __SOCKET_ERROR__ )
430    {
431        printf("\nCould not close socket\n");
432        return 0;
433    }
434
435    fflush(stdin);
436    fflush(stdout);
437        free(client);
438    pthread_exit(NULL);
439}
Note: See TracBrowser for help on using the repository browser.