[asterisk-commits] branch group/ami_ssl r27679 - in
/team/group/ami_ssl: ./ include/asterisk/
asterisk-commits at lists.digium.com
asterisk-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 asterisk-commits
mailing list