#include "server.h" #include "xmpp.h" #define HOST "im.celepar.parana" #define IP "10.15.20.219" #define PORT "5222" int tls = 0; void Read(void * fd, void *buf, int count) { bzero(buf, count); if ( tls == 0 ) read(*(int *) fd, buf, (ssize_t)count); else SSL_read((SSL *) fd, buf, count); } void Write(void * fd, void *buf, int count) { if ( tls == 0 ) write(*(int *) fd, buf, (ssize_t)count); else SSL_write((SSL *) fd, buf, count); } int main(int argc, char ** argv) { /* variables to parse arguments */ extern int optind, optopt; extern char * optarg; char * log_file; int c = (int)NULL, errflg = (int)NULL, verbose = (int)NULL, optval = 1; socklen_t optlen = sizeof(optval); /* fd -> file descriptor */ int socket_server_fd = (int)NULL, socket_server_port = (int)NULL, socket_accept_fd = (int)NULL, sockaddr_in_size = sizeof(struct sockaddr_in), err = (int)NULL; /* Internet socket address stuct */ struct sockaddr_in server_addr, accept_addr; struct client * clients = (struct client *) NULL, * current = (struct client *) NULL; SSL_CTX * ctx; pthread_t threads; // clear screen system(__CLEAR_SCREEN__); while ( (c = getopt(argc, argv, ":vp:")) != -1 ) { switch ( c ) { case 'p': if ( socket_server_port = strtol(optarg, 0, 10) == 0 ) { fprintf(stderr, "Option -%c requires a valid port and '%s' isn't valid\n", optopt, optarg); ++errflg; } break; case 'v': verbose = 1; break; case ':': // -f or -o without operand fprintf(stderr, "Option -%c requires an operand\n", optopt); ++errflg; break; case '?': fprintf(stderr, "Unrecognized option: -%c\n", optopt); ++errflg; } } if ( errflg ) { fprintf(stderr, "usage: . . . \n\n"); exit(2); } OpenSSL_add_all_algorithms(); SSL_library_init(); SSL_load_error_strings(); if ( !(ctx = SSL_CTX_new(TLSv1_server_method())) ) { printf("Error creating the context.\n"); exit(0); } if ( SSL_CTX_set_cipher_list(ctx, CIPHER_LIST) < 1 ) { printf("Error setting the cipher list.\n"); exit(0); } //Indicate the certificate file to be used if ( SSL_CTX_use_certificate_file(ctx, CERT_FILE, SSL_FILETYPE_PEM) < 1 ) { printf("Error setting the certificate file.\n"); exit(0); } //Load the password for the Private Key SSL_CTX_set_default_passwd_cb_userdata(ctx, KEY_PASSWD); //Indicate the key file to be used if ( SSL_CTX_use_PrivateKey_file(ctx, KEY_FILE, SSL_FILETYPE_PEM) < 1 ) { printf("Error setting the key file.\n"); exit(0); } //Make sure the key and certificate file match if ( !SSL_CTX_check_private_key(ctx) ) { printf("Private key does not match the certificate public key\n"); exit(0); } // Set the list of trusted CAs based on the file and/or directory provided if ( SSL_CTX_load_verify_locations(ctx, CA_FILE, CA_DIR) < 1 ) { printf("Error setting verify location\n"); exit(0); } // Set for server verification SSL_CTX_set_verify(ctx, SSL_VERIFY_NONE, NULL); /* make a socket */ socket_server_fd = socket(AF_INET, SOCK_STREAM, 0); if ( socket_server_fd == __SOCKET_ERROR__ ) { printf("\nCould not make a socket\n"); return 0; } bzero((char *) &server_addr, sockaddr_in_size); bzero((char *) &accept_addr, sockaddr_in_size); if ( !socket_server_port ) socket_server_port = __DEFAULT_OPEN_PORT__; /* fill address struct */ server_addr.sin_addr.s_addr = INADDR_ANY; server_addr.sin_port = htons(socket_server_port); server_addr.sin_family = AF_INET; bzero(&(server_addr.sin_zero), 8); if ( __DEBUG__ || verbose ) printf("\nBinding to port %d...\n", socket_server_port); /* bind to a port */ if ( bind(socket_server_fd, (struct sockaddr *)&(server_addr), sizeof(server_addr)) == __SOCKET_ERROR__ ) { printf("\nCould not connect to host\n"); exit(1); } /* get port number */ getsockname(socket_server_fd, (struct sockaddr *)&(server_addr), (socklen_t *) &(sockaddr_in_size)); if ( __DEBUG__ || verbose ) { printf("\nopened socket as fd (%d) on port (%d) for stream i/o\n", socket_server_fd, ntohs(server_addr.sin_port)); printf("Server\n\ sin_family = %d\n\ sin_addr.s_addr = %d\n\ sin_port = %d\n" , server_addr.sin_family , server_addr.sin_addr.s_addr , ntohs(server_addr.sin_port) ); printf("\nMaking a listen queue of %d elements", __QUEUE_SIZE__); } /* establish listen queue */ if ( listen(socket_server_fd, __QUEUE_SIZE__) == __SOCKET_ERROR__ ) { printf("\nCould not listen\n"); return 0; } for ( ; ; ) { if ( __DEBUG__ || verbose ) puts("\nWaiting for a connection\n"); /* get the connected socket */ socket_accept_fd = accept(socket_server_fd, (struct sockaddr *) &(accept_addr), (socklen_t *) &(sockaddr_in_size)); fcntl(socket_accept_fd, F_SETFL, fcntl(socket_accept_fd, F_GETFL, 0) | O_NDELAY); if ( socket_accept_fd > -1 ) { if ( clients == (struct client *) NULL ) current = clients; else while ( (current = clients->next) != (struct client *) NULL ); current = (struct client *) malloc(sizeof(struct client)); current->next = (struct client *) NULL; current->fd = socket_accept_fd; current->sockaddr = accept_addr; current->ctx = ctx; current->last = time(NULL); pthread_create(&(threads), NULL, handler, (void *) current); } } pthread_exit(NULL); } void * handler(void * pClient) { char buffer_client[__BUFFER_SIZE__], buffer_jabber[__BUFFER_SIZE__]; struct client * client = (struct client *) pClient; int i = 0, err; time_t last; char ip[46]; unsigned short port; inet_ntop(AF_INET, &(client->sockaddr.sin_addr), ip, sizeof (ip)); port = ntohs(client->sockaddr.sin_port); printf("\nGot a connection from %s, port %hu\n", ip, port); /*---------------------------------------------------*/ int client_is_connected = -1; int jabber_is_connected = -1; struct sockaddr_in socketaddr; int socketfd, nHostPort; char buff[4096]; char * xml = (char)NULL; SSL_CTX *ctx; SSL *myssl; char * old_host, * replace_host; xml = (char *) malloc(sizeof(__CONNECT__)); if ( (nHostPort = strtol(PORT, 0, 10)) == 0 ) { printf("\n\n\n"); printf("\ncould not make a socket\n"); return 0; } socketfd = socket(AF_INET, SOCK_STREAM, 0); socketaddr.sin_family = AF_INET; socketaddr.sin_addr.s_addr = inet_addr(IP); socketaddr.sin_port = htons(nHostPort); if ( !(ctx = SSL_CTX_new(TLSv1_client_method())) ) { printf("Error creating the context.\n"); exit(0); } err = connect(socketfd, (struct sockaddr*)&socketaddr, sizeof(socketaddr)); fcntl(socketfd, F_SETFL, fcntl(socketfd, F_GETFL, 0) | O_NDELAY); if ( err < 0 ) { printf("Socket returned error #%d,program terminated\n", err); exit(0); } while ( client_is_connected != 0 ) { /* read from client */ puts("\tread - client"); bzero(buffer_client, __BUFFER_SIZE__); if ( (client_is_connected = read(client->fd, buffer_client, __BUFFER_SIZE__)) != 0 ) { if ( strlen(buffer_jabber) > 0 ) { puts("\twrite - client"); printf("\t%s\n", buffer_jabber); /* write in the client */ write(client->fd, buffer_jabber, strlen(buffer_jabber)); } if ( strstr(buffer_client, " 0 ) { puts("\twrite - jabber"); printf("\t%s\n", buffer_client); /* write in the jabber service */ write(socketfd, buffer_client, strlen(buffer_client)); } if ( strstr(buffer_jabber, "") ) { fcntl( socketfd, F_SETFL, fcntl( socketfd, F_GETFL ) & ~O_NDELAY ); SSL_CTX_set_verify(ctx,SSL_VERIFY_NONE,NULL); //Create new ssl object myssl=SSL_new(ctx); if(!myssl){ printf("Error creating SSL structure.\n"); exit(0); } //Bind the socket to the SSL structure SSL_set_fd(myssl,socketfd); //Connect to the server, SSL layer. err=SSL_connect(myssl); printf("SSL error #%d in accept,program terminated\n",err); //Check for error in connect. if (err<1) { err=SSL_get_error(myssl,err); printf("SSL error #%d in accept,program terminated\n",err); printf("%d -- %d\n\n", SSL_ERROR_WANT_READ, SSL_ERROR_WANT_WRITE); if(err==5){printf("sockerrno is:\n");} close(socketfd); SSL_CTX_free(ctx); exit(0); } fcntl(socketfd, F_SETFL, fcntl(socketfd, F_GETFL, 0) | O_NDELAY); write(client->fd, buffer_jabber, strlen(buffer_jabber)); bzero(buffer_jabber, __BUFFER_SIZE__); fcntl( client->fd, F_SETFL, fcntl( client->fd, F_GETFL ) & ~O_NDELAY ); //Create new ssl object if( !(client->myssl = SSL_new(client->ctx)) ) { printf("Error creating SSL structure.\n"); exit(0); } //Bind the socket to the SSL structure SSL_set_fd(client->myssl, client->fd); puts("_____TESTE______"); //Connect to the server, SSL layer. err = SSL_accept(client->myssl); puts("_____TESTE______"); //Check for error in connect. if ( err < 1 ) { printf("SSL error #%d in accept,program terminated\n", err); err = SSL_get_error(client->myssl, 0); printf("SSL error #%d in accept,program terminated\n", err); switch ( err ) { case SSL_ERROR_NONE : puts("SSL_ERROR_NONE");break; case SSL_ERROR_SSL : puts("SSL_ERROR_SSL");break; case SSL_ERROR_WANT_READ : puts("SSL_ERROR_WANT_READ"); } if ( err == 5 ) printf("sockerrno is: %d\n", err); SSL_CTX_free(client->ctx); client_is_connected = 0; } } if ( jabber_is_connected == 0 ) client_is_connected = jabber_is_connected; puts("end loop"); usleep(500000); } if ( close(socketfd) == __SOCKET_ERROR__ ) { printf("\nCould not close jabber socket\n"); return 0; } //--------------------------------------------------- if ( close(client->fd) == __SOCKET_ERROR__ ) { printf("\nCould not close socket\n"); return 0; } fflush(stdin); fflush(stdout); free(client); pthread_exit(NULL); }