Browse code

auth_diameter: avoid passing large structs as params and better error handling

Daniel-Constantin Mierla authored on 27/07/2017 07:11:17
Showing 1 changed files
... ...
@@ -64,6 +64,7 @@ int init_mytcp(char* host, int port)
64 64
     if (server == NULL) 
65 65
 	{
66 66
 		LM_ERR("error finding the host\n");
67
+		close(sockfd);
67 68
 		return -1;
68 69
     }
69 70
 
... ...
@@ -76,8 +77,8 @@ int init_mytcp(char* host, int port)
76 77
     if (connect(sockfd, (const struct sockaddr *)&serv_addr, 
77 78
 							sizeof(serv_addr)) < 0) 
78 79
 	{
79
-        LM_ERR("error connecting to the "
80
-						"DIAMETER client\n");
80
+        LM_ERR("error connecting to the DIAMETER client\n");
81
+		close(sockfd);
81 82
 		return -1;
82 83
 	}	
83 84
 
Browse code

auth_diameter: removed svn id, history

Daniel-Constantin Mierla authored on 26/07/2017 20:32:39
Showing 1 changed files
... ...
@@ -1,6 +1,4 @@
1 1
 /*
2
- * $Id$
3
- *
4 2
  * Digest Authentication - Diameter support
5 3
  *
6 4
  * Copyright (C) 2001-2003 FhG Fokus
... ...
@@ -20,11 +18,6 @@
20 18
  * You should have received a copy of the GNU General Public License 
21 19
  * along with this program; if not, write to the Free Software 
22 20
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
23
- *
24
- * History:
25
- * -------
26
- *  
27
- *  
28 21
  */
29 22
 
30 23
 #include <stdio.h>
Browse code

core, lib, modules: updated include paths for header files

Daniel-Constantin Mierla authored on 07/12/2016 11:07:22
Showing 1 changed files
... ...
@@ -38,11 +38,11 @@
38 38
 #include <errno.h>
39 39
 
40 40
 /* memory management */
41
-#include "../../mem/mem.h"
41
+#include "../../core/mem/mem.h"
42 42
 
43 43
 /* printing messages, dealing with strings and other utils */
44
-#include "../../dprint.h"
45
-#include "../../str.h"
44
+#include "../../core/dprint.h"
45
+#include "../../core/str.h"
46 46
 
47 47
 /* headers defined by this module */
48 48
 #include "auth_diameter.h"
Browse code

core, lib, modules: restructured source code tree

- new folder src/ to hold the source code for main project applications
- main.c is in src/
- all core files are subfolder are in src/core/
- modules are in src/modules/
- libs are in src/lib/
- application Makefiles are in src/
- application binary is built in src/ (src/kamailio)

Daniel-Constantin Mierla authored on 07/12/2016 11:03:51
Showing 1 changed files
1 1
new file mode 100644
... ...
@@ -0,0 +1,337 @@
1
+/*
2
+ * $Id$
3
+ *
4
+ * Digest Authentication - Diameter support
5
+ *
6
+ * Copyright (C) 2001-2003 FhG Fokus
7
+ *
8
+ * This file is part of Kamailio, a free SIP server.
9
+ *
10
+ * Kamailio is free software; you can redistribute it and/or modify
11
+ * it under the terms of the GNU General Public License as published by
12
+ * the Free Software Foundation; either version 2 of the License, or
13
+ * (at your option) any later version
14
+ * 
15
+ * Kamailio is distributed in the hope that it will be useful,
16
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
17
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18
+ * GNU General Public License for more details.
19
+ *
20
+ * You should have received a copy of the GNU General Public License 
21
+ * along with this program; if not, write to the Free Software 
22
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
23
+ *
24
+ * History:
25
+ * -------
26
+ *  
27
+ *  
28
+ */
29
+
30
+#include <stdio.h>
31
+#include <stdlib.h>
32
+#include <unistd.h>
33
+#include <sys/types.h>
34
+#include <sys/time.h>
35
+#include <sys/socket.h>
36
+#include <netinet/in.h>
37
+#include <netdb.h> 
38
+#include <errno.h>
39
+
40
+/* memory management */
41
+#include "../../mem/mem.h"
42
+
43
+/* printing messages, dealing with strings and other utils */
44
+#include "../../dprint.h"
45
+#include "../../str.h"
46
+
47
+/* headers defined by this module */
48
+#include "auth_diameter.h"
49
+#include "defs.h"
50
+#include "tcp_comm.h"
51
+#include "diameter_msg.h"
52
+
53
+#define MAX_TRIES	10
54
+
55
+/* it initializes the TCP connection */ 
56
+int init_mytcp(char* host, int port)
57
+{
58
+	int sockfd;
59
+	struct sockaddr_in serv_addr;
60
+	struct hostent *server;
61
+    
62
+	sockfd = socket(PF_INET, SOCK_STREAM, 0);
63
+	
64
+    if (sockfd < 0) 
65
+	{
66
+		LM_ERR("error creating the socket\n");
67
+		return -1;
68
+	}	
69
+	
70
+    server = gethostbyname(host);
71
+    if (server == NULL) 
72
+	{
73
+		LM_ERR("error finding the host\n");
74
+		return -1;
75
+    }
76
+
77
+    memset((char *) &serv_addr, 0, sizeof(serv_addr));
78
+    serv_addr.sin_family = PF_INET;
79
+    memcpy((char *)&serv_addr.sin_addr.s_addr, (char *)server->h_addr,
80
+					server->h_length);
81
+    serv_addr.sin_port = htons(port);
82
+	
83
+    if (connect(sockfd, (const struct sockaddr *)&serv_addr, 
84
+							sizeof(serv_addr)) < 0) 
85
+	{
86
+        LM_ERR("error connecting to the "
87
+						"DIAMETER client\n");
88
+		return -1;
89
+	}	
90
+
91
+	return sockfd;
92
+}
93
+
94
+
95
+
96
+void reset_read_buffer(rd_buf_t *rb)
97
+{
98
+	rb->ret_code		= 0;
99
+	rb->chall_len		= 0;
100
+	if(rb->chall)
101
+		pkg_free(rb->chall);
102
+	rb->chall			= 0;
103
+
104
+	rb->first_4bytes	= 0;
105
+	rb->buf_len			= 0;
106
+	if(rb->buf)
107
+		pkg_free(rb->buf);
108
+	rb->buf				= 0;
109
+}
110
+
111
+/* read from a socket, an AAA message buffer */
112
+int do_read( int socket, rd_buf_t *p)
113
+{
114
+	unsigned char  *ptr;
115
+	unsigned int   wanted_len, len;
116
+	int n;
117
+
118
+	if (p->buf==0)
119
+	{
120
+		wanted_len = sizeof(p->first_4bytes) - p->buf_len;
121
+		ptr = ((unsigned char*)&(p->first_4bytes)) + p->buf_len;
122
+	}
123
+	else
124
+	{
125
+		wanted_len = p->first_4bytes - p->buf_len;
126
+		ptr = p->buf + p->buf_len;
127
+	}
128
+
129
+	while( (n=recv( socket, ptr, wanted_len, MSG_DONTWAIT ))>0 ) 
130
+	{
131
+//		LM_DBG("(sock=%d)  -> n=%d (expected=%d)\n", p->sock,n,wanted_len);
132
+		p->buf_len += n;
133
+		if (n<wanted_len)
134
+		{
135
+			//LM_DBG("only %d bytes read from %d expected\n",n,wanted_len);
136
+			wanted_len -= n;
137
+			ptr += n;
138
+		}
139
+		else 
140
+		{
141
+			if (p->buf==0)
142
+			{
143
+				/* I just finished reading the first 4 bytes from msg */
144
+				len = ntohl(p->first_4bytes)&0x00ffffff;
145
+				if (len<AAA_MSG_HDR_SIZE || len>MAX_AAA_MSG_SIZE)
146
+				{
147
+					LM_ERR(" (sock=%d): invalid message "
148
+						"length read %u (%x)\n", socket, len, p->first_4bytes);
149
+					goto error;
150
+				}
151
+				//LM_DBG("message length = %d(%x)\n",len,len);
152
+				if ( (p->buf=pkg_malloc(len))==0  )
153
+				{
154
+					LM_ERR("no more pkg memory\n");
155
+					goto error;
156
+				}
157
+				*((unsigned int*)p->buf) = p->first_4bytes;
158
+				p->buf_len = sizeof(p->first_4bytes);
159
+				p->first_4bytes = len;
160
+				/* update the reading position and len */
161
+				ptr = p->buf + p->buf_len;
162
+				wanted_len = p->first_4bytes - p->buf_len;
163
+			}
164
+			else
165
+			{
166
+				/* I finished reading the whole message */
167
+				LM_DBG("(sock=%d): whole message read (len=%d)!\n",
168
+					socket, p->first_4bytes);
169
+				return CONN_SUCCESS;
170
+			}
171
+		}
172
+	}
173
+
174
+	if (n==0)
175
+	{
176
+		LM_INFO("(sock=%d): FIN received\n", socket);
177
+		return CONN_CLOSED;
178
+	}
179
+	if ( n==-1 && errno!=EINTR && errno!=EAGAIN )
180
+	{
181
+		LM_ERR(" (sock=%d): n=%d , errno=%d (%s)\n",
182
+			socket, n, errno, strerror(errno));
183
+		goto error;
184
+	}
185
+error:
186
+	return CONN_ERROR;
187
+}
188
+
189
+
190
+/* send a message over an already opened TCP connection */
191
+int tcp_send_recv(int sockfd, char* buf, int len, rd_buf_t* rb, 
192
+					unsigned int waited_id)
193
+{
194
+	int n, number_of_tries;
195
+	fd_set active_fd_set, read_fd_set;
196
+	struct timeval tv;
197
+	unsigned long int result_code;
198
+	AAAMessage *msg;
199
+	AAA_AVP	*avp;
200
+	char serviceType;
201
+	unsigned int m_id;
202
+
203
+	/* try to write the message to the Diameter client */
204
+	while( (n=write(sockfd, buf, len))==-1 ) 
205
+	{
206
+		if (errno==EINTR)
207
+			continue;
208
+		LM_ERR("write returned error: %s\n", strerror(errno));
209
+		return AAA_ERROR;
210
+	}
211
+
212
+	if (n!=len) 
213
+	{
214
+		LM_ERR("write gave no error but wrote less than asked\n");
215
+		return AAA_ERROR;
216
+	}
217
+
218
+	/* wait for the answer a limited amount of time */
219
+	tv.tv_sec = MAX_WAIT_SEC;
220
+	tv.tv_usec = MAX_WAIT_USEC;
221
+
222
+	/* Initialize the set of active sockets. */
223
+	FD_ZERO (&active_fd_set);
224
+	FD_SET (sockfd, &active_fd_set);
225
+	number_of_tries = 0;
226
+
227
+	while(number_of_tries<MAX_TRIES)
228
+	{
229
+		read_fd_set = active_fd_set;
230
+		if (select (sockfd+1, &read_fd_set, NULL, NULL, &tv) < 0)
231
+		{
232
+			LM_ERR("select function failed\n");
233
+			return AAA_ERROR;
234
+		}
235
+/*
236
+		if (!FD_ISSET (sockfd, &read_fd_set))
237
+		{
238
+			LM_ERR("no response message received\n");
239
+//			return AAA_ERROR;
240
+		}
241
+*/
242
+		/* Data arriving on a already-connected socket. */
243
+		reset_read_buffer(rb);
244
+		switch( do_read(sockfd, rb) )
245
+		{
246
+			case CONN_ERROR:
247
+				LM_ERR("error when trying to read from socket\n");
248
+				return AAA_CONN_CLOSED;
249
+			case CONN_CLOSED:
250
+				LM_ERR("connection closed by diameter client!\n");
251
+				return AAA_CONN_CLOSED;
252
+		}
253
+		
254
+		/* obtain the structure corresponding to the message */
255
+		msg = AAATranslateMessage(rb->buf, rb->buf_len, 0);	
256
+		if(!msg)
257
+		{
258
+			LM_ERR("message structure not obtained\n");	
259
+			return AAA_ERROR;
260
+		}
261
+		avp = AAAFindMatchingAVP(msg, NULL, AVP_SIP_MSGID,
262
+								vendorID, AAA_FORWARD_SEARCH);
263
+		if(!avp)
264
+		{
265
+			LM_ERR("AVP_SIP_MSGID not found\n");
266
+			return AAA_ERROR;
267
+		}
268
+		m_id = *((unsigned int*)(avp->data.s));
269
+		LM_DBG("######## m_id=%d\n", m_id);
270
+		if(m_id!=waited_id)
271
+		{
272
+			number_of_tries ++;
273
+			LM_NOTICE("old message received\n");
274
+			continue;
275
+		}
276
+		goto next;
277
+	}
278
+
279
+	LM_ERR("too many old messages received\n");
280
+	return AAA_TIMEOUT;
281
+next:
282
+	/* Finally die correct answer */
283
+	avp = AAAFindMatchingAVP(msg, NULL, AVP_Service_Type,
284
+							vendorID, AAA_FORWARD_SEARCH);
285
+	if(!avp)
286
+	{
287
+		LM_ERR("AVP_Service_Type not found\n");
288
+		return AAA_ERROR;
289
+	}
290
+	serviceType = avp->data.s[0];
291
+
292
+	result_code = ntohl(*((unsigned long int*)(msg->res_code->data.s)));
293
+	switch(result_code)
294
+	{
295
+		case AAA_SUCCESS:					/* 2001 */
296
+			rb->ret_code = AAA_AUTHORIZED;
297
+			break;
298
+		case AAA_AUTHENTICATION_REJECTED:	/* 4001 */
299
+			if(serviceType!=SIP_AUTH_SERVICE)
300
+			{
301
+				rb->ret_code = AAA_NOT_AUTHORIZED;
302
+				break;
303
+			}
304
+			avp = AAAFindMatchingAVP(msg, NULL, AVP_Challenge,
305
+							vendorID, AAA_FORWARD_SEARCH);
306
+			if(!avp)
307
+			{
308
+				LM_ERR("AVP_Response not found\n");
309
+				rb->ret_code = AAA_SRVERR;
310
+				break;
311
+			}
312
+			rb->chall_len=avp->data.len;
313
+			rb->chall = (unsigned char*)pkg_malloc(avp->data.len*sizeof(unsigned char));
314
+			if(rb->chall == NULL)
315
+			{
316
+				LM_ERR("no more pkg memory\n");
317
+				rb->ret_code = AAA_SRVERR;
318
+				break;
319
+			}
320
+			memcpy(rb->chall, avp->data.s, avp->data.len);
321
+			rb->ret_code = AAA_CHALENGE;
322
+			break;
323
+		case AAA_AUTHORIZATION_REJECTED:	/* 5003 */
324
+			rb->ret_code = AAA_NOT_AUTHORIZED;
325
+			break;
326
+		default:							/* error */
327
+			rb->ret_code = AAA_SRVERR;
328
+	}
329
+	
330
+    return rb->ret_code;	
331
+}
332
+void close_tcp_connection(int sfd)
333
+{
334
+	shutdown(sfd, 2);
335
+}
336
+
337
+