C > socket NewSyndrome

Titresocket NewSyndrome
Postée le09-07-2009
Affichée443
Mini-lien
Description

test de la coloration

EtatNe contient pas d'erreurs. Ne contient pas d'erreurs.
Code d'insertion
Options
Afficher les numéros de lignes  Mettre la source en plein ecran  Selectionner la source  Partager sur Facebook 
Téléchargement Telecharger en format txt  Telecharger en format pdf  Telecharger en format c
Plein ecran
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Gestion du socket du bot ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Auteur: Thaeron
Projet: NewSyndrome
Licence: GPL
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/


#include "NewSyndrome.h"


#ifndef ENABLE_IPV6
int tcp_connect (const char *server_host, int port, const char *bind_ip)
{
        struct sockaddr_in sindist, msim;
        int ret = -1;
        struct hostent *host;
        unsigned long opt = 1;
        int sock;

        sock = socket (AF_INET, SOCK_STREAM, 0);
        if (sock == -1)
                return (NS_NO_SOCKET);

        if (bind_ip && *bind_ip)
        {
                msim.sin_addr.s_addr = inet_addr (bind_ip);
                msim.sin_family = AF_INET;
                msim.sin_port = htons (0);

                setsockopt (sock, SOL_SOCKET, SO_REUSEADDR, (char *) &opt, sizeof (opt));

                if (bind (sock, (struct sockaddr *) &msim, sizeof (msim)) < 0)
                {
                        closesocket (sock);
                        return (NS_CANNOT_BIND);
                }
        }

        sindist.sin_family = AF_INET;
        sindist.sin_addr.s_addr = inet_addr (server_host);
        sindist.sin_port = htons (port);

        if (sindist.sin_addr.s_addr == -1)
        {
                host = gethostbyname (server_host);
                if (host == NULL)
                {
                        closesocket (sock);
                        return (NS_CANNOT_RESOLVE);
                }
               
                memcpy ((char *) &sindist.sin_addr.s_addr, host->h_addr, host->h_length);
        }

        ret = connect (sock, (struct sockaddr *) &sindist, sizeof (struct sockaddr_in));
        if (ret < 0)
        {
                closesocket (sock);
                return (NS_CANNOT_CONNECT);
        }
       
        return (sock);
}
#endif


#ifdef ENABLE_IPV6
int tcp_connect (const char *server_host, int port, const char *bind_ip)
{
        int sock;
        int ret;
        struct addrinfo *res;
        char *str_port;
       
        str_port = strf ("%d", port);
        ret = getaddrinfo (server_host, str_port, NULL, &res);
        free (str_port);
       
        if (ret)
                return (NS_CANNOT_RESOLVE);
       
        sock = socket (res->ai_family, SOCK_STREAM, 0);
        if (sock == -1)
                return (NS_NO_SOCKET);
       
        ret = connect (sock, res->ai_addr, res->ai_addrlen);
        freeaddrinfo (res);
       
        if (ret < 0)
        {
                closesocket (sock);
                return (NS_CANNOT_CONNECT);
        }

        return (sock);
}
#endif


#ifdef ENABLE_SSL_CONNECTION

#ifdef SSL_FROM_OPENSSL
SSL_CTX *initialize_ctx (void)
{
        static byte init_once = 0;     
       
        SSL_METHOD *meth;
        SSL_CTX *ctx;

        if (!init_once)
        {
                SSL_library_init ();
                SSL_load_error_strings ();
                init_once = 1;
        }

        meth = SSLv23_method ();
        ctx = SSL_CTX_new (meth);

        SSL_CTX_load_verify_locations (ctx, "", 0);
#if (OPENSSL_VERSION_NUMBER < 0x00905100L)
        SSL_CTX_set_verify_depth (ctx, 1);
#endif

        return (ctx);
}


/*int check_cert(SSL *ssl, char *host)
{
        X509 *peer;
        char peer_CN[256];

        if (SSL_get_verify_result (ssl) != X509_V_OK)
                log_info ("SSL certificate non signé\n");


        peer = SSL_get_peer_certificate (ssl);
        if (peer == NULL)
                log_infof ("SSL : heu un truc");
       
        else
        {
                if (X509_NAME_get_text_by_NID (X509_get_subject_name (peer), NID_commonName, peer_CN, 256) == -1)
                        log_infof ("SSL : getting host name fails");
               
                else if (strcmp (peer_CN, host))
                        log_infof ("SSL: common name doesn't match host name\nSSL: [%s]<=>[%s]\n", peer_CN, host);
        }
       
        return (0);
}*/



int ssl_connect (void)
{
        BIO *sbio;
       
        ns_core.ctx = initialize_ctx ();
        ns_core.ssl = SSL_new (ns_core.ctx);
       
        sbio = BIO_new_socket (ns_core.sd, BIO_NOCLOSE);
        SSL_set_bio (ns_core.ssl, sbio, sbio);
       
        if (SSL_connect (ns_core.ssl) <= 0)
                return (-1);

        /*if (check_cert (ns_core.ssl, ns_conf.server) < 0)
                return (-1);*/

       
        return (1);
}


void ssl_free_all (void)
{
        SSL_free (ns_core.ssl);
        SSL_CTX_free (ns_core.ctx);
}

#endif
#ifdef SSL_FROM_GNUTLS

int ssl_connect (void)
{
        const char *err;
        int ret;
       
        gnutls_global_init ();
        gnutls_certificate_allocate_credentials (&ns_core.xcred);
        gnutls_certificate_set_x509_trust_file (ns_core.xcred, "", GNUTLS_X509_FMT_PEM);

        gnutls_init (&ns_core.session, GNUTLS_CLIENT);

        ret = gnutls_priority_set_direct (ns_core.session, "PERFORMANCE", &err);
        if (ret < 0)
        {
                if (ret == GNUTLS_E_INVALID_REQUEST)
                        log_infof ("SSL : Syntax error at: %s", err);
               
                return (-1);
        }

        gnutls_credentials_set (ns_core.session, GNUTLS_CRD_CERTIFICATE, ns_core.xcred);
        gnutls_transport_set_ptr (ns_core.session, (gnutls_transport_ptr_t) ((long int) ns_core.sd));
        ret = gnutls_handshake (ns_core.session);

        if (ret < 0)
        {
                log_infof ("SSL Error : Handshake failed (%s)", gnutls_strerror (ret));
               
                gnutls_deinit (ns_core.session);
                gnutls_certificate_free_credentials (ns_core.xcred);
                gnutls_global_deinit ();
               
                return (-1);
        }

        return (1);
}


void ssl_free_all (void)
{
        gnutls_bye (ns_core.session, GNUTLS_SHUT_RDWR);
        gnutls_deinit (ns_core.session);
        gnutls_certificate_free_credentials (ns_core.xcred);
        gnutls_global_deinit ();
}

#endif

#endif


ssize_t ns_send (int s, const void *buf, size_t len, int flags)
{
#ifdef ENABLE_SSL_CONNECTION
        if (ns_conf.use_ssl)
        {
#ifdef SSL_FROM_OPENSSL
                return (SSL_write (ns_core.ssl, buf, len));
#endif
#ifdef SSL_FROM_GNUTLS
                return (gnutls_record_send (ns_core.session, buf, len));
#endif
                log_info ("Erreur : SSL activé à la compilation et dans la configuration mais sans support d'openssl ou de gnutls");
        }
#endif
        return (send (s, buf, len, flags));    
}


ssize_t ns_recv (int s, void *buf, size_t len, int flags)
{
#ifdef ENABLE_SSL_CONNECTION
        if (ns_conf.use_ssl)
        {
#ifdef SSL_FROM_OPENSSL
                return (SSL_read (ns_core.ssl, buf, len));
#endif
#ifdef SSL_FROM_GNUTLS
                return (gnutls_record_recv (ns_core.session, buf, len));
#endif
                log_info ("Erreur : SSL activé à la compilation et dans la configuration mais sans support d'OpenSSL ou de GnuTLS");
        }
#endif
        return (recv (s, buf, len, flags));    
}