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