blob: bb096dd66a63a8ff2b31495bb274d363e0a47d3e [file] [log] [blame]
anjana_sreekumar@infosys.com991c2062020-01-08 11:42:57 +05301/*
2 * Copyright (c) 2003-2018, Great Software Laboratory Pvt. Ltd.
3 * Copyright (c) 2017 Intel Corporation
4 * Copyright (c) 2019, Infosys Ltd.
5 *
6 * Licensed under the Apache License, Version 2.0 (the "License");
7 * you may not use this file except in compliance with the License.
8 * You may obtain a copy of the License at
9 *
10 * http://www.apache.org/licenses/LICENSE-2.0
11 *
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
17 */
18
19
20#include <stdio.h>
21#include <stdlib.h>
22#include <pthread.h>
23#include <string.h>
24#include <unistd.h>
25#include <freeDiameter/freeDiameter-host.h>
26#include <freeDiameter/libfdcore.h>
27#include <freeDiameter/libfdproto.h>
28
29#include "log.h"
30#include "err_codes.h"
31#include "message_queues.h"
32#include "ipc_api.h"
33#include "s6a_fd.h"
34#include "s6a.h"
35#include "msgType.h"
36//#include "stage1_s6a_msg.h"
37#include "hss_message.h"
38
39#define DIAMETER_SUCCESS 2001
40
41/** Global and externs**/
42extern struct fd_dict_objects g_fd_dict_objs;
43extern struct fd_dict_data g_fd_dict_data;
44
45extern int g_Q_mme_S6a_fd;
46/**global and externs end**/
47
48/**
49 * @brief Parse authentication information avp recvd in AIA. This contains
50 * important security information for the UE
51 * @param [in] avp_data - AVP value received
52 * @param [out] aia - Security info is filled in to aia msg Q
53 * @return int - error code
54 */
55static int
56get_aia_sec_vector(struct avp *avp_data, struct aia_Q_msg *aia)
57{
58 struct avp *sub_avp = NULL;
59 struct avp_hdr *element = NULL;
60
61 CHECK_FCT_DO(fd_msg_avp_hdr(avp_data, &element),
62 return S6A_FD_ERROR);
63
64 /*Authentication-Info*/
65 if ((NULL == element) ||
66 (element->avp_code != g_fd_dict_data.auth_info.avp_code))
67 return S6A_FD_ERROR;
68
69 /*Find first sub child of Authentication-Info*/
70 CHECK_FCT_DO(fd_msg_browse(avp_data, MSG_BRW_FIRST_CHILD, &sub_avp,
71 NULL),
72 return S6A_FD_ERROR);
73
74 /*Lookup for sub element "E-UTRAN-Vector" in loop*/
75 while (NULL != sub_avp) {
76
77 fd_msg_avp_hdr(sub_avp, &element);
78
79 if ((NULL != element) && (element->avp_code ==
80 g_fd_dict_data.E_UTRAN_vector.avp_code))
81 /*Found the entry*/
82 break;
83
84 /*Iterate sub entries*/
85 CHECK_FCT_DO(fd_msg_browse(sub_avp, MSG_BRW_NEXT, &sub_avp,
86 NULL),
87 return S6A_FD_ERROR);
88 }
89
90 /*Element "E-UTRAN-Vector" not found, then return*/
91 if (NULL == sub_avp) return S6A_FD_ERROR;
92
93 CHECK_FCT_DO(fd_msg_browse(sub_avp, MSG_BRW_FIRST_CHILD,
94 &sub_avp, NULL),
95 return S6A_FD_ERROR);
96
97 /*Iterate all sub elements of E-UTRAN-Vector and filter sec vector params*/
98 for (;
99 NULL != sub_avp; /*Till null*/
100// CHECK_FCT_DO(fd_msg_browse(sub_avp, MSG_BRW_NEXT, &sub_avp, NULL),
101// return S6A_FD_ERROR) /*Iterate elements*/
102 ) {
103
104 fd_msg_avp_hdr(sub_avp, &element);
105
106 /*AVP: RAND(1447) l=28 f=VM- vnd=TGPP*/
107 if (element->avp_code == g_fd_dict_data.RAND.avp_code) {
108
109 //if (element->avp_value->os.len > sizeof(aia->sec.rand.val))
110 if (element->avp_value->os.len > AIA_RAND_SIZE)
111 return S6A_FD_ERROR;
112
113 aia->sec.rand.len = element->avp_value->os.len;
114 memcpy(aia->sec.rand.val, element->avp_value->os.data,
115 aia->sec.rand.len);
116 }
117
118 /*AVP: XRES(1448) l=20 f=VM- vnd=TGPP*/
119 if (element->avp_code == g_fd_dict_data.XRES.avp_code) {
120
121 if (element->avp_value->os.len > AIA_RES_SIZE)
122 return S6A_FD_ERROR;
123
124 aia->sec.xres.len = element->avp_value->os.len;
125 memcpy(aia->sec.xres.val, element->avp_value->os.data,
126 aia->sec.xres.len);
127 }
128
129 /*AVP: AUTN(1449) l=28 f=VM- vnd=TGPP*/
130 if (element->avp_code == g_fd_dict_data.AUTN.avp_code) {
131
132 if (element->avp_value->os.len > AIA_AUTN_SIZE)
133 return S6A_FD_ERROR;
134
135 aia->sec.autn.len = element->avp_value->os.len;
136 memcpy(aia->sec.autn.val, element->avp_value->os.data,
137 aia->sec.autn.len);
138 }
139
140 /*AVP: KASME(1450) l=44 f=VM- vnd=TGPP*/
141 if (element->avp_code == g_fd_dict_data.KASME.avp_code) {
142
143 if (element->avp_value->os.len > AIA_KASME_SIZE)
144 return S6A_FD_ERROR;
145
146 aia->sec.kasme.len = element->avp_value->os.len;
147 memcpy(aia->sec.kasme.val, element->avp_value->os.data,
148 aia->sec.kasme.len);
149 }
150
151 CHECK_FCT_DO(fd_msg_browse(sub_avp, MSG_BRW_NEXT, &sub_avp, NULL),
152 return S6A_FD_ERROR) /*Iterate elements*/
153
154 }
155
156 return SUCCESS;
157}
158
159static
160void send_to_stage2(struct s6_incoming_msg_data_t *incoming_msg_p)
161{
162 TRACE_ENTRY("\n****************WRITE TO g_Q_mme_S6a_fd");
163
164 incoming_msg_p->destInstAddr = htonl(mmeAppInstanceNum_c);
165 incoming_msg_p->srcInstAddr = htonl(s6AppInstanceNum_c);
166
167 /*Send to stage2 queue*/
168 send_tipc_message(g_Q_mme_S6a_fd, mmeAppInstanceNum_c, (char*)incoming_msg_p, S6_READ_MSG_BUF_SIZE);
169}
170
171int aia_resp_callback(struct msg **buf, struct avp *_avp,
172 struct session *session, void *data,
173 enum disp_action * action)
174{
175 TRACE_ENTRY("\n****************ANJANA ****** Callback ----- >AIA recvd\n");
176 int res = SUCCESS, sess_id_len;
177 struct msg *resp = *buf;
178 struct avp *avp_ptr = NULL;
179 unsigned char *sess_id= NULL;
180 struct s6_incoming_msg_data_t s6_incoming_msgs;
181 struct avp_hdr *avp_hdr = NULL;
182
183 log_msg(LOG_INFO, "\nCallback ----- >AIA recvd\n");
184
185 dump_fd_msg(resp);
186 //TODO - workaround for dump call. Remove this.
187 {
188 char * buf = NULL;
189 size_t len = 0;
190 printf("*********AIA CALLBACK******%s\n", fd_msg_dump_treeview(&buf, &len, NULL, resp,
191 fd_g_config->cnf_dict, 0, 1));
192 free(buf);
193 }
194
195 CHECK_FCT_DO(fd_sess_getsid(session, &sess_id, (size_t*)&sess_id_len),
196 return S6A_FD_ERROR);
197
198 log_msg(LOG_INFO, "\nCallback ----- >session id=%s \n",sess_id);
199
200 s6_incoming_msgs.msg_type = auth_info_answer;
201 /*Retrieve UE index embedded in to session ID string at AIR time*/
202 s6_incoming_msgs.ue_idx = get_ue_idx_from_fd_resp(sess_id, sess_id_len);
203
204 /*AVP: Result-Code(268)*/
205 fd_msg_search_avp(resp, g_fd_dict_objs.res_code, &avp_ptr);
206
207 if (NULL != avp_ptr) {
208 fd_msg_avp_hdr(avp_ptr, &avp_hdr);
209 res = avp_hdr->avp_value->u32;
210
211 if (DIAMETER_SUCCESS != res) {
212 log_msg(LOG_ERROR, "Diameter error with HSS\n");
213 }
214 //Vikram: chk res = SUCCESS;
215
216 } else {
217 struct fd_result fd_res;
218
219 avp_ptr = NULL;
220 fd_msg_search_avp(resp, g_fd_dict_objs.exp_res,
221 &avp_ptr);
222
223 if (NULL == avp_ptr) {
224 res = S6A_FD_ERROR;
225 } else if (parse_fd_result(avp_ptr, &fd_res) != 0) {
226 res = S6A_FD_ERROR;
227 } else res = fd_res.result_code;
228 }
229
230 if (DIAMETER_SUCCESS == res) {
231 /*AVP: Authentication-Info*/
232 fd_msg_search_avp(resp, g_fd_dict_objs.auth_info,
233 &avp_ptr);
234
235 if (NULL != avp_ptr) {
236 if (get_aia_sec_vector(avp_ptr, &s6_incoming_msgs.msg_data.aia_Q_msg_m) != SUCCESS)
237 res = S6A_FD_ERROR;
238 } else {
239 res = S6A_FD_ERROR;
240 }
241 }
242
243 /*Handled fd msg, do cleanup*/
244 fd_msg_free(*buf);
245
246 *buf = NULL;
247
248 if (DIAMETER_SUCCESS != res) s6_incoming_msgs.msg_data.aia_Q_msg_m.res = S6A_AIA_FAILED;
249
250 send_to_stage2(&s6_incoming_msgs);
251
252 return SUCCESS;
253}
254
255void
256handle_perf_hss_aia(int ue_idx, struct hss_aia_msg *aia)
257{
258 struct s6_incoming_msg_data_t msg;
259
260 msg.ue_idx = ue_idx;
261 msg.msg_type = auth_info_answer;
262 msg.msg_data.aia_Q_msg_m.res= 0;
263 memcpy(&(msg.msg_data.aia_Q_msg_m.sec.rand), &(aia->rand), sizeof(RAND));
264 memcpy(&(msg.msg_data.aia_Q_msg_m.sec.xres), &(aia->xres), sizeof(XRES));
265 memcpy(&(msg.msg_data.aia_Q_msg_m.sec.autn), &(aia->autn), sizeof(AUTN));
266 memcpy(&(msg.msg_data.aia_Q_msg_m.sec.kasme), &(aia->kasme), sizeof(KASME));
267
268 send_to_stage2(&msg);/*handle diameter error*/
269}