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

Revision 151, 8.1 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        while ( (c = getopt(argc, argv, ":vp:")) != -1 )
62        {
63                switch ( c )
64                {
65                        case 'p':
66                                if ( socket_server_port = strtol(optarg, 0, 10) == 0 )
67                                {
68                                        fprintf(stderr, "Option -%c requires a valid port and '%s' isn't valid\n", optopt, optarg);
69                                        ++errflg;
70                                }
71                                break;
72                        case 'v':
73                                verbose = 1;
74                                break;
75                        case ':':
76                                /* -f or -o without operand */
77                                fprintf(stderr, "Option -%c requires an operand\n", optopt);
78                                ++errflg;
79                                break;
80                        case '?':
81                                fprintf(stderr, "Unrecognized option: -%c\n", optopt);
82                                ++errflg;
83                }
84        }
85        if ( errflg )
86        {
87                fprintf(stderr, "usage: . . . \n\n");
88                exit(2);
89        }
90
91        /* make a socket */
92        int one = 1;
93        socket_server_fd = socket(AF_INET, SOCK_STREAM, 0);
94        if ( socket_server_fd == __SOCKET_ERROR__ )
95        {
96                printf("\nCould not make a socket\n");
97                return 0;
98        }
99
100        bzero((char *) &server_addr, sockaddr_in_size);
101        bzero((char *) &accept_addr, sockaddr_in_size);
102
103        if ( !socket_server_port )
104                socket_server_port = __DEFAULT_OPEN_PORT__;
105
106        /* fill address struct */
107        server_addr.sin_addr.s_addr     = INADDR_ANY;
108        server_addr.sin_port            = htons(socket_server_port);
109        server_addr.sin_family          = AF_INET;
110        bzero(&(server_addr.sin_zero), 8);
111
112        if ( __DEBUG__  || verbose )
113                printf("\nBinding to port %d...\n", socket_server_port);
114
115        /* bind to a port */
116        if ( bind(socket_server_fd, (struct sockaddr *)&(server_addr), sizeof(server_addr)) == __SOCKET_ERROR__ )
117        {
118                printf("\nCould not connect to host\n");
119                exit(1);
120        }
121
122        /* get port number */
123        getsockname(socket_server_fd, (struct sockaddr *)&(server_addr), (socklen_t *) &(sockaddr_in_size));
124        if ( __DEBUG__  || verbose )
125        {
126                printf("\nopened socket as fd (%d) on port (%d) for stream i/o\n", socket_server_fd, ntohs(server_addr.sin_port));
127
128                printf("Server\n\
129                                sin_family        = %d\n\
130                                sin_addr.s_addr   = %d\n\
131                                sin_port          = %d\n"
132                                , server_addr.sin_family
133                                , server_addr.sin_addr.s_addr
134                                , ntohs(server_addr.sin_port)
135                          );
136                printf("\nMaking a listen queue of %d elements", __QUEUE_SIZE__);
137        }
138
139        /* establish listen queue */
140        if ( listen(socket_server_fd, __QUEUE_SIZE__) == __SOCKET_ERROR__ )
141        {
142                printf("\nCould not listen\n");
143                return 0;
144        }
145
146        for ( ; ; )
147        {
148                if ( __DEBUG__  || verbose )
149                        puts("\nWaiting for a connection\n");
150
151                /* get the connected socket */
152                socket_accept_fd = accept(socket_server_fd, (struct sockaddr *) &(accept_addr), (socklen_t *) &(sockaddr_in_size));
153                fcntl(socket_accept_fd, F_SETFL, fcntl(socket_accept_fd, F_GETFL, 0) | O_NDELAY);
154
155                if ( socket_accept_fd > -1 )
156                {
157                        if ( clients == (struct client *) NULL )
158                                current = clients;
159                        else
160                                while ( (current = clients->next) != (struct client *) NULL );
161
162                        current                         = (struct client *) malloc(sizeof(struct client));
163                        current->next           = (struct client *) NULL;
164                        current->fd                     = socket_accept_fd;
165                        current->sockaddr       = accept_addr;
166                        current->last           = time(NULL);
167
168                        pthread_create(&(threads), NULL, handler, (void *) current);
169                }
170        }
171        pthread_exit(NULL);
172}
173
174void * handler(void * pClient)
175{
176    char buffer_client[__BUFFER_SIZE__],
177                 buffer_jabber[__BUFFER_SIZE__];
178    struct client * client = (struct client *) pClient;
179    int i = 0, err;
180        time_t last;
181
182        char ip[46];
183        unsigned short port;
184        inet_ntop(AF_INET, &(client->sockaddr.sin_addr), ip, sizeof (ip));
185        port = ntohs(client->sockaddr.sin_port);
186        printf("\nGot a connection from %s, port %hu\n", ip, port);
187        /*---------------------------------------------------*/
188
189        int client_is_connected = -1;
190        int jabber_is_connected = -1;
191
192        struct sockaddr_in socketaddr;
193        int socketfd,
194                nHostPort;
195
196        char buff[4096];
197        char * xml = (char)NULL;
198        SSL_CTX  *ctx;
199        SSL  *myssl;
200
201        char * old_host,
202                 * replace_host;
203
204        xml = (char *) malloc(sizeof(__CONNECT__));
205
206        if ( (nHostPort = strtol(PORT, 0, 10)) == 0 )
207        {
208                printf("\n<port>\n\n");
209                printf("\ncould not make a socket\n");
210                return 0;
211        }
212
213        socketfd = socket(AF_INET, SOCK_STREAM, 0);
214
215        socketaddr.sin_family = AF_INET;
216        socketaddr.sin_addr.s_addr = inet_addr(IP);
217        socketaddr.sin_port = htons(nHostPort);
218
219        OpenSSL_add_all_algorithms();
220        SSL_library_init();
221        SSL_load_error_strings();
222
223        if ( !(ctx = SSL_CTX_new(TLSv1_client_method())) )
224        {
225                printf("Error creating the context.\n");
226                exit(0);
227        }
228
229        err = connect(socketfd, (struct sockaddr*)&socketaddr, sizeof(socketaddr));
230        fcntl(socketfd, F_SETFL, fcntl(socketfd, F_GETFL, 0) | O_NDELAY);
231
232        if ( err < 0 )
233        {
234                printf("Socket returned error #%d,program terminated\n", err);
235                exit(0);
236        }
237
238        while ( client_is_connected != 0 )
239        {
240                /* read from client */
241                puts("\tread - client");
242                bzero(buffer_client, __BUFFER_SIZE__);
243                if ( (client_is_connected = read(client->fd, buffer_client, __BUFFER_SIZE__)) != 0 )
244                {
245                        if ( strlen(buffer_jabber) > 0 )
246                        {
247                                puts("\twrite - client");
248                                printf("\t%s\n", buffer_jabber);
249                                /* write in the client */
250                                write(client->fd, buffer_jabber, strlen(buffer_jabber));
251                        }
252
253                        if ( strstr(buffer_client, "<stream:stream") && (old_host = strstr(buffer_client, "to=")) )
254                        {
255                                strncpy(replace_host, buffer_client, (strlen(buffer_client) - strlen(old_host))+4);
256                                strcat(replace_host, HOST);
257                                old_host = strstr(old_host, " ");
258                                old_host--;
259                                strcat(replace_host, old_host);
260                                strcpy(buffer_client, replace_host);
261                        }
262                }
263
264                /* read from jabber service */
265                puts("\tread - jabber");
266                bzero(buffer_jabber, __BUFFER_SIZE__);
267                if ( (jabber_is_connected = read(socketfd, buffer_jabber, __BUFFER_SIZE__))  && strlen(buffer_client) > 0 )
268                {
269                        puts("\twrite - jabber");
270                        printf("\t%s\n", buffer_client);
271                        /* write in the jabber service */
272                        write(socketfd, buffer_client, strlen(buffer_client));
273                }
274
275                if ( strstr(buffer_jabber, "<proceed xmlns='urn:ietf:params:xml:ns:xmpp-tls'/>") )
276                {
277                        fcntl( socketfd, F_SETFL, fcntl( socketfd, F_GETFL ) & ~O_NDELAY );
278                        SSL_CTX_set_verify(ctx,SSL_VERIFY_NONE,NULL);
279                        //Create new ssl object
280                        myssl=SSL_new(ctx);
281
282                        if(!myssl){
283                                printf("Error creating SSL structure.\n");
284                                exit(0);
285                        }
286
287                        //Bind the socket to the SSL structure
288                        SSL_set_fd(myssl,socketfd);
289
290                        //Connect to the server, SSL layer.
291                        err=SSL_connect(myssl);
292                        printf("SSL error #%d in accept,program terminated\n",err);
293                        //Check for error in connect.
294                        if (err<1) {
295
296                                err=SSL_get_error(myssl,err);
297                                printf("SSL error #%d in accept,program terminated\n",err);
298                                printf("%d -- %d\n\n", SSL_ERROR_WANT_READ, SSL_ERROR_WANT_WRITE);
299
300                                if(err==5){printf("sockerrno is:\n");}
301
302                                close(socketfd);
303                                SSL_CTX_free(ctx);
304                                exit(0);
305                        }
306
307
308                        fcntl(socketfd, F_SETFL, fcntl(socketfd, F_GETFL, 0) | O_NDELAY);
309                }
310
311                if ( jabber_is_connected == 0 )
312                        client_is_connected = jabber_is_connected;
313
314                puts("end loop");
315                usleep(500000);
316        }
317    if ( close(socketfd) == __SOCKET_ERROR__ )
318    {
319        printf("\nCould not close jabber socket\n");
320        return 0;
321    }
322        //---------------------------------------------------
323    if ( close(client->fd) == __SOCKET_ERROR__ )
324    {
325        printf("\nCould not close socket\n");
326        return 0;
327    }
328
329    fflush(stdin);
330    fflush(stdout);
331        free(client);
332    pthread_exit(NULL);
333}
Note: See TracBrowser for help on using the repository browser.