Asterisk - The Open Source Telephony Project  18.5.0
channels/sip/security_events.c
Go to the documentation of this file.
1 /*
2  * Asterisk -- An open source telephony toolkit.
3  *
4  * Copyright (C) 2012, Digium, Inc.
5  *
6  * Michael L. Young <[email protected]>
7  *
8  * See http://www.asterisk.org for more information about
9  * the Asterisk project. Please do not directly contact
10  * any of the maintainers of this project for assistance;
11  * the project provides a web site, mailing lists and IRC
12  * channels for your use.
13  *
14  * This program is free software, distributed under the terms of
15  * the GNU General Public License Version 2. See the LICENSE file
16  * at the top of the source tree.
17  */
18 
19 /*!
20  * \file
21  *
22  * \brief Generate security events in the SIP channel
23  *
24  * \author Michael L. Young <[email protected]>
25  */
26 
27 /*** MODULEINFO
28  <support_level>deprecated</support_level>
29  ***/
30 
31 #include "asterisk.h"
32 
33 #include "include/sip.h"
35 
36 /*! \brief Determine transport type used to receive request*/
37 
39 {
40  return p->socket.type;
41 }
42 
43 void sip_report_invalid_peer(const struct sip_pvt *p)
44 {
45  char session_id[32];
46 
47  struct ast_security_event_inval_acct_id inval_acct_id = {
50  .common.service = "SIP",
51  .common.account_id = p->exten,
52  .common.local_addr = {
53  .addr = &p->ourip,
54  .transport = security_event_get_transport(p)
55  },
56  .common.remote_addr = {
57  .addr = &p->sa,
58  .transport = security_event_get_transport(p)
59  },
60  .common.session_id = session_id,
61  };
62 
63  snprintf(session_id, sizeof(session_id), "%p", p);
64 
65  ast_security_event_report(AST_SEC_EVT(&inval_acct_id));
66 }
67 
68 void sip_report_failed_acl(const struct sip_pvt *p, const char *aclname)
69 {
70  char session_id[32];
71 
72  struct ast_security_event_failed_acl failed_acl_event = {
74  .common.version = AST_SECURITY_EVENT_FAILED_ACL_VERSION,
75  .common.service = "SIP",
76  .common.account_id = p->exten,
77  .common.local_addr = {
78  .addr = &p->ourip,
79  .transport = security_event_get_transport(p)
80  },
81  .common.remote_addr = {
82  .addr = &p->sa,
83  .transport = security_event_get_transport(p)
84  },
85  .common.session_id = session_id,
86  .acl_name = aclname,
87  };
88 
89  snprintf(session_id, sizeof(session_id), "%p", p);
90 
91  ast_security_event_report(AST_SEC_EVT(&failed_acl_event));
92 }
93 
94 void sip_report_inval_password(const struct sip_pvt *p, const char *response_challenge, const char *response_hash)
95 {
96  char session_id[32];
97 
98  struct ast_security_event_inval_password inval_password = {
101  .common.service = "SIP",
102  .common.account_id = p->exten,
103  .common.local_addr = {
104  .addr = &p->ourip,
105  .transport = security_event_get_transport(p)
106  },
107  .common.remote_addr = {
108  .addr = &p->sa,
109  .transport = security_event_get_transport(p)
110  },
111  .common.session_id = session_id,
112 
113  .challenge = p->nonce,
114  .received_challenge = response_challenge,
115  .received_hash = response_hash,
116  };
117 
118  snprintf(session_id, sizeof(session_id), "%p", p);
119 
120  ast_security_event_report(AST_SEC_EVT(&inval_password));
121 }
122 
123 void sip_report_auth_success(const struct sip_pvt *p, uint32_t using_password)
124 {
125  char session_id[32];
126 
127  struct ast_security_event_successful_auth successful_auth = {
130  .common.service = "SIP",
131  .common.account_id = p->exten,
132  .common.local_addr = {
133  .addr = &p->ourip,
134  .transport = security_event_get_transport(p)
135  },
136  .common.remote_addr = {
137  .addr = &p->sa,
138  .transport = security_event_get_transport(p)
139  },
140  .common.session_id = session_id,
141  .using_password = using_password,
142  };
143 
144  snprintf(session_id, sizeof(session_id), "%p", p);
145 
146  ast_security_event_report(AST_SEC_EVT(&successful_auth));
147 }
148 
149 void sip_report_session_limit(const struct sip_pvt *p)
150 {
151  char session_id[32];
152 
153  struct ast_security_event_session_limit session_limit = {
156  .common.service = "SIP",
157  .common.account_id = p->exten,
158  .common.local_addr = {
159  .addr = &p->ourip,
160  .transport = security_event_get_transport(p)
161  },
162  .common.remote_addr = {
163  .addr = &p->sa,
164  .transport = security_event_get_transport(p)
165  },
166  .common.session_id = session_id,
167  };
168 
169  snprintf(session_id, sizeof(session_id), "%p", p);
170 
171  ast_security_event_report(AST_SEC_EVT(&session_limit));
172 }
173 
174 void sip_report_failed_challenge_response(const struct sip_pvt *p, const char *response, const char *expected_response)
175 {
176  char session_id[32];
177  char account_id[256];
178 
179  struct ast_security_event_chal_resp_failed chal_resp_failed = {
182  .common.service = "SIP",
183  .common.account_id = account_id,
184  .common.local_addr = {
185  .addr = &p->ourip,
186  .transport = security_event_get_transport(p)
187  },
188  .common.remote_addr = {
189  .addr = &p->sa,
190  .transport = security_event_get_transport(p)
191  },
192  .common.session_id = session_id,
193 
194  .challenge = p->nonce,
195  .response = response,
196  .expected_response = expected_response,
197  };
198 
199  if (!ast_strlen_zero(p->from)) { /* When dialing, show account making call */
200  ast_copy_string(account_id, p->from, sizeof(account_id));
201  } else {
202  ast_copy_string(account_id, p->exten, sizeof(account_id));
203  }
204 
205  snprintf(session_id, sizeof(session_id), "%p", p);
206 
207  ast_security_event_report(AST_SEC_EVT(&chal_resp_failed));
208 }
209 
210 void sip_report_chal_sent(const struct sip_pvt *p)
211 {
212  char session_id[32];
213  char account_id[256];
214 
215  struct ast_security_event_chal_sent chal_sent = {
217  .common.version = AST_SECURITY_EVENT_CHAL_SENT_VERSION,
218  .common.service = "SIP",
219  .common.account_id = account_id,
220  .common.local_addr = {
221  .addr = &p->ourip,
222  .transport = security_event_get_transport(p)
223  },
224  .common.remote_addr = {
225  .addr = &p->sa,
226  .transport = security_event_get_transport(p)
227  },
228  .common.session_id = session_id,
229 
230  .challenge = p->nonce,
231  };
232 
233  if (!ast_strlen_zero(p->from)) { /* When dialing, show account making call */
234  ast_copy_string(account_id, p->from, sizeof(account_id));
235  } else {
236  ast_copy_string(account_id, p->exten, sizeof(account_id));
237  }
238 
239  snprintf(session_id, sizeof(session_id), "%p", p);
240 
242 }
243 
244 void sip_report_inval_transport(const struct sip_pvt *p, const char *transport)
245 {
246  char session_id[32];
247 
248  struct ast_security_event_inval_transport inval_transport = {
251  .common.service = "SIP",
252  .common.account_id = p->exten,
253  .common.local_addr = {
254  .addr = &p->ourip,
255  .transport = security_event_get_transport(p)
256  },
257  .common.remote_addr = {
258  .addr = &p->sa,
259  .transport = security_event_get_transport(p)
260  },
261  .common.session_id = session_id,
262 
263  .transport = transport,
264  };
265 
266  snprintf(session_id, sizeof(session_id), "%p", p);
267 
268  ast_security_event_report(AST_SEC_EVT(&inval_transport));
269 }
270 
271 int sip_report_security_event(const char *peer, struct ast_sockaddr *addr, const struct sip_pvt *p,
272  const struct sip_request *req, const int res)
273 {
274 
275  struct sip_peer *peer_report;
276  enum check_auth_result res_report = res;
277  struct ast_str *buf;
278  char *c;
279  const char *authtoken;
280  char *reqheader, *respheader;
281  int result = 0;
282  char aclname[256];
283  struct digestkeys keys[] = {
284  [K_RESP] = { "response=", "" },
285  [K_URI] = { "uri=", "" },
286  [K_USER] = { "username=", "" },
287  [K_NONCE] = { "nonce=", "" },
288  [K_LAST] = { NULL, NULL}
289  };
290 
291  peer_report = sip_find_peer(peer, addr, TRUE, FINDPEERS, FALSE, p->socket.type);
292 
293  switch(res_report) {
294  case AUTH_DONT_KNOW:
295  break;
296  case AUTH_SUCCESSFUL:
297  if (peer_report) {
298  if (ast_strlen_zero(peer_report->secret) && ast_strlen_zero(peer_report->md5secret)) {
300  } else {
302  }
303  }
304  break;
305  case AUTH_CHALLENGE_SENT:
307  break;
308  case AUTH_SECRET_FAILED:
310  sip_auth_headers(WWW_AUTH, &respheader, &reqheader);
311  authtoken = sip_get_header(req, reqheader);
313  ast_str_set(&buf, 0, "%s", authtoken);
314  c = ast_str_buffer(buf);
315 
316  sip_digest_parser(c, keys);
317 
318  if (res_report == AUTH_SECRET_FAILED) {
319  sip_report_inval_password(p, keys[K_NONCE].s, keys[K_RESP].s);
320  } else {
321  if (peer_report) {
322  sip_report_failed_challenge_response(p, keys[K_USER].s, peer_report->username);
323  }
324  }
325  break;
326  case AUTH_NOT_FOUND:
327  /* with sip_cfg.alwaysauthreject on, generates 2 events */
329  break;
330  case AUTH_UNKNOWN_DOMAIN:
331  snprintf(aclname, sizeof(aclname), "domain_must_match");
332  sip_report_failed_acl(p, aclname);
333  break;
335  snprintf(aclname, sizeof(aclname), "peer_not_dynamic");
336  sip_report_failed_acl(p, aclname);
337  break;
338  case AUTH_ACL_FAILED:
339  /* with sip_cfg.alwaysauthreject on, generates 2 events */
340  snprintf(aclname, sizeof(aclname), "device_must_match_acl");
341  sip_report_failed_acl(p, aclname);
342  break;
343  case AUTH_BAD_TRANSPORT:
345  break;
346  case AUTH_RTP_FAILED:
347  break;
348  case AUTH_SESSION_LIMIT:
350  break;
351  }
352 
353  if (peer_report) {
354  sip_unref_peer(peer_report, "sip_report_security_event: sip_unref_peer: from handle_incoming");
355  }
356 
357  return result;
358 }
const char * sip_get_header(const struct sip_request *req, const char *name)
Get header from SIP request.
Definition: chan_sip.c:8600
chan_sip header file
Definition: sip.h:703
uint32_t using_password
Using password - if a password was used or not.
An attempt at basic password authentication failed.
enum ast_security_event_type event_type
The security event sub-type.
struct ast_security_event_common common
Common security event descriptor elements.
Asterisk main include file. File version handling, generic pbx functions.
Generate security events in the SIP channel.
#define FALSE
Definition: app_minivm.c:521
FYI FWIW, Successful authentication has occurred.
struct sip_peer * sip_find_peer(const char *peer, struct ast_sockaddr *addr, int realtime, int which_objects, int devstate_only, int transport)
Locate device by name or ip address.
Definition: chan_sip.c:5851
const char * expected_response
Response expected to be received.
void sip_auth_headers(enum sip_auth_type code, char **header, char **respheader)
return the request and response header for a 401 or 407 code
Definition: chan_sip.c:16549
static struct ast_threadstorage check_auth_buf
Definition: sip.h:1883
An attempt at challenge/response auth failed.
char buf[BUFSIZE]
Definition: eagi_proxy.c:66
const char * transport
Attempted transport.
ast_transport
Definition: netsock2.h:59
void sip_report_auth_success(const struct sip_pvt *p, uint32_t using_password)
char * ast_str_buffer(const struct ast_str *buf)
Returns the string buffer within the ast_str buf.
Definition: strings.h:714
struct sip_socket socket
Definition: sip.h:1066
void sip_report_inval_transport(const struct sip_pvt *p, const char *transport)
void sip_report_invalid_peer(const struct sip_pvt *p)
#define AST_SECURITY_EVENT_CHAL_SENT_VERSION
Event descriptor version.
const char * sip_get_transport(enum ast_transport t)
Return transport as string.
Definition: chan_sip.c:3725
Checking against an IP access control list failed.
struct ast_sockaddr ourip
Definition: sip.h:1136
check_auth_result
Authentication result from check_auth* functions.
Definition: sip.h:517
struct ast_security_event_common common
Common security event descriptor elements.
void sip_report_failed_challenge_response(const struct sip_pvt *p, const char *response, const char *expected_response)
A challenge was sent out.
const char * response
Response received.
const ast_string_field from
Definition: sip.h:1063
static struct test_val c
struct ast_security_event_common common
Common security event descriptor elements.
static enum ast_transport security_event_get_transport(const struct sip_pvt *p)
Determine transport type used to receive request.
#define NULL
Definition: resample.c:96
#define AST_SECURITY_EVENT_SUCCESSFUL_AUTH_VERSION
Event descriptor version.
Socket address structure.
Definition: netsock2.h:97
#define AST_SEC_EVT(e)
const ast_string_field nonce
Definition: sip.h:1063
#define ast_strlen_zero(foo)
Definition: strings.h:52
void sip_digest_parser(char *c, struct digestkeys *keys)
Takes the digest response and parses it.
Definition: chan_sip.c:17309
int ast_str_set(struct ast_str **buf, ssize_t max_len, const char *fmt,...)
Set a dynamic string using variable arguments.
Definition: strings.h:1065
An attempt at basic password auth failed.
struct ast_sockaddr sa
Definition: sip.h:1125
int sip_report_security_event(const char *peer, struct ast_sockaddr *addr, const struct sip_pvt *p, const struct sip_request *req, const int res)
Request denied because of a session limit.
const ast_string_field exten
Definition: sip.h:1063
#define AST_SECURITY_EVENT_FAILED_ACL_VERSION
Event descriptor version.
const ast_string_field username
Definition: sip.h:1306
Challenge was sent out, informational.
struct ast_security_event_common common
Common security event descriptor elements.
const ast_string_field md5secret
Definition: sip.h:1306
struct ast_security_event_common common
Common security event descriptor elements.
void sip_report_session_limit(const struct sip_pvt *p)
Attempt to contact peer on invalid transport.
#define AST_SECURITY_EVENT_INVAL_ACCT_ID_VERSION
Event descriptor version.
The descriptor of a dynamic string XXX storage will be optimized later if needed We use the ts field ...
Definition: strings.h:584
Definition: sip.h:707
An attempt at challenge/response authentication failed.
Structure used for each SIP dialog, ie. a call, a registration, a subscribe. Created and initialized ...
Definition: sip.h:1005
#define sip_unref_peer(peer, tag)
Definition: sip.h:1895
Definition: sip.h:705
#define FINDPEERS
Definition: sip.h:53
Structure for SIP peer data, we place calls to peers if registered or fixed IP address (host) ...
Definition: sip.h:1273
Definition: sip.h:504
struct ast_security_event_common common
Common security event descriptor elements.
sip_request: The data grabbed from the UDP socket
Definition: sip.h:829
Invalid account ID specified (invalid username, for example)
void sip_report_chal_sent(const struct sip_pvt *p)
const char * s
Definition: sip.h:1880
struct ast_security_event_common common
Common security event descriptor elements.
#define AST_SECURITY_EVENT_INVAL_PASSWORD_VERSION
Event descriptor version.
#define AST_SECURITY_EVENT_INVAL_TRANSPORT_VERSION
Event descriptor version.
struct ast_security_event_common common
Common security event descriptor elements.
enum ast_transport type
Definition: sip.h:798
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:401
#define TRUE
Definition: app_minivm.c:518
const ast_string_field secret
Definition: sip.h:1306
static PGresult * result
Definition: cel_pgsql.c:88
void sip_report_inval_password(const struct sip_pvt *p, const char *response_challenge, const char *response_hash)
Definition: sip.h:704
void sip_report_failed_acl(const struct sip_pvt *p, const char *aclname)
#define AST_SECURITY_EVENT_CHAL_RESP_FAILED_VERSION
Event descriptor version.
struct sip_socket socket
Definition: sip.h:846
struct ast_str * ast_str_thread_get(struct ast_threadstorage *ts, size_t init_len)
Retrieve a thread locally stored dynamic string.
Definition: strings.h:861
int ast_security_event_report(const struct ast_security_event_common *sec)
Report a security event.
#define CHECK_AUTH_BUF_INITLEN
Definition: sip.h:401
#define AST_SECURITY_EVENT_SESSION_LIMIT_VERSION
Event descriptor version.
Definition: sip.h:706
An attempt to contact a peer on an invalid transport.