diff options
Diffstat (limited to 'src/ssl.c')
-rw-r--r-- | src/ssl.c | 81 |
1 files changed, 79 insertions, 2 deletions
@@ -39,7 +39,6 @@ You must check for (value==-1) instead, since all other negative fd's now are valid fd's. */ -#ifdef AMI_WITH_SSL #include <sys/types.h> #include <string.h> #include <unistd.h> @@ -58,6 +57,7 @@ #include "ssl.h" SSL_CTX *sctx; +SSL_CTX *cctx; static long rec_bytes; static long sent_bytes; static int ssl_initialized; @@ -95,6 +95,25 @@ int init_secure(char *certfile) return 0; } + +/* Initializes all the client-side ssl related stuff here. +*/ +int client_init_secure(void) +{ + SSL_METHOD *meth; + + /* client init */ + SSLeay_add_ssl_algorithms(); + meth = SSLv23_client_method(); + SSL_load_error_strings(); + cctx = SSL_CTX_new (meth); + + if (!cctx) { + fprintf(stderr, "Failed to create a client ssl context!\n"); + } + 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. */ @@ -307,4 +326,62 @@ int is_encrypt_request(int sslclhellotimeout, int fd) } return 0; } -#endif + + +/* Connects to an asterisk server either plain or SSL as appropriate +*/ +int ast_connect(struct mansession *a) { + int s, err=-1, fd; + SSL* ssl; + + fd = connect_nonb(a); + if ( fd < 0 ) + return -1; + + if (a->server->use_ssl) { + if ((s=sec_getslot())!=-1) { /* find a slot for the ssl handle */ + sec_channel[s].fd = fd; /* remember the real fd */ + + if((ssl=SSL_new(cctx))) { /* get a new ssl */ + sec_channel[s].ssl = ssl; + SSL_set_fd(ssl, fd); /* and attach the real fd */ + err = SSL_connect(ssl); /* now try and connect */ + } + fd = -(s+2); /* offset by two and negate */ + /* this tells us it is a ssl fd */ + } + + if (err==-1) { + close_sock(fd); /* that frees the ssl too */ + fd = -1; + } + } + + pthread_mutex_lock(&a->lock); + a->fd = fd; + pthread_mutex_unlock(&a->lock); + + return fd; +} + +int connect_nonb(struct mansession *a) +{ + int s, flags, one=1; + + s = get_real_fd(a->fd); + + flags = fcntl(s, F_GETFL, 0); + fcntl(s, F_SETFL, flags | O_NONBLOCK); + + if (setsockopt(s, SOL_SOCKET, SO_REUSEADDR, (char *)&one, sizeof(one))==-1) { + (void)close(s); + return -1; + } + + if (connect(s, (struct sockaddr *) &a->sin, sizeof(a->sin)) < 0) { + if (errno != EINPROGRESS) + return -1; + } + return s; +} + |