1 /*
2  *  Copyright (C) 20016 Christos Tsantilas
3  *
4  *  This program is free software; you can redistribute it and/or
5  *  modify it under the terms of the GNU Lesser General Public
6  *  License as published by the Free Software Foundation; either
7  *  version 2.1 of the License, or (at your option) any later version.
8  *
9  *  This program is distributed in the hope that it will be useful,
10  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
11  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  *  Lesser General Public License for more details.
13  *
14  *  You should have received a copy of the GNU Lesser General Public
15  *  License along with this library; if not, write to the Free Software
16  *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
17  *  MA  02110-1301  USA.
18  */
19 
20 #include "common.h"
21 #include "c-icap.h"
22 #include "array.h"
23 #include "port.h"
24 #ifdef USE_OPENSSL
25 #include "net_io_ssl.h"
26 #endif
27 #include "debug.h"
28 
mystrcmp(const char * s1,const char * s2)29 static int mystrcmp(const char *s1, const char *s2)
30 {
31     if (s1 && !s2)
32         return 1;
33     if (!s1 && s2)
34         return -1;
35     if (!s1 && !s2)
36         return 0;
37     return strcmp(s1, s2);
38 }
39 
ci_port_compare_config(ci_port_t * src,ci_port_t * dst)40 static int ci_port_compare_config(ci_port_t *src, ci_port_t *dst)
41 {
42     if (dst->port != src->port)
43         return 0;
44 
45     if (mystrcmp(dst->address, src->address))
46         return 0;
47 
48     /*fd, configured, protocol_family and secs_to_linger are filled by c-icap while port configured*/
49 
50 #ifdef USE_OPENSSL
51     if (dst->tls_enabled != src->tls_enabled)
52         return 0;
53 #endif
54     return 1;
55 }
56 
ci_port_move_configured(ci_port_t * dst,ci_port_t * src)57 static void ci_port_move_configured(ci_port_t *dst, ci_port_t *src)
58 {
59     dst->configured = src->configured;
60     dst->fd = src->fd;
61     src->configured = 0;
62     src->fd = -1;
63 
64 #ifdef USE_OPENSSL
65     dst->tls_enabled = src->tls_enabled;
66     dst->tls_context = src->tls_context;
67     dst->bio = src->bio;
68     src->tls_context = NULL;
69     src->bio = NULL;
70     if (src->tls_enabled)
71         ci_port_reconfigure_tls(dst);
72 #endif
73 }
74 
ci_port_handle_reconfigure(ci_vector_t * new_ports,ci_vector_t * old_ports)75 void ci_port_handle_reconfigure(ci_vector_t *new_ports, ci_vector_t *old_ports)
76 {
77     int i, k;
78     ci_port_t *find_port, *check_port, *check_old_port;
79     for (i = 0; (check_port = (ci_port_t *)ci_vector_get(new_ports, i)) != NULL; ++i) {
80         for (k = 0, find_port = NULL; (find_port == NULL) && ((check_old_port = (ci_port_t *)ci_vector_get(old_ports, k)) != NULL); ++k ) {
81             if (ci_port_compare_config(check_port, check_old_port)) {
82                 find_port = check_port;
83                 ci_port_move_configured(check_port, check_old_port);
84             }
85         }
86         if (find_port)
87             ci_debug_printf(1, "Port %d is already configured\n", find_port->port);
88     }
89 }
90 
ci_port_close(ci_port_t * port)91 void ci_port_close(ci_port_t *port)
92 {
93     if (port->fd < 0)
94         return;
95 
96 #ifdef USE_OPENSSL
97     if (port->bio)
98         icap_close_server_tls(port);
99     else
100 #endif
101         close(port->fd);
102     port->fd = -1;
103     port->configured = 0;
104 }
105 
ci_port_list_release(ci_vector_t * ports)106 void ci_port_list_release(ci_vector_t *ports)
107 {
108     int i;
109     ci_port_t *p;
110 
111     for (i = 0; (p = (ci_port_t *)ci_vector_get(ports, i)) != NULL; ++i) {
112         ci_port_close(p);
113         if (p->address)
114             free(p->address);
115 #ifdef USE_OPENSSL
116         if (p->tls_server_cert)
117             free(p->tls_server_cert);
118         if (p->tls_server_key)
119             free(p->tls_server_key);
120         if (p->tls_client_ca_certs)
121             free(p->tls_client_ca_certs);
122         if (p->tls_cafile)
123             free(p->tls_cafile);
124         if (p->tls_capath)
125             free(p->tls_capath);
126         if (p->tls_method)
127             free(p->tls_method);
128         if (p->tls_ciphers)
129             free(p->tls_ciphers);
130 #endif
131     }
132 
133     ci_vector_destroy(ports);
134 }
135