浏览代码

- preliminary tls support
- added qm_realloc/pkg_realloc/shm_realloc (needed by libssl)

Andrei Pelinescu-Onciul 22 年之前
父节点
当前提交
f22b996bef
共有 9 个文件被更改,包括 634 次插入67 次删除
  1. 19 4
      Makefile.defs
  2. 6 1
      config.h
  3. 81 24
      main.c
  4. 3 0
      mem/mem.h
  5. 173 32
      mem/q_malloc.c
  6. 6 0
      mem/q_malloc.h
  7. 35 6
      mem/shm_mem.h
  8. 244 0
      tls_init.c
  9. 67 0
      tls_init.h

+ 19 - 4
Makefile.defs

@@ -26,6 +26,7 @@
 #  2003-06-06  moved compiler detection before DEFS (andrei)
 #  2003-06-10  removed -m32 for gcc 3.x/sparc64  -- it will use 
 #              arch. default: -m32 on solaris, -m64 on *bsd (andrei)
+#  2003-06-29  added TLS support: TLS=1 (andrei)
 
 
 # check if already included/exported
@@ -39,14 +40,16 @@ export makefile_defs
 #version number
 VERSION = 0
 PATCHLEVEL = 8
-SUBLEVEL =   11
-EXTRAVERSION = dev34
+SUBLEVEL =   12
+EXTRAVERSION = dev-tls01
 
 RELEASE=$(VERSION).$(PATCHLEVEL).$(SUBLEVEL)$(EXTRAVERSION)
 OS = $(shell uname -s | sed -e s/SunOS/solaris/ | tr "[A-Z]" "[a-z]")
 ARCH = $(shell uname -m |sed -e s/i.86/i386/ -e s/sun4u/sparc64/  \
 			-e s/armv4l/arm/)
 
+# TLS support
+TLS ?=
 # extra CC command line options (e.g  -march=athlon-mp)
 CC_EXTRA_OPTS ?=
  # install location
@@ -251,10 +254,12 @@ endif
 #  		forking (done at the top of main_loop). Needed if you want
 #  		to use the snmp module.
 # -DUSE_TCP
-#		compiles in tcp support (highly experimental for now, it will probably
-#		not work, use it only if you really now what you are doing)
+#		compiles in tcp support
 # -DDISABLE_NAGLE
 #		disable the tcp Nagle algorithm (lower delay)
+# -DUSE_TLS
+#		compiles in tls support, requires -DUSE_TCP. Please use
+#		make TLS=1 instead. (tls support is highly experimental for now)
 
 
 DEFS+= $(extra_defs) \
@@ -289,6 +294,11 @@ DEFS+= $(extra_defs) \
 # WARNING: do not add mode=debug or mode=release anymore in the Makefile,
 # use make mode=debug all instead. Anyway no by default ser is  compiled w/ 
 # debugging symbols in all cases (-g). --andrei
+
+ifneq ($(TLS),)
+	DEFS+= -DUSE_TLS
+endif
+
 ifeq ($(mode),)
 	mode = release
 endif
@@ -675,6 +685,11 @@ ifneq (,$(findstring CYGWIN, $(OS)))
 	endif
 endif
 
+#add libssl if needed
+ifneq ($(TLS),)
+LIBS+= -lssl
+endif
+
 ifneq ($(found_lock_method), yes)
 $(warning	No locking method found so far, trying SYS V sems)
 		DEFS+= -DUSE_SYSV_SEM  # try sys v sems

+ 6 - 1
config.h

@@ -38,10 +38,15 @@
 #include "types.h"
 
 /* default sip port if none specified */
-#define SIP_PORT 5060
+#define SIP_PORT  5060
+#define SIPS_PORT 5061
 
 #define CFG_FILE CFG_DIR "ser.cfg"
 
+#define TLS_PKEY_FILE CFG_DIR "cert.pem" 
+#define TLS_CERT_FILE CFG_DIR "cert.pem"
+#define TLS_CA_FILE 0 /* no CA list file by default */
+
 
 /* maximum number of addresses on which we will listen */
 #define MAX_LISTEN 16

+ 81 - 24
main.c

@@ -40,6 +40,8 @@
  *               after daemonize (so that we won't catch anymore our own
  *               SIGCHLD generated when becoming session leader) (andrei)
  *              changed is_main default value to 1 (andrei)
+ *  2003-06-29  preliminary tls support (andrei)
+ *              replaced port_no_str snprintf w/ int2str (andrei)
  *
  */
 
@@ -92,9 +94,14 @@
 #include "hash_func.h"
 #include "pt.h"
 #include "script_cb.h"
+#include "ut.h"
 #ifdef USE_TCP
 #include "tcp_init.h"
+#ifdef USE_TLS
+#include "tls_init.h"
 #endif
+#endif
+
 
 
 #include "stats.h"
@@ -119,6 +126,9 @@ static char flags[]=
 #ifdef USE_TCP
 ", USE_TCP"
 #endif
+#ifdef USE_TLS
+", USE_TLS"
+#endif
 #ifdef DISABLE_NAGLE
 ", DISABLE_NAGLE"
 #endif
@@ -267,6 +277,9 @@ int children_no = 0;			/* number of children processing requests */
 int tcp_children_no = 0;
 int tcp_disable = 0; /* 1 if tcp is disabled */
 #endif
+#ifdef USE_TLS
+int tls_disable = 0; /* 1 if tls is disabled */
+#endif
 struct process_table *pt=0;		/*array with childrens pids, 0= main proc,
 									alloc'ed in shared mem if possible*/
 int sig_flag = 0;              /* last signal received */
@@ -315,6 +328,9 @@ struct socket_info sock_info[MAX_LISTEN];/*all addresses we listen/send from*/
 #ifdef USE_TCP
 struct socket_info tcp_info[MAX_LISTEN];/*all tcp addresses we listen on*/
 #endif
+#ifdef USE_TLS
+struct socket_info tls_info[MAX_LISTEN]; /* all tls addresses we listen on*/
+#endif
 int sock_no=0; /* number of addresses/open sockets*/
 struct socket_info* bind_address=0; /* pointer to the crt. proc.
 									 listening address*/
@@ -325,8 +341,15 @@ struct socket_info* sendipv6; /* same as above for ipv6 */
 struct socket_info* sendipv4_tcp; 
 struct socket_info* sendipv6_tcp; 
 #endif
+#ifdef USE_TLS
+struct socket_info* sendipv4_tls;
+struct socket_info* sendipv6_tls;
+#endif
 
 unsigned short port_no=0; /* default port*/
+#ifdef USE_TLS
+unsigned short tls_port_no=0; /* default port */
+#endif
 
 struct host_alias* aliases=0; /* name aliases list */
 
@@ -367,6 +390,9 @@ void cleanup(show_status)
 	destroy_modules();
 #ifdef USE_TCP
 	destroy_tcp();
+#endif
+#ifdef USE_TLS
+	destroy_tls();
 #endif
 	destroy_timer();
 	destroy_fifo();
@@ -702,6 +728,10 @@ int main_loop()
 #ifdef USE_TCP
 	int sockfd[2];
 #endif
+#ifdef USE_TLS
+	char* tmp;
+	int len;
+#endif
 		
 
 	/* one "main" process and n children handling i/o */
@@ -818,7 +848,36 @@ int main_loop()
 					sendipv6_tcp=&tcp_info[r];
 		#endif
 			}
-#endif
+#ifdef USE_TLS
+			if (!tls_disable){
+				tls_info[r]=sock_info[r]; /* copy the sockets */
+				/* fix the port number -- there is no way so far to set-up
+				 * individual tls port numbers */
+				tls_info[r].port_no=tls_port_no; /* FIXME: */
+				tmp=int2str(tls_info[r].port_no, &len);
+				/* we don't need to free the previous content, is uesd
+				 * by tcp & udp! */
+				tls_info[r].port_no_str.s=(char*)pkg_malloc(len+1);
+				if (tls_info[r].port_no_str.s==0){
+					LOG(L_CRIT, "memory allocation failure\n");
+					goto error;
+				}
+				strncpy(tls_info[r].port_no_str.s, tmp, len+1);
+				tls_info[r].port_no_str.len=len;
+				
+				/* same as for tcp*/
+				if (tls_init(&tls_info[r])==-1)  goto error;
+				/* get first ipv4/ipv6 socket*/
+				if ((tls_info[r].address.af==AF_INET)&&
+						((sendipv4_tls==0)||(sendipv4_tls->is_lo)))
+					sendipv4_tls=&tls_info[r];
+		#ifdef USE_IPV6
+				if((sendipv6_tls==0)&&(tls_info[r].address.af==AF_INET6))
+					sendipv6_tls=&tls_info[r];
+		#endif
+			}
+#endif /* USE_TLS */
+#endif /* USE_TCP */
 			/* all procs should have access to all the sockets (for sending)
 			 * so we open all first*/
 		}
@@ -942,9 +1001,9 @@ int main_loop()
 	}
 #ifdef USE_TCP
 		if (!tcp_disable){
-				/* start tcp receivers */
+				/* start tcp  & tls receivers */
 			if (tcp_init_children()<0) goto error;
-				/* start tcp master proc */
+				/* start tcp+tls master proc */
 			process_no++;
 			if ((pid=fork())<0){
 				LOG(L_CRIT, "main_loop: cannot fork tcp main process\n");
@@ -1147,8 +1206,7 @@ int main(int argc, char** argv)
 	struct host_alias* a;
 	struct utsname myname;
 	char *options;
-	char port_no_str[MAX_PORT_LEN];
-	int port_no_str_len;
+	int len;
 	int ret;
 	struct passwd *pw_entry;
 	struct group  *gr_entry;
@@ -1156,7 +1214,6 @@ int main(int argc, char** argv)
 	int rfd;
 
 	/*init*/
-	port_no_str_len=0;
 	ret=-1;
 	my_argc=argc; my_argv=argv;
 	
@@ -1402,6 +1459,9 @@ try_again:
 	
 	/* fix parameters */
 	if (port_no<=0) port_no=SIP_PORT;
+#ifdef USE_TLS
+	if (tls_port_no<=0) tls_port_no=SIPS_PORT;
+#endif
 	
 	
 	if (children_no<=0) children_no=CHILD_NO;
@@ -1483,31 +1543,19 @@ try_again:
 	for (r=0; r<sock_no;r++){
 		/* fix port number, port_no should be !=0 here */
 		if (sock_info[r].port_no==0) sock_info[r].port_no=port_no;
-		port_no_str_len=snprintf(port_no_str, MAX_PORT_LEN, "%d", 
-									(unsigned short) sock_info[r].port_no);
-		/* if buffer too small, snprintf may return per C99 estimated size
-		   of needed space; there is no guarantee how many characters 
-		   have been written to the buffer and we can be happy if
-		   the snprintf implementation zero-terminates whatever it wrote
-		   -jku
-		*/
-		if (port_no_str_len<0 || port_no_str_len>=MAX_PORT_LEN){
+		tmp=int2str(sock_info[r].port_no, &len);
+		if (len>=MAX_PORT_LEN){
 			fprintf(stderr, "ERROR: bad port number: %d\n", 
 						sock_info[r].port_no);
 			goto error;
 		}
-		/* on some systems snprintf returns really strange things if it does 
-		  not have  enough space */
-		port_no_str_len=
-				(port_no_str_len<MAX_PORT_LEN)?port_no_str_len:MAX_PORT_LEN;
-		sock_info[r].port_no_str.s=(char*)pkg_malloc(strlen(port_no_str)+1);
+		sock_info[r].port_no_str.s=(char*)pkg_malloc(len+1);
 		if (sock_info[r].port_no_str.s==0){
 			fprintf(stderr, "Out of memory.\n");
 			goto error;
 		}
-		strncpy(sock_info[r].port_no_str.s, port_no_str,
-					strlen(port_no_str)+1);
-		sock_info[r].port_no_str.len=strlen(port_no_str);
+		strncpy(sock_info[r].port_no_str.s, tmp, len+1);
+		sock_info[r].port_no_str.len=len;
 		
 		/* get "official hostnames", all the aliases etc. */
 		he=resolvehost(sock_info[r].name.s);
@@ -1643,7 +1691,16 @@ try_again:
 			goto error;
 		}
 	}
-#endif
+#ifdef USE_TLS
+	if (!tls_disable){
+		/* init tls*/
+		if (init_tls()<0){
+			LOG(L_CRIT, "could not initialize tls, exiting...\n");
+			goto error;
+		}
+	}
+#endif /* USE_TLS */
+#endif /* USE_TCP */
 	/* init_daemon? */
 	if (!dont_fork){
 		if ( daemonize(argv[0]) <0 ) goto error;

+ 3 - 0
mem/mem.h

@@ -74,6 +74,8 @@
 #		else
 #			define pkg_malloc(s) qm_malloc(mem_block, (s),__FILE__, \
 				__FUNCTION__, __LINE__)
+#			define pkg_realloc(p, s) qm_realloc(mem_block, (p), (s),__FILE__, \
+				__FUNCTION__, __LINE__)
 #			define pkg_free(p)   qm_free(mem_block, (p), __FILE__,  \
 				__FUNCTION__, __LINE__)
 #		endif
@@ -86,6 +88,7 @@
 #			define pkg_free(p)   fm_free(mem_block, (p))
 #		else
 #			define pkg_malloc(s) qm_malloc(mem_block, (s))
+#			define pkg_realloc(p, s) qm_realloc(mem_block, (p), (s))
 #			define pkg_free(p)   qm_free(mem_block, (p))
 #		endif
 #	endif

+ 173 - 32
mem/q_malloc.c

@@ -29,6 +29,7 @@
  * --------
  *  ????-??-??  created by andrei
  *  2003-04-14  more debugging added in DBG_QM_MALLOC mode (andrei)
+ *  2003-06-29  added qm_realloc (andrei)
  */
 
 
@@ -266,6 +267,49 @@ static inline struct qm_frag* qm_find_free(struct qm_block* qm,
 }
 
 
+/* returns 0 on success, -1 on error;
+ * new_size < size & rounduped already!*/
+static inline
+#ifdef DBG_QM_MALLOC
+int split_frag(struct qm_block* qm, struct qm_frag* f, unsigned int new_size,
+				char* file, char* func, unsigned int line)
+#else
+int split_frag(struct qm_block* qm, struct qm_frag* f, unsigned int new_size)
+#endif
+{
+	unsigned int rest;
+	struct qm_frag* n;
+	struct qm_frag_end* end;
+	
+	rest=f->size-new_size;
+	if (rest>(FRAG_OVERHEAD+MIN_FRAG_SIZE)){
+		f->size=new_size;
+		/*split the fragment*/
+		end=FRAG_END(f);
+		end->size=new_size;
+		n=(struct qm_frag*)((char*)end+sizeof(struct qm_frag_end));
+		n->size=rest-FRAG_OVERHEAD;
+		FRAG_END(n)->size=n->size;
+		qm->real_used+=FRAG_OVERHEAD;
+#ifdef DBG_QM_MALLOC
+		end->check1=END_CHECK_PATTERN1;
+		end->check2=END_CHECK_PATTERN2;
+		/* frag created by malloc, mark it*/
+		n->file=file;
+		n->func=func;
+		n->line=line;
+		n->check=ST_CHECK_PATTERN;
+#endif
+		/* reinsert n in free list*/
+		qm_insert_free(qm, n);
+		return 0;
+	}else{
+			/* we cannot split this fragment any more */
+		return -1;
+	}
+}
+
+
 
 #ifdef DBG_QM_MALLOC
 void* qm_malloc(struct qm_block* qm, unsigned int size, char* file, char* func,
@@ -275,9 +319,6 @@ void* qm_malloc(struct qm_block* qm, unsigned int size)
 #endif
 {
 	struct qm_frag* f;
-	struct qm_frag_end* end;
-	struct qm_frag* n;
-	unsigned int rest;
 	
 #ifdef DBG_QM_MALLOC
 	unsigned int list_cntr;
@@ -304,34 +345,12 @@ void* qm_malloc(struct qm_block* qm, unsigned int size)
 		qm_detach_free(qm, f);
 		/*mark it as "busy"*/
 		f->u.is_free=0;
-		
-		/*see if we'll use full frag, or we'll split it in 2*/
-		rest=f->size-size;
-		if (rest>(FRAG_OVERHEAD+MIN_FRAG_SIZE)){
-			f->size=size;
-			/*split the fragment*/
-			end=FRAG_END(f);
-			end->size=size;
-			n=(struct qm_frag*)((char*)end+sizeof(struct qm_frag_end));
-			n->size=rest-FRAG_OVERHEAD;
-			FRAG_END(n)->size=n->size;
-			qm->real_used+=FRAG_OVERHEAD;
+		/* we ignore split return */
 #ifdef DBG_QM_MALLOC
-			end->check1=END_CHECK_PATTERN1;
-			end->check2=END_CHECK_PATTERN2;
-			/* frag created by malloc, mark it*/
-			n->file=file;
-			n->func="frag. from qm_malloc";
-			n->line=line;
-			n->check=ST_CHECK_PATTERN;
-/*			FRAG_END(n)->check1=END_CHECK_PATTERN1;
-			FRAG_END(n)->check2=END_CHECK_PATTERN2; */
+		split_frag(qm, f, size, file, "fragm. from qm_malloc", line);
+#else
+		split_frag(qm, f, size);
 #endif
-			/* reinsert n in free list*/
-			qm_insert_free(qm, n);
-		}else{
-			/* we cannot split this fragment any more => alloc all of it*/
-		}
 		qm->real_used+=f->size;
 		qm->used+=f->size;
 		if (qm->max_real_used<qm->real_used)
@@ -394,9 +413,6 @@ void qm_free(struct qm_block* qm, void* p)
 	size=f->size;
 	qm->used-=size;
 	qm->real_used-=size;
-#ifdef DBG_QM_MALLOC
-	qm_debug_frag(qm, f);
-#endif
 
 #ifdef QM_JOIN_FREE
 	/* join packets if possible*/
@@ -436,6 +452,131 @@ void qm_free(struct qm_block* qm, void* p)
 
 
 
+#ifdef DBG_QM_MALLOC
+void* qm_realloc(struct qm_block* qm, void* p, unsigned int size,
+					char* file, char* func, unsigned int line)
+#else
+void* qm_realloc(struct qm_block* qm, void* p, unsigned int size)
+#endif
+{
+	struct qm_frag* f;
+	unsigned int diff;
+	unsigned int orig_size;
+	struct qm_frag* n;
+	void* ptr;
+	
+	
+#ifdef DBG_QM_MALLOC
+	DBG("qm_realloc(%p, %p, %d) called from %s: %s(%d)\n", qm, p, size,
+			file, func, line);
+	if (p>(void*)qm->last_frag_end || p<(void*)qm->first_frag){
+		LOG(L_CRIT, "BUG: qm_free: bad pointer %p (out of memory block!) - "
+				"aborting\n", p);
+		abort();
+	}
+#endif
+	
+	if (size==0) {
+		if (p)
+#ifdef DBG_QM_MALLOC
+			qm_free(qm, p, file, func, line);
+#else
+			qm_free(qm, p);
+#endif
+		return 0;
+	}
+	if (p==0)
+#ifdef DBG_QM_MALLOC
+		return qm_malloc(qm, size, file, func, line);
+#else
+		return qm_malloc(qm, size);
+#endif
+	f=(struct qm_frag*) ((char*)p-sizeof(struct qm_frag));
+#ifdef DBG_QM_MALLOC
+	qm_debug_frag(qm, f);
+	DBG("qm_realloc: realloc'ing frag %p alloc'ed from %s: %s(%ld)\n",
+			f, f->file, f->func, f->line);
+	if (f->u.is_free){
+		LOG(L_CRIT, "BUG:qm_realloc: trying to realloc an already freed "
+				"pointer %p , fragment %p -- aborting\n", p, f);
+		abort();
+	}
+#endif
+	/* find first acceptable size */
+	size=ROUNDUP(size);
+	if (f->size > size){
+		/* shrink */
+#ifdef DBG_QM_MALLOC
+		DBG("qm_realloc: shrinking from %ld to %d\n", f->size, size);
+		if(split_frag(qm, f, size, file, "fragm. from qm_realloc", line)!=0){
+		DBG("qm_realloc : shrinked succesfull\n");
+#else
+		if(split_frag(qm, f, size)!=0){
+#endif
+			/* update used sizes */
+			qm->real_used-=(f->size-size);
+			qm->used-=(f->size-size);
+		}
+		
+	}else if (f->size < size){
+		/* grow */
+#ifdef DBG_QM_MALLOC
+		DBG("qm_realloc: growing from %ld to %d\n", f->size, size);
+#endif
+			orig_size=f->size;
+			diff=size-f->size;
+			n=FRAG_NEXT(f);
+			if (((char*)n < (char*)qm->last_frag_end) && 
+					(n->u.is_free)&&((n->size+FRAG_OVERHEAD)>=diff)){
+				/* join  */
+				qm_detach_free(qm, n);
+				f->size+=n->size+FRAG_OVERHEAD;
+				qm->real_used-=FRAG_OVERHEAD;
+				FRAG_END(f)->size=f->size;
+				/* end checks should be ok */
+				/* split it if necessary */
+				if (f->size > size ){
+	#ifdef DBG_QM_MALLOC
+					split_frag(qm, f, size, file, "fragm. from qm_realloc",
+										line);
+	#else
+					split_frag(qm, f, size);
+	#endif
+				}
+				qm->real_used+=(f->size-orig_size);
+				qm->used+=(f->size-orig_size);
+			}else{
+				/* could not join => realloc */
+	#ifdef DBG_QM_MALLOC
+				ptr=qm_malloc(qm, size, file, func, line);
+	#else
+				ptr=qm_malloc(qm, size);
+	#endif
+				if (ptr)
+					/* copy, need by libssl */
+					memcpy(ptr, p, orig_size);
+	#ifdef DBG_QM_MALLOC
+					qm_free(qm, p, file, func, line);
+	#else
+					qm_free(qm, p);
+	#endif
+				p=ptr;
+			}
+	}else{
+		/* do nothing */
+#ifdef DBG_QM_MALLOC
+		DBG("qm_realloc: doing nothing, same size: %ld - %d\n", f->size, size);
+#endif
+	}
+#ifdef DBG_QM_MALLOC
+	DBG("qm_realloc: returning %p\n", p);
+#endif
+	return p;
+}
+
+
+
+
 void qm_status(struct qm_block* qm)
 {
 	struct qm_frag* f;

+ 6 - 0
mem/q_malloc.h

@@ -136,6 +136,12 @@ void  qm_free(struct qm_block*, void* p, char* file, char* func,
 #else
 void  qm_free(struct qm_block*, void* p);
 #endif
+#ifdef DBG_QM_MALLOC
+void* qm_realloc(struct qm_block*, void* p, unsigned int size,
+				char* file, char* func, unsigned int line);
+#else
+void* qm_realloc(struct qm_block*, void* p, unsigned int size);
+#endif
 
 void  qm_status(struct qm_block*);
 

+ 35 - 6
mem/shm_mem.h

@@ -25,6 +25,11 @@
  * along with this program; if not, write to the Free Software 
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
+/*
+ * History:
+ * --------
+ *  2003-06-29  added shm_realloc & replaced shm_resize (andrei)
+ */
 
 
 #ifdef SHM_MEM
@@ -71,6 +76,7 @@
 	extern struct qm_block* shm_block;
 #	define MY_MALLOC qm_malloc
 #	define MY_FREE qm_free
+#	define MY_REALLOC qm_realloc
 #	define MY_STATUS qm_status
 #	define  shm_malloc_init qm_malloc_init
 #endif
@@ -108,15 +114,29 @@ inline static void* _shm_malloc(unsigned int size,
 {
 	void *p;
 	
-	shm_lock();\
+	shm_lock();
 	p=MY_MALLOC(shm_block, size, file, function, line );
 	shm_unlock();
 	return p; 
 }
 
+
+inline static void* _shm_realloc(void *ptr, unsigned int size, 
+		char* file, char* function, int line )
+{
+	void *p;
+	shm_lock();
+	p=MY_REALLOC(shm_block, ptr, size, file, function, line);
+	shm_unlock();
+	return p;
+}
+
 #define shm_malloc( _size ) _shm_malloc((_size), \
 	__FILE__, __FUNCTION__, __LINE__ )
 
+#define shm_realloc( _ptr, _size ) _shm_realloc( (_ptr), (_size), \
+	__FILE__, __FUNCTION__, __LINE__ )
+
 
 
 #define shm_free_unsafe( _p  ) \
@@ -129,9 +149,9 @@ do { \
 		shm_unlock(); \
 }while(0)
 
-void* _shm_resize( void*, unsigned int, char*, char*, unsigned int);
-#define shm_resize(_p, _s ) \
-	_shm_resize( (_p), (_s),   __FILE__, __FUNCTION__, __LINE__)
+
+
+#define shm_resize(_p, _s ) shm_realloc( (_p), (_s))
 
 
 
@@ -151,7 +171,16 @@ inline static void* shm_malloc(unsigned int size)
 }
 
 
-void* _shm_resize( void*, unsigned int);
+inline static void* shm_realloc(void *ptr, unsigned int size)
+{
+	void *p;
+	shm_lock();
+	p=MY_REALLOC(shm_block, ptr, size);
+	shm_unlock();
+	return p;
+}
+
+
 
 #define shm_free_unsafe( _p ) MY_FREE(shm_block, (_p))
 
@@ -164,7 +193,7 @@ do { \
 
 
 
-#define shm_resize(_p, _s) _shm_resize( (_p), (_s))
+#define shm_resize(_p, _s) shm_realloc( (_p), (_s))
 
 
 #endif

+ 244 - 0
tls_init.c

@@ -0,0 +1,244 @@
+/*
+ * $Id$
+ *
+ * Copyright (C) 2001-2003 Fhg Fokus
+ *
+ * This file is part of ser, a free SIP server.
+ *
+ * ser 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
+ *
+ * For a license to use the ser software under conditions
+ * other than those described here, or to purchase support for this
+ * software, please contact iptel.org by e-mail at the following addresses:
+ *    [email protected]
+ *
+ * ser 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
+ */
+/*
+ * tls initialization & cleanup functions
+ * 
+ * History:
+ * --------
+ *  2003-06-29  created by andrei
+ */
+#ifdef USE_TLS
+
+
+
+#include <openssl/ssl.h>
+#include <openssl/err.h>
+
+#include "mem/mem.h"
+#include "mem/shm_mem.h"
+#include "tcp_init.h"
+#include "dprint.h"
+
+
+
+#if OPENSSL_VERSION_NUMBER < 0x00906000L  /* 0.9.6*/
+#error "OpenSSL 0.9.6 or greater required"
+/* it might work ok with older versions (I think
+ *  >= 0.9.4 should be ok), but I didn't test them
+ *  so try them at your own risk :-) -- andrei
+ */
+#endif
+
+
+/* global tls related data */
+SSL_CTX* default_ctx=0 ; /* global ssl context */
+
+int tls_log=L_INFO; /* tls log level */
+int tls_require_cert=0; /* require client certificate */
+char* tls_pkey_file=0; /* private key file name */
+char* tls_cert_file=0; /* certificate file name */
+char* tls_ca_file=0;   /* CA list file name */
+
+
+/* inits a sock_info structure with tls data
+ * (calls tcp_init for the tcp part)
+ * returns 0 on success, -1 on error */
+int tls_init(struct socket_info* sock_info)
+{
+	int ret;
+	if ((ret=tcp_init(sock_info))!=0){
+		LOG(L_ERR, "ERROR: tls_init: tcp_init failed on"
+			"%.*s:%d\n", sock_info->address_str.len,
+			sock_info->address_str.s, sock_info->port_no);
+		return ret;
+	}
+	sock_info->proto=PROTO_TLS;
+	/* tls specific stuff */
+	return 0;
+}
+
+
+/* malloc & friends functions that will be used
+ * by libssl (we need most ssl info in shared mem.)*/
+
+void* tls_malloc(size_t size)
+{
+	return shm_malloc(size);
+}
+
+
+void tls_free(void* ptr)
+{
+	shm_free(ptr);
+}
+
+
+void* tls_realloc(void* ptr, size_t size)
+{
+	return shm_realloc(ptr, size);
+}
+
+
+/* print the ssl error stack */
+void tls_dump_errors(char* s)
+{
+	long err;
+	if ( 1 /*default_ctx */) /* only if ssl was initialized */
+		while((err=ERR_get_error()))
+			LOG(L_ERR, "%s%s\n", (s)?s:"", ERR_error_string(err,0));
+}
+
+
+
+/* inits ser tls support
+ * returns 0 on success, <0 on error */
+int init_tls()
+{
+
+	
+	if (tls_pkey_file==0)
+		tls_pkey_file=TLS_PKEY_FILE;
+	if (tls_cert_file==0)
+		tls_cert_file=TLS_CERT_FILE;
+	if (tls_ca_file==0)
+		tls_ca_file=TLS_CA_FILE;
+	
+	DBG("initializing openssl...\n");
+	SSL_library_init();  /* don't use shm_ for SSL_library_init() */
+	/* init mem. alloc. for libcrypt & openssl */
+	CRYPTO_set_mem_functions(tls_malloc, tls_realloc,
+								tls_free);
+	
+	/* init the openssl library */
+	SSL_load_error_strings(); /* readable error messages*/
+	/* seed the PRNG, nothing on linux because openssl should automatically
+	   use /dev/urandom, see RAND_seed, RAND_add */
+	
+	/* create the ssl context */
+	DBG("creating the ssl context...\n");
+	default_ctx=SSL_CTX_new(TLSv1_method());
+	if (default_ctx==0){
+		LOG(L_ERR, "init_tls: failed to create ssl context\n");
+		goto error;
+	}
+	/* no passwd: */
+	 /* SSL_CTX_set_default_passwd_cb(ctx, callback); */
+	
+	/* set options, e.g SSL_OP_NO_SSLv2, 
+	 * SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION
+	 */
+	/* SSL_CTX_set_options(ctx, options); */
+	
+	/* mode, e.g. SSL_MODE_ENABLE_PARTIAL_WRITE,
+	 * SSL_MODE_AUTO_RETRY */
+	/* SSL_CTX_set_mode(ctx, mode); */
+	
+	/* using certificates (we don't allow anonymous ciphers => at least
+	 * the server must have a cert)*/
+	/* private key */
+	if (SSL_CTX_use_PrivateKey_file(default_ctx, tls_pkey_file,
+				SSL_FILETYPE_PEM)!=1){
+		LOG(L_ERR, "init_tls: failed to load private key from \"%s\"\n",
+				tls_pkey_file);
+		goto error_certs;
+	}
+	if (SSL_CTX_use_certificate_chain_file(default_ctx, tls_cert_file)!=1){
+		/* better than *_use_certificate_file 
+		 * see SSL_CTX_use_certificate(3)/Notes */
+		LOG(L_ERR, "init_tls: failed to load certificate from \"%s\"\n",
+					tls_cert_file);
+		goto error_certs;
+	}
+	/* check if private key corresponds to the loaded ceritficate */
+	if (SSL_CTX_check_private_key(default_ctx)!=1){
+		LOG(L_CRIT, "init_tls: private key \"%s\" does not match the"
+				" certificate file \"%s\"\n", tls_pkey_file, tls_cert_file);
+		goto error_certs;
+	}
+	
+	/* set session id context, usefull for reusing stored sessions */
+	/*
+	if (SSL_CTX_set_session_id_context(ctx, version, version_len)!=1){
+		LOG(L_CRIT, "init_tls: failed to set session id\n");
+		goto error;
+	}
+	*/
+	
+	/* set cert. verifications options */
+	/* verify peer if it has a cert (to fail for no cert. add 
+	 *  | SSL_VERIFY_FAIL_IF_NO_PEER_CERT ); forces the server to send
+	 *  a client certificate request */
+	SSL_CTX_set_verify(default_ctx, SSL_VERIFY_PEER | ( (tls_require_cert)?
+			SSL_VERIFY_FAIL_IF_NO_PEER_CERT:0 ), 0);
+	/* SSL_CTX_set_verify_depth(ctx, 2);  -- default 9 */
+	/* CA locations, list */
+	if (tls_ca_file){
+		if (SSL_CTX_load_verify_locations(default_ctx, tls_ca_file, 0 )!=1){
+			/* we don't support ca path, we load them only from files */
+			LOG(L_CRIT, "init_tls: error while processing CA locations\n");
+			goto error_certs;
+		}
+		SSL_CTX_set_client_CA_list(default_ctx, 
+									SSL_load_client_CA_file(tls_ca_file));
+		if (SSL_CTX_get_client_CA_list(default_ctx)==0){
+			LOG(L_CRIT, "init_tls: error setting client CA list from <%s>\n",
+						tls_ca_file);
+			goto error_certs;
+		}
+	}
+	
+	/* DH tmp key generation -- see DSA_generate_parameters,
+	 * SSL_CTX_set_tmp_dh, SSL_CTX_set_options(ctx, SSL_OP_SINGLE_DH_USE */
+	
+	/* RSA tmp key generation => we don't care, we won't accept 
+	 * connection to export restricted applications and tls does not
+	 * allow a tmp key in another sitaution */
+	
+	return 0;
+error_certs:
+	/*
+	SSL_CTX_free(ctx);
+	ctx=0;
+	*/
+error:
+	tls_dump_errors("tls_init:");
+	return -1;
+}
+
+
+
+void destroy_tls()
+{
+	if(default_ctx){
+		DBG("destroy_tls...\n");
+		SSL_CTX_free(default_ctx);
+		ERR_free_strings();
+		default_ctx=0; 
+	}
+}
+
+#endif

+ 67 - 0
tls_init.h

@@ -0,0 +1,67 @@
+
+/*
+ * $Id$
+ *
+ * Copyright (C) 2001-2003 Fhg Fokus
+ *
+ * This file is part of ser, a free SIP server.
+ *
+ * ser 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
+ *
+ * For a license to use the ser software under conditions
+ * other than those described here, or to purchase support for this
+ * software, please contact iptel.org by e-mail at the following addresses:
+ *    [email protected]
+ *
+ * ser 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
+ */
+/*
+ * tls initialization & cleanup functions
+ * 
+ * History:
+ * --------
+ *  2003-06-29  created by andrei
+ */
+#ifdef USE_TLS
+
+#ifndef tls_init_h
+#define tls_init_h
+
+#ifndef USE_TCP
+#error "TLS requires TCP support compiled-in, please" \
+        " add -DUSE_TCP to the Makefile.defs"
+#endif
+
+#ifndef SHM_MEM
+#error "shared memory support needed (add -DSHM_MEM to Makefile.defs)"
+#endif
+
+
+/* inits ser tls support
+ * returns 0 on success, <0 on error */
+int init_tls();
+
+/* cleans up */
+void destroy_tls();
+
+/* inits a sock_info structure with tls data
+ * (calls tcp_init for the tcp part)
+ * returns 0 on success, -1 on error */
+int tls_init(struct socket_info* sock_info);
+
+/* print the ssl error stack */
+void tls_dump_errors(char* s);
+
+
+#endif /* tls_init_h*/
+#endif /* USE_TLS*/