⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 tlsconnection.cxx

📁 RTP协议
💻 CXX
字号:
/* ==================================================================== * The Vovida Software License, Version 1.0  *  * Copyright (c) 2000 Vovida Networks, Inc.  All rights reserved. *  * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: *  * 1. Redistributions of source code must retain the above copyright *    notice, this list of conditions and the following disclaimer. *  * 2. Redistributions in binary form must reproduce the above copyright *    notice, this list of conditions and the following disclaimer in *    the documentation and/or other materials provided with the *    distribution. *  * 3. The names "VOCAL", "Vovida Open Communication Application Library", *    and "Vovida Open Communication Application Library (VOCAL)" must *    not be used to endorse or promote products derived from this *    software without prior written permission. For written *    permission, please contact vocal@vovida.org. * * 4. Products derived from this software may not be called "VOCAL", nor *    may "VOCAL" appear in their name, without prior written *    permission of Vovida Networks, Inc. *  * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND * NON-INFRINGEMENT ARE DISCLAIMED.  IN NO EVENT SHALL VOVIDA * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH * DAMAGE. *  * ==================================================================== *  * This software consists of voluntary contributions made by Vovida * Networks, Inc. and many individuals on behalf of Vovida Networks, * Inc.  For more information on Vovida Networks, Inc., please see * <http://www.vovida.org/>. * */static const char* const TlsConnection_cxx_version =    "$Id: TlsConnection.cxx,v 1.3 2002/09/28 00:03:34 sprajpat Exp $";#include "TlsConnection.hxx"#ifdef VOCAL_HAS_OPENSSL #include <openssl/err.h>#endif#include "cpLog.h"#include "Mutex.hxx"#include "Condition.hxx"bool TlsConnection::initThreads = false;extern "C"{    void my_locking_function(int mode, int n, const char *file, int line);};void my_locking_function(int mode, int n, const char *file, int line){#ifdef VOCAL_HAS_OPENSSL    static Vocal::Threads::Mutex myMutex[2000];    if(mode & CRYPTO_LOCK)    {        myMutex[n].lock();    }    else    {        myMutex[n].unlock();    }#endif}//id_function()static void setCallbacks(){#ifdef VOCAL_HAS_OPENSSL    CRYPTO_set_locking_callback(my_locking_function);#endif}TlsConnection::TlsConnection()    : Connection(),      ctx(0),      ssl(0),      meth(0),      myCertificate(),      myKey(){    if(!initThreads)    {        // set the callbacks        setCallbacks();        initThreads = true;    }}TlsConnection::TlsConnection(Connection& other)    : Connection(other),      ctx(0),      ssl(0),      meth(0),      myCertificate(),      myKey(){    if(!initThreads)    {        // set the callbacks        setCallbacks();        initThreads = true;    }}bool TlsConnection::isTls() const{    return ssl != 0;}int TlsConnection::iclose(){    if(ssl)    {#ifdef VOCAL_HAS_OPENSSL	cpLog(LOG_DEBUG_STACK, "closing SSL");        SSL_shutdown(ssl);		SSL_free (ssl);	SSL_CTX_free (ctx);#endif    }    cpLog(LOG_DEBUG_STACK, "closing regular connection");    return Connection::iclose();}const TlsConnection&TlsConnection::operator=(const TlsConnection& x){    if(&x != this)    {        this->Connection::operator=(x);        ctx = x.ctx;        ssl = x.ssl;        meth = x.meth;        myCertificate = x.myCertificate;        myKey = x.myKey;    }    return *this;}ssize_t TlsConnection::iread(char* buf, size_t count){    if(ssl)    {#ifdef VOCAL_HAS_OPENSSL        while(1)        {            ssize_t t = SSL_read(ssl, buf, count);            if(t == -1)             {                ERR_print_errors_fp(stderr);                int myerr = SSL_get_error(ssl, t);                if(myerr == SSL_ERROR_WANT_READ)                {                    // select here to wait for the right bits but keep                    // from looping relentlessly.  this only will work                    // on UNIX.                    int fd = SSL_get_fd(ssl);                    if(fd >= 0)                    {                        fd_set rfds;                        struct timeval tv;                        int retval;                                                FD_ZERO(&rfds);                        FD_SET(fd, &rfds);                        tv.tv_sec = 5;                        tv.tv_usec = 0;                                                retval = select(fd + 1, &rfds, NULL, NULL, &tv);                                                if(retval <= 0)                        {                            errno = EIO;                            return -1;                        }                    }                    else                    {                        return -1;                    }                }                else                 {                    return -1;                }            }            else            {                return t;            }        }#endif    }    return Connection::iread(buf, count);}ssize_t TlsConnection::iwrite(char* buf, size_t count){    if(ssl)    {#ifdef VOCAL_HAS_OPENSSL        ssize_t t = SSL_write(ssl, buf, count);	if(t == -1) 	{	    ERR_print_errors_fp(stderr);            int myerr = SSL_get_error(ssl, t);            if(myerr == SSL_ERROR_WANT_READ || myerr == SSL_ERROR_WANT_WRITE)            {                return 0;            }	}	return t;#endif    }    return Connection::iwrite(buf, count);}int TlsConnection::initTlsClient(){#ifdef VOCAL_HAS_OPENSSL    SSLeay_add_ssl_algorithms();    meth = TLSv1_client_method();    SSL_load_error_strings();    ctx = SSL_CTX_new (meth);    if(ctx == 0)    {	return -1;    }    ssl = SSL_new (ctx);    if(ssl == 0)    {	return -1;    }    int err;    err = SSL_set_fd (ssl, _connId);    if(!err)    {        cpLog(LOG_DEBUG, "failed to connect socket to TLS!");        return -1;    }    while(1)    {        err = SSL_connect (ssl);        if(err <= 0)        {            // check for ERROR_WANT_READ / ERROR_WANT_WRITE            int myerr = SSL_get_error(ssl, err);                        if(myerr == SSL_ERROR_WANT_READ || myerr == SSL_ERROR_WANT_WRITE)            {                cpLog(LOG_DEBUG, "try again!\n");                vusleep(1000);            }            else            {                // issue                cpLog(LOG_DEBUG, "TLS error: %d ( %s )", err, ERR_error_string(SSL_get_error(ssl, err),0));                break;            }        }        else        {            break;        }    }    return err;#else    return -1;#endif}int TlsConnection::initTlsServer(const char* certificate,                             const char* key){#ifdef VOCAL_HAS_OPENSSL    // check for TLSness    char test[100];    int bytes = ::recv(_connId, test, 32, MSG_PEEK);    test[bytes-1] = '\0';    if(strcmp(test, ".") == 0)    {        cpLog(LOG_DEBUG_STACK, "TLS connection!\n");    }    char buf2[256];    char* bptr = buf2;    for(int i = 0; i < bytes ; ++i)    {        sprintf(bptr, "%2.2x", test[i]);        bptr += 2;    }    cpLog(LOG_DEBUG_STACK, "%s %d", buf2, bytes);    myCertificate = certificate;    myKey = key;        cpLog(LOG_DEBUG_STACK, "initalizing TLS server connection");    SSLeay_add_ssl_algorithms();    meth = TLSv1_server_method();    SSL_load_error_strings();    ctx = SSL_CTX_new (meth);    if(ctx == 0)    {	cpLog(LOG_ERR, "no ctx");	return -1;    }    // at this point, you need your certs.    LocalScopeAllocator lo1;    LocalScopeAllocator lo2;    if (SSL_CTX_use_certificate_file(ctx, 				     myCertificate.getData(lo1), 				     SSL_FILETYPE_PEM) <= 0)     {	ERR_print_errors_fp(stderr);	cpLog(LOG_ERR, "failed to set certificate file %s",	      myCertificate.getData(lo1));	return -1;    }    if (SSL_CTX_use_PrivateKey_file(ctx, 				    myKey.getData(lo2), 				    SSL_FILETYPE_PEM) <= 0)     {	ERR_print_errors_fp(stderr);	cpLog(LOG_ERR, "failed to set key file %s",	      myKey.getData(lo1));	return -1;    }    int err;    assert(ctx != 0);    ssl = SSL_new (ctx);    if(ssl == 0)    {	cpLog(LOG_ERR, "failed to create new ssl");	return -1;    }    assert(_connId >= 0);    SSL_set_fd (ssl, _connId);    while(1)    {        err = SSL_accept (ssl);        if(err <= 0)        {            // check for ERROR_WANT_READ / ERROR_WANT_WRITE            int myerr = SSL_get_error(ssl, err);                        if(myerr == SSL_ERROR_WANT_READ || myerr == SSL_ERROR_WANT_WRITE)            {                cpLog(LOG_DEBUG, "try again!\n");                vusleep(1000);            }            else            {                // issue                cpLog(LOG_DEBUG, "TLS error: %d ( %s )", err, ERR_error_string(SSL_get_error(ssl, err),0));                break;            }        }        else        {            break;        }    }    return err;#else    return -1;#endif}SSL* TlsConnection::getSsl(){    return ssl;}bool TlsConnection::hasTls(){#ifdef VOCAL_HAS_OPENSSL    return true;#else    return false;#endif}DataTlsConnection::getErrMsg(int e){    char tmp[1024];#ifdef VOCAL_HAS_OPENSSL    ERR_error_string_n(SSL_get_error(ssl, e), tmp, 1024);#endif    return Data(tmp);}/* Local Variables: *//* c-file-style: "stroustrup" *//* indent-tabs-mode: nil *//* c-file-offsets: ((access-label . -) (inclass . ++)) *//* c-basic-offset: 4 *//* End: */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -