ims_ipsec_pcscf: fixed possible use of uninitialized value in ipsec_forward()
[sip-router] / src / modules / ims_ipsec_pcscf / ims_ipsec_pcscf_mod.c
1 /*
2  * IMS IPSEC PCSCF module
3  *
4  * Copyright (C) 2018 Tsvetomir Dimitrov
5  *
6  * This file is part of Kamailio, a free SIP server.
7  *
8  * Kamailio is free software; you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License as published by
10  * the Free Software Foundation; either version 2 of the License, or
11  * (at your option) any later version
12  *
13  * Kamailio is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with this program; if not, write to the Free Software
20  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
21  *
22  */
23
24 #include "../../core/sr_module.h"
25 #include "../../modules/tm/tm_load.h"
26 #include "../ims_usrloc_pcscf/usrloc.h"
27
28 #include "cmd.h"
29 #include "spi_gen.h"
30
31
32 MODULE_VERSION
33
34 usrloc_api_t ul;                                                /**!< Structure containing pointers to usrloc functions*/
35 struct tm_binds tmb;                                    /**!< TM API structure */
36
37
38 str ipsec_listen_addr = STR_NULL;
39 str ipsec_listen_addr6 = STR_NULL;
40 int ipsec_client_port =  5062;
41 int ipsec_server_port =  5063;
42 int spi_id_start = 100;
43 int spi_id_range = 1000;
44 int xfrm_user_selector = 143956232;
45
46 /*! \brief Module init & destroy function */
47 static int  mod_init(void);
48 static int  child_init(int);
49 static void mod_destroy(void);
50 static int w_create(struct sip_msg* _m, char* _d, char* _cflags);
51 static int w_forward(struct sip_msg* _m, char* _d, char* _cflags);
52 static int w_destroy(struct sip_msg* _m, char* _d, char* _cflags);
53
54 /*! \brief Fixup functions */
55 static int domain_fixup(void** param, int param_no);
56 static int save_fixup2(void** param, int param_no);
57
58 /*! \brief
59  * Exported functions
60  */
61 static cmd_export_t cmds[] = {
62         {"ipsec_create",  (cmd_function)w_create,  1, save_fixup2, 0, ONREPLY_ROUTE },
63         {"ipsec_forward", (cmd_function)w_forward, 1, save_fixup2, 0, REQUEST_ROUTE | ONREPLY_ROUTE },
64         {"ipsec_destroy", (cmd_function)w_destroy, 1, save_fixup2, 0, REQUEST_ROUTE | ONREPLY_ROUTE },
65         {0, 0, 0, 0, 0, 0}
66 };
67
68 /*! \brief
69  * Exported parameters
70  */
71 static param_export_t params[] = {
72         {"ipsec_listen_addr",  PARAM_STR, &ipsec_listen_addr   },
73         {"ipsec_listen_addr6",  PARAM_STR, &ipsec_listen_addr6   },
74         {"ipsec_client_port",   INT_PARAM, &ipsec_client_port   },
75         {"ipsec_server_port",   INT_PARAM, &ipsec_server_port   },
76         {"ipsec_spi_id_start",  INT_PARAM, &spi_id_start},
77         {"ipsec_spi_id_range",  INT_PARAM, &spi_id_range},
78         {0, 0, 0}
79 };
80
81 /*! \brief
82  * Module exports structure
83  */
84 struct module_exports exports = {
85         "ims_ipsec_pcscf",
86         DEFAULT_DLFLAGS,/* dlopen flags */
87         cmds,           /* exported functions */
88         params,         /* exported params */
89         0,              /*·exported·RPC·methods·*/
90         0,              /* exported pseudo-variables */
91         0,              /*·response·function·*/
92         mod_init,       /* module initialization function */
93         child_init,     /* Per-child init function */
94         mod_destroy,    /* destroy function */
95 };
96
97
98 /*! \brief
99  * Initialize parent
100  */
101 static int mod_init(void) {
102     char addr4[128];
103         char addr6[128];
104
105         bind_usrloc_t bind_usrloc;
106
107         bind_usrloc = (bind_usrloc_t) find_export("ul_bind_ims_usrloc_pcscf", 1, 0);
108         if (!bind_usrloc) {
109                 LM_ERR("can't bind ims_usrloc_pcscf\n");
110                 return -1;
111         }
112
113         if (bind_usrloc(&ul) < 0) {
114                 return -1;
115         }
116         LM_INFO("Successfully bound to PCSCF Usrloc module\n");
117
118         /* load the TM API */
119         if (load_tm_api(&tmb) != 0) {
120                 LM_ERR("can't load TM API\n");
121                 return -1;
122         }
123         LM_INFO("Successfully bound to TM module\n");
124
125         if(ipsec_listen_addr.len) {
126                 if(ipsec_listen_addr.len > sizeof(addr4)-1) {
127                 LM_ERR("Bad value for ipsec listen address IPv4: %.*s\n", ipsec_listen_addr.len, ipsec_listen_addr.s);
128                 return -1;
129         }
130
131             memset(addr4, 0, sizeof(addr4));
132             memcpy(addr4, ipsec_listen_addr.s, ipsec_listen_addr.len);
133
134                 //add listen interfaces for IPv4
135                 if(add_listen_iface(addr4, NULL, ipsec_client_port, PROTO_TCP, 0) != 0) {
136                         LM_ERR("Error adding listen ipsec client TCP interface for IPv4\n");
137                         return -1;
138                 }
139
140                 if(add_listen_iface(addr4, NULL, ipsec_server_port, PROTO_TCP, 0) != 0) {
141                         LM_ERR("Error adding listen ipsec server TCP interface for IPv4\n");
142                         return -1;
143                 }
144
145                 if(add_listen_iface(addr4, NULL, ipsec_client_port, PROTO_UDP, 0) != 0) {
146                         LM_ERR("Error adding listen ipsec client UDP interface for IPv4\n");
147                         return -1;
148                 }
149
150                 if(add_listen_iface(addr4, NULL, ipsec_server_port, PROTO_UDP, 0) != 0) {
151                         LM_ERR("Error adding listen ipsec server UDP interface for IPv4\n");
152                         return -1;
153                 }
154         }
155
156         if(ipsec_listen_addr6.len) {
157                 if(ipsec_listen_addr6.len > sizeof(addr6)-1) {
158                         LM_ERR("Bad value for ipsec listen address IPv6: %.*s\n", ipsec_listen_addr6.len, ipsec_listen_addr6.s);
159                 return -1;
160                 }
161
162                 memset(addr6, 0, sizeof(addr6));
163         memcpy(addr6, ipsec_listen_addr6.s, ipsec_listen_addr6.len);
164
165                 //add listen interfaces for IPv6
166                 if(add_listen_iface(addr6, NULL, ipsec_client_port, PROTO_TCP, 0) != 0) {
167                         LM_ERR("Error adding listen ipsec client TCP interface for IPv6\n");
168                         return -1;
169                 }
170
171                 if(add_listen_iface(addr6, NULL, ipsec_server_port, PROTO_TCP, 0) != 0) {
172                         LM_ERR("Error adding listen ipsec server TCP interface for IPv6\n");
173                         return -1;
174                 }
175
176                 if(add_listen_iface(addr6, NULL, ipsec_client_port, PROTO_UDP, 0) != 0) {
177                         LM_ERR("Error adding listen ipsec client UDP interface for IPv6\n");
178                         return -1;
179                 }
180
181                 if(add_listen_iface(addr6, NULL, ipsec_server_port, PROTO_UDP, 0) != 0) {
182                         LM_ERR("Error adding listen ipsec server UDP interface for IPv6\n");
183                         return -1;
184                 }
185         }
186
187     if(fix_all_socket_lists() != 0) {
188         LM_ERR("Error calling fix_all_socket_lists() during module initialisation\n");
189         return -1;
190     }
191
192     if(ipsec_cleanall() != 0) {
193         LM_ERR("Error ipsec tunnels during for module initialisation\n");
194         return -1;
195         }
196
197     int res = 0;
198     if((res = init_spi_gen(spi_id_start, spi_id_start + spi_id_range)) != 0) {
199         LM_ERR("Error initialising spi generator. Error: %d\n", res);
200         return -1;
201     }
202
203         return 0;
204 }
205
206 static void mod_destroy(void)
207 {
208     if(ipsec_cleanall() != 0) {
209         LM_ERR("Error ipsec tunnels during for module cleanup\n");
210         }
211
212     if(destroy_spi_gen() != 0) {
213         LM_ERR("Error destroying spi generator\n");
214     }
215 }
216
217 static int child_init(int rank)
218 {
219         return 0;
220 }
221
222 /* fixups */
223 static int domain_fixup(void** param, int param_no)
224 {
225         udomain_t* d;
226
227         if (param_no == 1) {
228                 if (ul.register_udomain((char*)*param, &d) < 0) {
229                         LM_ERR("failed to register domain\n");
230                         return E_UNSPEC;
231                 }
232                 *param = (void*)d;
233         }
234         return 0;
235 }
236
237 /*! \brief
238  * Fixup for "save" function - both domain and flags
239  */
240 static int save_fixup2(void** param, int param_no)
241 {
242         if (param_no == 1) {
243                 return domain_fixup(param,param_no);
244         }
245         return 0;
246 }
247
248
249 /*! \brief
250  * Wrapper to ipsec functions
251  */
252 static int w_create(struct sip_msg* _m, char* _d, char* _cflags)
253 {
254         return ipsec_create(_m, (udomain_t*)_d);
255 }
256
257 static int w_forward(struct sip_msg* _m, char* _d, char* _cflags)
258 {
259         return ipsec_forward(_m, (udomain_t*)_d);
260 }
261
262 static int w_destroy(struct sip_msg* _m, char* _d, char* _cflags)
263 {
264         return ipsec_destroy(_m, (udomain_t*)_d);
265 }