tls_domain.c

Go to the documentation of this file.
00001 /*
00002  * $Id: tls_domain.c 4680 2008-08-12 07:26:43Z klaus_darilion $
00003  *
00004  * Copyright (C) 2001-2003 FhG Fokus
00005  * Copyright (C) 2004,2005 Free Software Foundation, Inc.
00006  * Copyright (C) 2006 enum.at
00007  *
00008  * This file is part of Kamailio, a free SIP server.
00009  *
00010  * Kamailio is free software; you can redistribute it and/or modify
00011  * it under the terms of the GNU General Public License as published by
00012  * the Free Software Foundation; either version 2 of the License, or
00013  * (at your option) any later version
00014  *
00015  * Kamailio is distributed in the hope that it will be useful,
00016  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00017  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00018  * GNU General Public License for more details.
00019  *
00020  * You should have received a copy of the GNU General Public License 
00021  * along with this program; if not, write to the Free Software 
00022  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00023  */
00024 
00025 /*!
00026  * \file
00027  * \brief Kamailio TLS support :: Domains
00028  * \ingroup tls
00029  * Module: \ref tls
00030  */
00031 
00032 #include "tls_server.h"
00033 #include "tls_domain.h"
00034 #include <stdlib.h>
00035 
00036 struct tls_domain *tls_server_domains = NULL;
00037 struct tls_domain *tls_client_domains = NULL;
00038 struct tls_domain *tls_default_server_domain = NULL;
00039 struct tls_domain *tls_default_client_domain = NULL;
00040 
00041 /*! \brief
00042  * find server domain with given ip and port 
00043  * it will only return server domains which do not
00044  * have a server_name defined (as to those will be swtiched
00045  * in the servername callback function).
00046  * If IP:port with empty server_name is not found in the list 
00047  * it will return the default server domain
00048  * \return default domain if virtual domain not found
00049  */
00050 struct tls_domain *
00051 tls_find_server_domain(struct ip_addr *ip, unsigned short port)
00052 {
00053    struct tls_domain *p = tls_server_domains;
00054    while (p) {
00055       if ((p->port == port) && ip_addr_cmp(&p->addr, ip)
00056 #ifndef OPENSSL_NO_TLSEXT
00057          && (p->server_name == NULL)
00058 #endif
00059          ) {
00060          LM_DBG("socket based TLS server domain found\n");
00061          return p;
00062       }
00063       p = p->next;
00064    }
00065    LM_DBG("socket based TLS server domain not found, "
00066       "Using default TLS server domain settings\n");
00067    return tls_default_server_domain;
00068 }
00069 
00070 
00071 #ifndef OPENSSL_NO_TLSEXT
00072 /*
00073  * find server domain with given ip and port 
00074  * and matching server_name.
00075  * If none is found, it will return 0
00076  */
00077 struct tls_domain *
00078 tls_find_server_domain_server_name(struct ip_addr *ip, 
00079    unsigned short port, const char *server_name)
00080 {
00081    struct tls_domain *p = tls_server_domains;
00082    LM_DBG("looking up TLS server domain for socket [%s:%d] and "
00083       "server_name '%s' ...\n", ip_addr2a(ip), port, server_name);
00084    while (p) {
00085       LM_DBG("comparing with TLS server domain [%s:%d] and "
00086          "server_name %p:'%s' ...\n", ip_addr2a(&p->addr), p->port, 
00087          p->server_name, p->server_name?p->server_name:"");
00088       if ((p->port == port) && ip_addr_cmp(&p->addr, ip) && p->server_name
00089          && !strcasecmp(p->server_name,server_name)) {
00090          LM_DBG("socket+server_name based TLS server domain found\n");
00091          return p;
00092       }
00093       p = p->next;
00094    }
00095    LM_DBG("socket+server_name based TLS server domain not found\n");
00096    return 0;
00097 }
00098 #endif
00099 
00100 
00101 /*! \brief
00102  * find client domain with given ip and port,
00103  * return default domain if virtual domain not found
00104  */
00105 struct tls_domain *
00106 tls_find_client_domain(struct ip_addr *ip, unsigned short port)
00107 {
00108    struct tls_domain *p = tls_client_domains;
00109    while (p) {
00110       if ((p->name.len == 0) && (p->port == port) && ip_addr_cmp(&p->addr, ip)) {
00111          LM_DBG("virtual TLS client domain found\n");
00112          return p;
00113       }
00114       p = p->next;
00115    }
00116    LM_DBG("virtual TLS client domain not found, "
00117       "Using default TLS client domain settings\n");
00118    return tls_default_client_domain;
00119 }
00120 
00121 /*! \brief
00122  * find client domain with given name,
00123  * return 0 if name based virtual domain not found
00124  */
00125 struct tls_domain *
00126 tls_find_client_domain_name(str name)
00127 {
00128    struct tls_domain *p = tls_client_domains;
00129    while (p) {
00130       if ((p->name.len == name.len) && !strncasecmp(p->name.s, name.s, name.len)) {
00131          LM_DBG("virtual TLS client domain found\n");
00132          return p;
00133       }
00134       p = p->next;
00135    }
00136    LM_DBG("virtual TLS client domain not found\n");
00137    return 0;
00138 }
00139 
00140 
00141 /*! \brief
00142  * create a new server domain (identified by a socket)
00143  */
00144 int
00145 tls_new_server_domain(struct ip_addr *ip, unsigned short port)
00146 {
00147    struct tls_domain *d = tls_server_domains;
00148 
00149    LM_DBG("creating server domain for [%s:%d]\n", 
00150       ip_addr2a(ip), port);
00151    // check if for this socket is already a domain defined
00152    while (d) {
00153       if ((d->port == port) && ip_addr_cmp(&d->addr, ip)) {
00154 #ifdef OPENSSL_NO_TLSEXT
00155          LM_ERR("TLS server domain for socket [%s:%d] already defined\n",
00156             ip_addr2a(ip), port);
00157          return -1;
00158 #else
00159          LM_WARN("TLS server domain for socket [%s:%d] already defined\n",
00160             ip_addr2a(ip), port);
00161 #endif
00162       }
00163       d = d->next;
00164    }
00165    LM_DBG("creating a new TLS server domain ...\n");
00166 
00167    d = tls_new_domain(TLS_DOMAIN_SRV);
00168    if (d == NULL) {
00169       LM_ERR("pkg memory allocation failure\n");
00170       return -1;
00171    }
00172 
00173    /* fill socket data */
00174    memcpy(&d->addr, ip, sizeof(struct ip_addr));
00175    d->port = port;
00176 
00177    /* add this new domain to the linked list */
00178    d->next = tls_server_domains;
00179    tls_server_domains = d;
00180    return 0;
00181 }
00182 
00183 /*! \brief
00184  * create a new client domain (identified by a socket)
00185  */
00186 int
00187 tls_new_client_domain(struct ip_addr *ip, unsigned short port)
00188 {
00189    struct tls_domain *d;
00190 
00191    d = tls_new_domain(TLS_DOMAIN_CLI);
00192    if (d == NULL) {
00193       LM_ERR("pkg memory allocation failure\n");
00194       return -1;
00195    }
00196 
00197    /* fill socket data */
00198    memcpy(&d->addr, ip, sizeof(struct ip_addr));
00199    d->port = port;
00200 
00201    /* add this new domain to the linked list */
00202    d->next = tls_client_domains;
00203    tls_client_domains = d;
00204    return 0;
00205 }
00206 
00207 /*! \brief
00208  * create a new client domain (identified by a string)
00209  */
00210 int
00211 tls_new_client_domain_name(char *s, int len)
00212 {
00213    struct tls_domain *d;
00214 
00215    d = tls_new_domain(TLS_DOMAIN_CLI | TLS_DOMAIN_NAME);
00216    if (d == NULL) {
00217       LM_ERR("pkg memory allocation failure\n");
00218       return -1;
00219    }
00220 
00221    /* initialize name data */
00222    d->name.s = pkg_malloc(len);
00223    if (d->name.s == NULL) {
00224       LM_ERR("pkg memory allocation failure\n");
00225       pkg_free(d);
00226       return -1;
00227    }
00228    memcpy(d->name.s, s, len);
00229    d->name.len = len;
00230 
00231    /* add this new domain to the linked list */
00232    d->next = tls_client_domains;
00233    tls_client_domains = d;
00234    return 0;
00235 }
00236 
00237 /*! \brief
00238  * allocate memory and set default values for
00239  * TLS domain structure
00240  */
00241 struct tls_domain *tls_new_domain(int type)
00242 {
00243    struct tls_domain *d;
00244 
00245    d = pkg_malloc(sizeof(struct tls_domain));
00246    if (d == NULL) {
00247       LM_ERR("pkg memory allocation failure\n");
00248       return 0;
00249    }
00250    memset( d, 0, sizeof(struct tls_domain));
00251 
00252    d->type = type;
00253 
00254    if (type & TLS_DOMAIN_SRV) {
00255       d->verify_cert         = tls_verify_client_cert;
00256       d->require_client_cert = tls_require_client_cert;
00257    } else {
00258       d->verify_cert         = tls_verify_server_cert;
00259       d->require_client_cert = 0;
00260    }
00261    d->method = TLS_METHOD_UNSPEC;
00262 
00263    return d;
00264 }
00265 
00266 /*! \brief
00267  * clean up 
00268  */
00269 void
00270 tls_free_domains(void)
00271 {
00272    struct tls_domain *p;
00273    while (tls_server_domains) {
00274       p = tls_server_domains;
00275       tls_server_domains = tls_server_domains->next;
00276       pkg_free(p);
00277    }
00278    while (tls_client_domains) {
00279       p = tls_client_domains;
00280       tls_client_domains = tls_client_domains->next;
00281       /* ToDo: If socket based client domains will be implemented, the name may
00282          be empty (must be set to NULL manually). Thus no need to free it */
00283       if (p->name.s) {
00284          pkg_free(p->name.s);
00285       }
00286       pkg_free(p);
00287    }
00288    pkg_free(tls_default_client_domain);
00289    pkg_free(tls_default_server_domain);
00290 }
00291 

Generated on Thu May 24 20:00:33 2012 for Kamailio - The Open Source SIP Server by  doxygen 1.5.6