[svn-commits] branch group/ami_ssl r27679 - in /team/group/ami_ssl: ./ include/asterisk/

svn-commits at lists.digium.com svn-commits at lists.digium.com
Tue May 16 23:08:08 MST 2006


Author: oej
Date: Wed May 17 01:08:07 2006
New Revision: 27679

URL: http://svn.digium.com/view/asterisk?rev=27679&view=rev
Log:
Adding patch from jtodd

Modified:
    team/group/ami_ssl/cli.c
    team/group/ami_ssl/include/asterisk/manager.h
    team/group/ami_ssl/include/asterisk/ssl_addon.h
    team/group/ami_ssl/include/asterisk/utils.h
    team/group/ami_ssl/manager.c
    team/group/ami_ssl/ssl_addon.c
    team/group/ami_ssl/utils.c

Modified: team/group/ami_ssl/cli.c
URL: http://svn.digium.com/view/asterisk/team/group/ami_ssl/cli.c?rev=27679&r1=27678&r2=27679&view=diff
==============================================================================
--- team/group/ami_ssl/cli.c (original)
+++ team/group/ami_ssl/cli.c Wed May 17 01:08:07 2006
@@ -65,7 +65,7 @@
 	if (res == -1) {
 		ast_log(LOG_ERROR, "Memory allocation failure\n");
 	} else {
-		ast_carefulwrite(fd, stuff, strlen(stuff), 100);
+		ast_carefulwrite(fd, stuff, strlen(stuff), 100, NULL);
 		free(stuff);
 	}
 }

Modified: team/group/ami_ssl/include/asterisk/manager.h
URL: http://svn.digium.com/view/asterisk/team/group/ami_ssl/include/asterisk/manager.h?rev=27679&r1=27678&r2=27679&view=diff
==============================================================================
--- team/group/ami_ssl/include/asterisk/manager.h (original)
+++ team/group/ami_ssl/include/asterisk/manager.h Wed May 17 01:08:07 2006
@@ -26,6 +26,10 @@
 #include <arpa/inet.h>
 
 #include "asterisk/lock.h"
+
+#if AMI_WITH_SSL
+#include "asterisk/ssl_addon.h"
+#endif
 
 /*!
  \file
@@ -59,7 +63,56 @@
 #define AST_MAX_MANHEADERS 80
 #define AST_MAX_MANHEADER_LEN 256
 
-struct mansession;
+struct mansession {
+	/*! Execution thread */
+	pthread_t t;
+	/*! Thread lock -- don't use in action callbacks, it's already taken care of  */
+	ast_mutex_t __lock;
+	/*! socket address */
+	struct sockaddr_in sin;
+	/*! TCP socket */
+	int fd;
+#if AMI_WITH_SSL
+	/*! Whether or not we use SSL (ssl context *, or NULL) */
+	SSL *ssl;
+#endif
+	/*! Whether or not we're busy doing an action */
+	int busy;
+	/*! Whether or not we're "dead" */
+	int dead;
+	/*! Whether an HTTP manager is in use */
+	int inuse;
+	/*! Whether an HTTP session should be destroyed */
+	int needdestroy;
+	/*! Whether an HTTP session has someone waiting on events */
+	pthread_t waiting_thread;
+	/*! Unique manager identifer */
+	unsigned long managerid;
+	/*! Session timeout if HTTP */
+	time_t sessiontimeout;
+	/*! Output from manager interface */
+	char *outputstr;
+	/*! Logged in username */
+	char username[80];
+	/*! Authentication challenge */
+	char challenge[10];
+	/*! Authentication status */
+	int authenticated;
+	/*! Authorization for reading */
+	int readperm;
+	/*! Authorization for writing */
+	int writeperm;
+	/*! Buffer */
+	char inbuf[AST_MAX_MANHEADER_LEN];
+	int inlen;
+	int send_events;
+	int displaysystemname;		/*!< Add system name to manager responses and events */
+	/* Queued events that we've not had the ability to send yet */
+	struct eventqent *eventq;
+	/* Timeout for ast_carefulwrite() */
+	int writetimeout;
+	struct mansession *next;
+};
 
 struct message {
 	int hdrcount;

Modified: team/group/ami_ssl/include/asterisk/ssl_addon.h
URL: http://svn.digium.com/view/asterisk/team/group/ami_ssl/include/asterisk/ssl_addon.h?rev=27679&r1=27678&r2=27679&view=diff
==============================================================================
--- team/group/ami_ssl/include/asterisk/ssl_addon.h (original)
+++ team/group/ami_ssl/include/asterisk/ssl_addon.h Wed May 17 01:08:07 2006
@@ -59,7 +59,7 @@
    Accepts the connection, if the security is enabled it returns the negative fd. -1 is flase, -2, -3 
    etc are ssl connections. 
 */ 
-int saccept(int s);
+int saccept(void *s);
 
 /*!  \brief
    Sends the data over secured or unsecured connections. 
@@ -70,7 +70,7 @@
 /*! \brief
    Receives the connection from either ssl or fd.
 */
-int m_recv(int s, void *buf, size_t len, int flags);
+int m_recv(void *s, void *buf, size_t len, int flags);
 
 
 /*! \brief
@@ -78,7 +78,7 @@
   It also closes the ssl meta connection.
 */
 
-int close_sock(int socket);
+int close_sock(void *s);
 
 int errexit(char s[]);
 

Modified: team/group/ami_ssl/include/asterisk/utils.h
URL: http://svn.digium.com/view/asterisk/team/group/ami_ssl/include/asterisk/utils.h?rev=27679&r1=27678&r2=27679&view=diff
==============================================================================
--- team/group/ami_ssl/include/asterisk/utils.h (original)
+++ team/group/ami_ssl/include/asterisk/utils.h Wed May 17 01:08:07 2006
@@ -233,8 +233,10 @@
 	it on a file descriptor that _DOES_ have NONBLOCK set.  This way,
 	there is only one system call made to do a write, unless we actually
 	have a need to wait.  This way, we get better performance.
-*/
-int ast_carefulwrite(int fd, char *s, int len, int timeoutms);
+	The file descriptor is taken from the struct mansession pointer, if it is
+	non NULL, otherwise the parameter fd is used.
+*/
+int ast_carefulwrite(int fd, char *s, int len, int timeoutms, void *vs);
 
 /*! Compares the source address and port of two sockaddr_in */
 static force_inline int inaddrcmp(const struct sockaddr_in *sin1, const struct sockaddr_in *sin2)

Modified: team/group/ami_ssl/manager.c
URL: http://svn.digium.com/view/asterisk/team/group/ami_ssl/manager.c?rev=27679&r1=27678&r2=27679&view=diff
==============================================================================
--- team/group/ami_ssl/manager.c (original)
+++ team/group/ami_ssl/manager.c Wed May 17 01:08:07 2006
@@ -53,6 +53,9 @@
 
 #include "asterisk/channel.h"
 #include "asterisk/file.h"
+#ifdef AMI_WITH_SSL
+#include "asterisk/ssl_addon.h"
+#endif
 #include "asterisk/manager.h"
 #include "asterisk/config.h"
 #include "asterisk/callerid.h"
@@ -65,9 +68,6 @@
 #include "asterisk/md5.h"
 #include "asterisk/acl.h"
 #include "asterisk/utils.h"
-#ifdef AMI_WITH_SSL
-#include "asterisk/ssl_addon.h"
-#endif
 #include "asterisk/http.h"
 
 struct fast_originate_helper {
@@ -128,52 +128,7 @@
 	{ 0, "none" },
 };
 
-static struct mansession {
-	/*! Execution thread */
-	pthread_t t;
-	/*! Thread lock -- don't use in action callbacks, it's already taken care of  */
-	ast_mutex_t __lock;
-	/*! socket address */
-	struct sockaddr_in sin;
-	/*! TCP socket */
-	int fd;
-	/*! Whether or not we're busy doing an action */
-	int busy;
-	/*! Whether or not we're "dead" */
-	int dead;
-	/*! Whether an HTTP manager is in use */
-	int inuse;
-	/*! Whether an HTTP session should be destroyed */
-	int needdestroy;
-	/*! Whether an HTTP session has someone waiting on events */
-	pthread_t waiting_thread;
-	/*! Unique manager identifer */
-	unsigned long managerid;
-	/*! Session timeout if HTTP */
-	time_t sessiontimeout;
-	/*! Output from manager interface */
-	char *outputstr;
-	/*! Logged in username */
-	char username[80];
-	/*! Authentication challenge */
-	char challenge[10];
-	/*! Authentication status */
-	int authenticated;
-	/*! Authorization for reading */
-	int readperm;
-	/*! Authorization for writing */
-	int writeperm;
-	/*! Buffer */
-	char inbuf[AST_MAX_MANHEADER_LEN];
-	int inlen;
-	int send_events;
-	int displaysystemname;		/*!< Add system name to manager responses and events */
-	/* Queued events that we've not had the ability to send yet */
-	struct eventqent *eventq;
-	/* Timeout for ast_carefulwrite() */
-	int writetimeout;
-	struct mansession *next;
-} *sessions = NULL;
+static struct mansession *sessions = NULL;
 
 static struct manager_action *first_action = NULL;
 AST_MUTEX_DEFINE_STATIC(actionlock);
@@ -392,7 +347,7 @@
 		return;
 	} 
 	if (s->fd > -1)
-		ast_carefulwrite(s->fd, stuff, strlen(stuff), s->writetimeout);
+		ast_carefulwrite(0, stuff, strlen(stuff), s->writetimeout, s);
 	else {
 		tmp = realloc(s->outputstr, (s->outputstr ? strlen(s->outputstr) : 0) + strlen(stuff) + 1);
 		if (tmp) {
@@ -535,7 +490,7 @@
 {
 	struct eventqent *eqe;
 #ifdef AMI_WITH_SSL
-	close_sock(s->fd);
+	close_sock(s);
 #else
 	if (s->fd > -1)
 		close(s->fd);
@@ -1633,7 +1588,7 @@
 			eqe = s->eventq->next;
 			if ((s->authenticated && (s->readperm & eqe->category) == eqe->category) &&
 			    ((s->send_events & eqe->category) == eqe->category)) {
-				if (!ret && ast_carefulwrite(s->fd, eqe->eventdata, strlen(eqe->eventdata), s->writetimeout) < 0)
+				if (!ret && ast_carefulwrite(0, eqe->eventdata, strlen(eqe->eventdata), s->writetimeout, s) < 0)
 					ret = -1;
 			}
 			unuse_eventqent(s->eventq);
@@ -1749,9 +1704,6 @@
 		s->inlen = 0;
 	}
 	fds[0].fd = s->fd;
-#ifdef AMI_WITH_SSL
-	fds[0].fd = get_real_fd(s->fd);
-#endif
 
 	fds[0].events = POLLIN;
 	do {
@@ -1775,7 +1727,14 @@
 		} else if (res > 0) {
 			ast_mutex_lock(&s->__lock);
 #ifdef AMI_WITH_SSL
-			res = m_recv(s->fd, s->inbuf + s->inlen, sizeof(s->inbuf) - 1 - s->inlen, 0);
+			if (s->ssl) {
+				res = SSL_read (s->ssl, s->inbuf + s->inlen,
+						sizeof(s->inbuf) - 1 - s->inlen);
+			} 
+			else {
+				res = read(s->fd, s->inbuf + s->inlen,
+						sizeof(s->inbuf) - 1 - s->inlen);
+			}
 #else
 			res = read(s->fd, s->inbuf + s->inlen, sizeof(s->inbuf) - 1 - s->inlen);
 #endif
@@ -1907,53 +1866,55 @@
 				ast_log(LOG_WARNING, "Failed to set manager tcp connection to TCP_NODELAY mode: %s\n", strerror(errno));
 			}
 		}
+		
+                s = malloc(sizeof(struct mansession));
+		if (!s) {
+			ast_log(LOG_WARNING, "Failed to allocate management session: %s\n", strerror(errno));
+			continue;
+		} 
+                
+		memset(s, 0, sizeof(struct mansession));
+		memcpy(&s->sin, &sin, sizeof(sin));
+		s->writetimeout = 100;
+		s->waiting_thread = AST_PTHREADT_NULL;
+
+		s->fd = as;
+
 #ifdef AMI_WITH_SSL
 		is_encrypted = is_encrypt_request(sslclhellotimeout, as);
 		if (is_encrypted > 0) {
 			if (!acceptencryptedconnection) {
 				ast_log(LOG_WARNING, "Accepting encrypted connection disabled, closing the connection \n");
-				close_sock(as);
+				close_sock(s);
+                                free(s);
                                 continue;
 			} else {
-                        	if((as = saccept(as)) >= 0 ) {
+                        	if(saccept(s) == -1 ) {
                                 	ast_log(LOG_WARNING, "Can't accept the ssl connection, since SSL init has failed for certificate reason\n");
-                                	close_sock(as);
+                                	close_sock(s);
+                                        free(s);
                                 	continue;
 				}
                         }
 		} else if (is_encrypted == -1) {
 		   	ast_log(LOG_ERROR, "SSL version 2 is unsecure, we don't support it\n");
-			close_sock(as);
+			close_sock(s);
+                        free(s);
 			continue;
 		}
 		if ( (! acceptunencryptedconnection) && (as >= 0)) {
 			ast_log(LOG_NOTICE, "Unencrypted connections are not accepted and we received an unencrypted connection request\n");
-			close_sock(as);
+			close_sock(s);
+                        free(s);
 			continue;
 		}
 #endif
-		s = malloc(sizeof(struct mansession));
-		if (!s) {
-			ast_log(LOG_WARNING, "Failed to allocate management session: %s\n", strerror(errno));
-			continue;
-		} 
-		memset(s, 0, sizeof(struct mansession));
-		memcpy(&s->sin, &sin, sizeof(sin));
-		s->writetimeout = 100;
-		s->waiting_thread = AST_PTHREADT_NULL;
-
 		if (!block_sockets) {
 			/* For safety, make sure socket is non-blocking */
-#ifdef AMI_WITH_SSL
-			flags = fcntl(get_real_fd(as), F_GETFL);
-			fcntl(get_real_fd(as), F_SETFL, flags | O_NONBLOCK);
-#else
 			flags = fcntl(as, F_GETFL);
 			fcntl(as, F_SETFL, flags | O_NONBLOCK);
-#endif
 		}
 		ast_mutex_init(&s->__lock);
-		s->fd = as;
 		s->send_events = -1;
 		ast_mutex_lock(&sessionlock);
 		num_sessions++;

Modified: team/group/ami_ssl/ssl_addon.c
URL: http://svn.digium.com/view/asterisk/team/group/ami_ssl/ssl_addon.c?rev=27679&r1=27678&r2=27679&view=diff
==============================================================================
--- team/group/ami_ssl/ssl_addon.c (original)
+++ team/group/ami_ssl/ssl_addon.c Wed May 17 01:08:07 2006
@@ -61,10 +61,9 @@
 #include "asterisk/options.h"
 #include "asterisk/config.h"
 #include "asterisk/ssl_addon.h"
+#include "asterisk/manager.h"
 
 SSL_CTX *sctx;
-static long rec_bytes;
-static long sent_bytes;
 static int ssl_initialized;
 
 
@@ -100,153 +99,42 @@
 	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 <SEC_MAX)
-	    		fd = sec_channel[fd].fd;
-		else fd = -1;
-
-	}
-	return fd;
-}
-
-/*! \brief    Returns the SSL pointer from the fd. This structure is filled when we accept 
- *     the ssl connection and used 
- *     for reading and writing through ssl.
-*/
-SSL *get_ssl(int fd)
-{
-	SSL *ssl = NULL;
-
-	fd = -fd - 2;
-
-	if (fd>=0 && fd <SEC_MAX)
-		ssl = sec_channel[fd].ssl;
-
-	return ssl;
-}
-
-/*! \brief    Returns the empty ssl slot. Used to save ssl information.
-*/
-int sec_getslot(void)
-{
-	int i;
-
-	for (i=0; i<SEC_MAX; i++) {
-		if(sec_channel[i].ssl==NULL)
-	    		break;
-	}
-
-	if (i==SEC_MAX)
+/*! \brief     Accepts the ssl connection.
+*/
+int saccept(void *vs)
+{
+	int fd, err;
+
+	struct mansession *s = (struct mansession *) vs;
+
+	if (!ssl_initialized)
 		return -1;
-	return i;
-}
-
-/*! \brief     Accepts the ssl connection. Retrurns the negative fd. negative fd's are 
- *	choosen to differentiate between ssl and non-ssl connections. positive 
- *	fd's are used for non-ssl connections and negative fd's are used for ssl 
- *	connections. So we purposefully calculate and return negative fds. 
- *	You can always get positive fd by calling get_real_fd(negative fd). 
- *	The positive fd's are required for system calls.
- *
-*/
-int saccept(int s)
-{
-	int fd, err;
-	SSL* ssl;
-
-	if (!ssl_initialized)
-		return s;
-
-	if (((fd=sec_getslot())!=-1))  {
-		ssl=SSL_new(sctx);
-		SSL_set_fd(ssl, s);
-		sec_channel[fd].ssl = ssl;	/* remember ssl */
-		sec_channel[fd].fd = s;		/* remember the real fd */
-		do {
-			err = SSL_accept(ssl);
-			err = SSL_get_error(ssl, err);
-		} while( err == SSL_ERROR_WANT_READ || err == SSL_ERROR_WANT_WRITE);
-
-		SSL_set_mode(ssl, SSL_MODE_ENABLE_PARTIAL_WRITE);
-		ast_log(LOG_DEBUG, "ssl_addon: Connection accepted");
-
-		err=1;
-
-		fd = -(fd+2);
-
-		if (err!=1 || !ssl) {
-		    /* it did not work */
-		    sec_channel[fd].ssl = NULL;	/* free the slot */
-		    fd = -1;
-		}
-	}
-	return fd;
-}
-
-/*!	
- * \brief Writes through secured ssl connection 
-*/
-int m_send(int fd, const void *data, size_t len)
-{
-	sent_bytes += len;
-
-	if (fd < -1) {
-		SSL* ssl = get_ssl(fd);
-		return SSL_write(ssl, data, len);
-	}
-	return write(fd, data, len);
-}
-
-/*!
- * \brief	Receives data from the SSL connection. 
-*/
-int m_recv(int s, void *buf, size_t len, int flags)
-{
-	int ret = 0;
-
-	if (s<-1) {
-		SSL* ssl = get_ssl(s);
-		ret = SSL_read (ssl, buf, len);
-	} else
-		ret = recv(s, buf, len, flags);
-
-	if (ret > 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);
+
+	s->ssl=SSL_new(sctx);
+	SSL_set_fd(s->ssl, s->fd);
+	do {
+		err = SSL_accept(s->ssl);
+		err = SSL_get_error(s->ssl, err);
+	} while( err == SSL_ERROR_WANT_READ || err == SSL_ERROR_WANT_WRITE);
+
+	SSL_set_mode(s->ssl, SSL_MODE_ENABLE_PARTIAL_WRITE);
+	ast_log(LOG_DEBUG, "ssl_addon: Connection accepted");
+
+	if (!s->ssl) 
+	    fd = -1; /* it did not work */
+	
+	return 0;
+}
+
+int close_sock(void *vs)
+{
+	int ret;
+	struct mansession *s = (struct mansession *) vs;
+
+	ret = close(s->fd);
+
+	if(s->ssl)
+		SSL_free (s->ssl);
 
 	return(ret);
 }

Modified: team/group/ami_ssl/utils.c
URL: http://svn.digium.com/view/asterisk/team/group/ami_ssl/utils.c?rev=27679&r1=27678&r2=27679&view=diff
==============================================================================
--- team/group/ami_ssl/utils.c (original)
+++ team/group/ami_ssl/utils.c Wed May 17 01:08:07 2006
@@ -47,6 +47,11 @@
 #include "asterisk/sha1.h"
 #include "asterisk/options.h"
 #include "asterisk/compat.h"
+
+#ifdef AMI_WITH_SSL
+#include "asterisk/ssl_addon.h"
+#include "asterisk/manager.h"
+#endif
 
 #define AST_API_MODULE		/* ensure that inlinable API functions will be built in this module if required */
 #include "asterisk/strings.h"
@@ -591,14 +596,27 @@
 	return poll(pfd, 1, ms);
 }
 
-int ast_carefulwrite(int fd, char *s, int len, int timeoutms) 
+int ast_carefulwrite(int fd, char *s, int len, int timeoutms, void *vs) 
 {
 	/* Try to write string, but wait no more than ms milliseconds
 	   before timing out */
 	int res = 0;
 	struct pollfd fds[1];
+#if AMI_WITH_SSL
+	struct mansession *ms = (struct mansession *)vs;
+
+	if(ms) fd = ms->fd;
+#endif
+
 	while (len) {
+#if AMI_WITH_SSL
+		if (ms->ssl)
+			res = SSL_write(ms->ssl, s, len);
+		else
+			res = write(ms->fd, s, len);
+#else
 		res = write(fd, s, len);
+#endif
 		if ((res < 0) && (errno != EAGAIN)) {
 			return -1;
 		}



More information about the svn-commits mailing list