/*
* $Id: tls_domain.c 1264 2006-11-23 15:02:14Z klaus_darilion $
*
* Copyright (C) 2001-2003 FhG Fokus
* Copyright (C) 2004,2005 Free Software Foundation, Inc.
* Copyright (C) 2006 enum.at
*
* This file is part of openser, a free SIP server.
*
* openser is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version
*
* openser is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "tls_server.h"
#include "tls_domain.h"
#include <stdlib.h>
struct tls_domain *tls_server_domains = NULL;
struct tls_domain *tls_client_domains = NULL;
struct tls_domain *tls_default_server_domain = NULL;
struct tls_domain *tls_default_client_domain = NULL;
/*
* find server domain with given ip and port
* return default domain if virtual domain not found
*/
struct tls_domain *
tls_find_server_domain(struct ip_addr *ip, unsigned short port)
{
struct tls_domain *p = tls_server_domains;
while (p) {
if ((p->port == port) && ip_addr_cmp(&p->addr, ip)) {
DBG("tls_find_server_domain: virtual TLS server domain found\n");
return p;
}
p = p->next;
}
DBG("tls_find_server_domain: virtual TLS server domain not found, "
"Using default TLS server domain settings\n");
return tls_default_server_domain;
}
/*
* find client domain with given ip and port,
* return default domain if virtual domain not found
*/
struct tls_domain *
tls_find_client_domain(struct ip_addr *ip, unsigned short port)
{
struct tls_domain *p = tls_client_domains;
while (p) {
if ((p->name.len == 0) && (p->port == port) && ip_addr_cmp(&p->addr, ip)) {
DBG("tls_find_client_domain: virtual TLS client domain found\n");
return p;
}
p = p->next;
}
DBG("tls_find_client_domain: virtual TLS client domain not found, "
"Using default TLS client domain settings\n");
return tls_default_client_domain;
}
/*
* find client domain with given name,
* return 0 if name based virtual domain not found
*/
struct tls_domain *
tls_find_client_domain_name(str name)
{
struct tls_domain *p = tls_client_domains;
while (p) {
if ((p->name.len == name.len) && !strncasecmp(p->name.s, name.s, name.len)) {
DBG("tls_find_client_domain_name: virtual TLS client domain found\n");
return p;
}
p = p->next;
}
DBG("tls_find_client_domain_name: virtual TLS client domain not found\n");
return 0;
}
/*
* create a new server domain (identified by a socket)
*/
int
tls_new_server_domain(struct ip_addr *ip, unsigned short port)
{
struct tls_domain *d;
d = tls_new_domain(TLS_DOMAIN_SRV);
if (d == NULL) {
LOG(L_ERR, "tls_new_server_domain: Memory allocation failure\n");
return -1;
}
/* fill socket data */
memcpy(&d->addr, ip, sizeof(struct ip_addr));
d->port = port;
/* add this new domain to the linked list */
d->next = tls_server_domains;
tls_server_domains = d;
return 0;
}
/*
* create a new client domain (identified by a socket)
*/
int
tls_new_client_domain(struct ip_addr *ip, unsigned short port)
{
struct tls_domain *d;
d = tls_new_domain(TLS_DOMAIN_CLI);
if (d == NULL) {
LOG(L_ERR, "tls_new_client_domain: Memory allocation failure\n");
return -1;
}
/* fill socket data */
memcpy(&d->addr, ip, sizeof(struct ip_addr));
d->port = port;
/* add this new domain to the linked list */
d->next = tls_client_domains;
tls_client_domains = d;
return 0;
}
/*
* create a new client domain (identified by a string)
*/
int
tls_new_client_domain_name(char *s, int len)
{
struct tls_domain *d;
d = tls_new_domain(TLS_DOMAIN_CLI | TLS_DOMAIN_NAME);
if (d == NULL) {
LOG(L_ERR, "tls_new_client_domain: Memory allocation failure\n");
return -1;
}
/* initialize name data */
d->name.s = pkg_malloc(len);
if (d->name.s == NULL) {
LOG(L_ERR, "tls_new_client_domain: Memory allocation failure for domain name\n");
pkg_free(d);
return -1;
}
memcpy(d->name.s, s, len);
d->name.len = len;
/* add this new domain to the linked list */
d->next = tls_client_domains;
tls_client_domains = d;
return 0;
}
/*
* allocate memory and set default values for
* TLS domain structure
*/
struct tls_domain *tls_new_domain(int type)
{
struct tls_domain *d;
d = pkg_malloc(sizeof(struct tls_domain));
if (d == NULL) {
LOG(L_ERR,"ERROR:tls:pre_init_tls_domain: memory allocation failed\n");
return 0;
}
memset( d, 0, sizeof(struct tls_domain));
d->type = type;
if (type & TLS_DOMAIN_SRV) {
d->verify_cert = tls_verify_client_cert;
d->require_client_cert = tls_require_client_cert;
} else {
d->verify_cert = tls_verify_server_cert;
d->require_client_cert = 0;
}
d->method = TLS_METHOD_UNSPEC;
return d;
}
/*
* clean up
*/
void
tls_free_domains(void)
{
struct tls_domain *p;
while (tls_server_domains) {
p = tls_server_domains;
tls_server_domains = tls_server_domains->next;
pkg_free(p);
}
while (tls_client_domains) {
p = tls_client_domains;
tls_client_domains = tls_client_domains->next;
/* ToDo: If socket based client domains will be implemented, the name may
be empty (must be set to NULL manually). Thus no need to free it */
if (p->name.s) {
pkg_free(p->name.s);
}
pkg_free(p);
}
pkg_free(tls_default_client_domain);
pkg_free(tls_default_server_domain);
}
syntax highlighted by Code2HTML, v. 0.9.1