From d42357d54b2c933a95ac637c9c1e521b3dbf0a16 Mon Sep 17 00:00:00 2001 From: David Troy Date: Sat, 1 Apr 2006 17:12:46 +0000 Subject: git-svn-id: http://svncommunity.digium.com/svn/astmanproxy/branches/1.20pre@40 f02b47b9-160a-0410-81a6-dc3441afb0ec --- src/ssl.c | 313 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 313 insertions(+) create mode 100644 src/ssl.c (limited to 'src/ssl.c') diff --git a/src/ssl.c b/src/ssl.c new file mode 100644 index 0000000..c912435 --- /dev/null +++ b/src/ssl.c @@ -0,0 +1,313 @@ +/* + * Asterisk -- An open source telephony toolkit. + * + * Copyright (C) 2006, Tello Corporation, Inc. + * + * Remco Treffkorn(Architect) and Mahesh Karoshi(Senior Software Developer) + * + * See http://www.asterisk.org for more information about + * the Asterisk project. Please do not directly contact + * any of the maintainers of this project for assistance; + * the project provides a web site, mailing lists and IRC + * channels for your use. + * + * This program is free software, distributed under the terms of + * the GNU General Public License Version 2. See the LICENSE file + * at the top of the source tree. + */ + +/*! \file + * + * \brief SSL for The Asterisk Management Interface - AMI + * + * Channel Management and more + * + * \author Remco Treffkorn(Architect) and Mahesh Karoshi(Senior Software Developer) + * \ref amiconf + */ + +/*! \addtogroup Group_AMI AMI functions +*/ +/*! @{ + Doxygen group */ + +/*! \note We use negative file descriptors for secure channels. The file descriptor + -1 is reseved for errors. -2 to -... are secure file descriptors. 0 to ... + are regular file descriptors. + + NOTE: Commonly error checks for routines returning fd's are done with (value<0). + You must check for (value==-1) instead, since all other negative fd's now + are valid fd's. +*/ +#ifdef AMI_WITH_SSL +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "asterisk.h" +ASTERISK_FILE_VERSION(__FILE__, "$Revision: 15611 $") + +#include "asterisk/logger.h" +#include "asterisk/options.h" +#include "asterisk/config.h" +#include "asterisk/ssl_addon.h" + +SSL_CTX *sctx; +static long rec_bytes; +static long sent_bytes; +static int ssl_initialized; + + +/*! \brief this has to be called before any other function dealing with ssl. + Initializes all the ssl related stuff here. */ +int init_secure(char *certfile) +{ + SSL_METHOD *meth; + + SSLeay_add_ssl_algorithms(); + SSL_load_error_strings(); + + /* server init */ + meth = SSLv23_server_method(); + sctx = SSL_CTX_new(meth); + + if (!sctx) { + return errexit("Failed to create a server ssl context!"); + } + + if (SSL_CTX_use_certificate_file(sctx, certfile, SSL_FILETYPE_PEM) <= 0) { + return errexit("Failed to use the certificate file!"); + } + + if (SSL_CTX_use_PrivateKey_file(sctx, certfile, SSL_FILETYPE_PEM) <= 0) { + return errexit("Failed to use the key file!\n"); + } + + if (!SSL_CTX_check_private_key(sctx)) { + return errexit("Private key does not match the certificate public key"); + } + ssl_initialized = 1; + return 0; +} + +/*! \brief Takes the negative ssl fd and returns the positive fd recieved from the os. + * It goes through arrray of fixed maximum number of secured channels. +*/ +int get_real_fd(int fd) +{ + if (fd<-1) { + fd = -fd - 2; + if (fd>=0 && fd =0 && fd 0) + rec_bytes += ret; + + if (option_debug > 2) + ast_log(LOG_DEBUG, "Received data from SSL socket - %d\n", ret); + return ret; +} + + +/*! \brief + Needs to be called instead of close() to close a socket. + It also closes the SSL meta connection. +*/ + +int close_sock(int socket) +{ + int ret=0; + SSL* ssl = NULL; + + if (socket < -1) { + socket = - socket - 2; + + ssl = sec_channel[socket].ssl; + sec_channel[socket].ssl = NULL; + socket = sec_channel[socket].fd; + } + + ret= close(socket); + + if (ssl) + SSL_free (ssl); + + return(ret); +} + +/*! \brief This process cannot continue without fixing this error. +*/ +int errexit(char s[]) +{ + ast_log(LOG_ERROR, "SSL critical error: %s", s); + return -1; +} + +/*! \brief Checks whether the client is requesting an ssl encrypted connection or not. If its encrypted + * request we expect "Client Hello" in the beginning of the message and ssl version 2. + * This can be verified by checking buf[0x02], buf[0x03] and buf[0x04]. If the contents are + * 0x01, 0x00, 0x02, then its an ssl packet with content "Client Hello", "SSL version 2". + * For SSL version 3, we might need to check for 0x01, 0x00, 0x03. + * +*/ +int is_encrypt_request(int sslclhellotimeout, int fd) +{ + fd_set listeners; + struct timeval tv; + char buf[1024]; + int ready_fdescriptors; + int ret; + + tv.tv_sec = 0; + tv.tv_usec = sslclhellotimeout * 1000; + + FD_ZERO(&listeners); + FD_SET(fd, &listeners); + + ready_fdescriptors = select (fd + 1, &listeners, NULL, NULL, &tv); + + if (ready_fdescriptors < 0 ) { + ast_log(LOG_ERROR, "select returned error, This should not happen: \n"); + return 0; + } else if (ready_fdescriptors == 0) { + return 0; + } + ret = recv(fd, buf, 100, MSG_PEEK); + if(ret > 0) { + /* check for sslv3 or tls*/ + if ((buf[0x00] == 0x16) && (buf[0x01] == 0x03) && + /* for tls buf[0x02] = 0x01 and ssl v3 buf[0x02] = 0x02 */ + ((buf[0x02] == 0x00) || (buf[0x02] == 0x01))) { + if (option_debug > 1) + ast_log(LOG_DEBUG, "Received a SSL request\n"); + return 1; + /* check for sslv23_client_method */ + } else if ((buf[0x02] == 0x01) && (buf[0x03] == 0x03) && (buf[0x04] == 0x01)) { + if (option_debug > 1) + ast_log(LOG_DEBUG, "Received a SSL request for SSLv23_client_method()\n"); + return 1; + } + /* check for sslv2 and return -1 */ + else if ((buf[0x02] == 0x01) && (buf[0x03] == 0x00) && (buf[0x04] == 0x02)) { + return -1; + } + } + return 0; +} +#endif -- cgit