| 
									
										
										
										
											2011-09-22 16:35:20 +00:00
										 |  |  | /*
 | 
					
						
							|  |  |  |  * Asterisk -- An open source telephony toolkit. | 
					
						
							|  |  |  |  * | 
					
						
							| 
									
										
										
										
											2012-04-16 21:20:50 +00:00
										 |  |  |  * Copyright (C) 2012, Digium, Inc. | 
					
						
							| 
									
										
										
										
											2011-09-22 16:35:20 +00:00
										 |  |  |  * | 
					
						
							|  |  |  |  * Michael L. Young <elgueromexicano@gmail.com> | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * See http://www.asterisk.org for more information about
 | 
					
						
							|  |  |  |  * the Asterisk project. Please do not directly contact | 
					
						
							|  |  |  |  * any of the maintainers of this project for assistance; | 
					
						
							|  |  |  |  * the project provides a web site, mailing lists and IRC | 
					
						
							|  |  |  |  * channels for your use. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * This program is free software, distributed under the terms of | 
					
						
							|  |  |  |  * the GNU General Public License Version 2. See the LICENSE file | 
					
						
							|  |  |  |  * at the top of the source tree. | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /*!
 | 
					
						
							|  |  |  |  * \file | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * \brief Generate security events in the SIP channel | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * \author Michael L. Young <elgueromexicano@gmail.com> | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-06-15 16:20:16 +00:00
										 |  |  | /*** MODULEINFO
 | 
					
						
							| 
									
										
										
										
											2018-10-10 08:09:15 -04:00
										 |  |  | 	<support_level>deprecated</support_level> | 
					
						
							| 
									
										
										
										
											2012-06-15 16:20:16 +00:00
										 |  |  |  ***/ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-09-22 16:35:20 +00:00
										 |  |  | #include "asterisk.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include "include/sip.h"
 | 
					
						
							|  |  |  | #include "include/security_events.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /*! \brief Determine transport type used to receive request*/ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-05-17 17:36:10 +00:00
										 |  |  | static enum ast_transport security_event_get_transport(const struct sip_pvt *p) | 
					
						
							| 
									
										
										
										
											2011-09-22 16:35:20 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2013-05-17 17:36:10 +00:00
										 |  |  | 	return p->socket.type; | 
					
						
							| 
									
										
										
										
											2011-09-22 16:35:20 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void sip_report_invalid_peer(const struct sip_pvt *p) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	char session_id[32]; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	struct ast_security_event_inval_acct_id inval_acct_id = { | 
					
						
							|  |  |  | 		.common.event_type = AST_SECURITY_EVENT_INVAL_ACCT_ID, | 
					
						
							|  |  |  | 		.common.version    = AST_SECURITY_EVENT_INVAL_ACCT_ID_VERSION, | 
					
						
							|  |  |  | 		.common.service    = "SIP", | 
					
						
							|  |  |  | 		.common.account_id = p->exten, | 
					
						
							|  |  |  | 		.common.local_addr = { | 
					
						
							| 
									
										
										
										
											2012-04-16 21:20:50 +00:00
										 |  |  | 			.addr      = &p->ourip, | 
					
						
							| 
									
										
										
										
											2011-09-22 16:35:20 +00:00
										 |  |  | 			.transport = security_event_get_transport(p) | 
					
						
							|  |  |  | 		}, | 
					
						
							|  |  |  | 		.common.remote_addr = { | 
					
						
							| 
									
										
										
										
											2012-04-16 21:20:50 +00:00
										 |  |  | 			.addr       = &p->sa, | 
					
						
							| 
									
										
										
										
											2011-09-22 16:35:20 +00:00
										 |  |  | 			.transport = security_event_get_transport(p) | 
					
						
							|  |  |  | 		}, | 
					
						
							|  |  |  | 		.common.session_id = session_id, | 
					
						
							|  |  |  | 	}; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	snprintf(session_id, sizeof(session_id), "%p", p); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	ast_security_event_report(AST_SEC_EVT(&inval_acct_id)); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void sip_report_failed_acl(const struct sip_pvt *p, const char *aclname) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |         char session_id[32]; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         struct ast_security_event_failed_acl failed_acl_event = { | 
					
						
							|  |  |  |                 .common.event_type  = AST_SECURITY_EVENT_FAILED_ACL, | 
					
						
							|  |  |  |                 .common.version     = AST_SECURITY_EVENT_FAILED_ACL_VERSION, | 
					
						
							|  |  |  |                 .common.service     = "SIP", | 
					
						
							|  |  |  |                 .common.account_id  = p->exten, | 
					
						
							|  |  |  |                 .common.local_addr  = { | 
					
						
							| 
									
										
										
										
											2012-04-16 21:20:50 +00:00
										 |  |  |                         .addr       = &p->ourip, | 
					
						
							| 
									
										
										
										
											2011-09-22 16:35:20 +00:00
										 |  |  |                         .transport  = security_event_get_transport(p) | 
					
						
							|  |  |  |                 }, | 
					
						
							|  |  |  |                 .common.remote_addr = { | 
					
						
							| 
									
										
										
										
											2012-04-16 21:20:50 +00:00
										 |  |  |                         .addr       = &p->sa, | 
					
						
							| 
									
										
										
										
											2011-09-22 16:35:20 +00:00
										 |  |  |                         .transport  = security_event_get_transport(p) | 
					
						
							|  |  |  |                 }, | 
					
						
							|  |  |  |                 .common.session_id  = session_id, | 
					
						
							|  |  |  |                 .acl_name           = aclname, | 
					
						
							|  |  |  |         }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         snprintf(session_id, sizeof(session_id), "%p", p); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         ast_security_event_report(AST_SEC_EVT(&failed_acl_event)); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void sip_report_inval_password(const struct sip_pvt *p, const char *response_challenge, const char *response_hash) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |         char session_id[32]; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         struct ast_security_event_inval_password inval_password = { | 
					
						
							|  |  |  |                 .common.event_type  = AST_SECURITY_EVENT_INVAL_PASSWORD, | 
					
						
							|  |  |  |                 .common.version     = AST_SECURITY_EVENT_INVAL_PASSWORD_VERSION, | 
					
						
							|  |  |  |                 .common.service     = "SIP", | 
					
						
							|  |  |  |                 .common.account_id  = p->exten, | 
					
						
							|  |  |  |                 .common.local_addr  = { | 
					
						
							| 
									
										
										
										
											2012-04-16 21:20:50 +00:00
										 |  |  |                         .addr       = &p->ourip, | 
					
						
							| 
									
										
										
										
											2011-09-22 16:35:20 +00:00
										 |  |  |                         .transport  = security_event_get_transport(p) | 
					
						
							|  |  |  |                 }, | 
					
						
							|  |  |  |                 .common.remote_addr = { | 
					
						
							| 
									
										
										
										
											2012-04-16 21:20:50 +00:00
										 |  |  |                         .addr       = &p->sa, | 
					
						
							| 
									
										
										
										
											2011-09-22 16:35:20 +00:00
										 |  |  |                         .transport  = security_event_get_transport(p) | 
					
						
							|  |  |  |                 }, | 
					
						
							|  |  |  |                 .common.session_id  = session_id, | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
											  
											
												Clean up chan_sip
This clean up was broken out from
https://reviewboard.asterisk.org/r/1976/ and addresses the following:
 - struct sip_refer converted to use the stringfields API.
 - sip_{refer|notify}_allocate -> sip_{notify|refer}_alloc to match
   other *alloc functions.
 - Replace get_msg_text, get_msg_text2 and get_pidf_body -> No, not
   get_pidf_msg_text_body3 but get_content, to match add_content.
 - get_body doesn't get the request body, renamed to get_content_line.
 - get_body_by_line doesn't get the body line, and is just a simple if
   test. Moved code inline and removed function.
 - Remove camelCase in struct sip_peer peer state variables,
   onHold -> onhold, inUse -> inuse, inRinging -> ringing.
 - Remove camelCase in struct sip_request rlPart1 -> rlpart1,
   rlPart2 -> rlpart2.
 - Rename instances of pvt->randdata to pvt->nonce because that is what
   it is, no need to update struct sip_pvt because _it already has a
   nonce field_.
 - Removed struct sip_pvt randdata stringfield.
 - Remove useless (and inconsistent) 'header' suffix on variables in
   handle_request_subscribe.
 - Use ast_strdupa on Event header in handle_request_subscribe to avoid
   overly complicated strncmp calls to find the event package.
 - Move get_destination check in handle_request_subscribe to avoid
   duplicate checking for packages that don't need it.
 - Move extension state callback management in handle_request_subscribe
   to avoid duplicate checking for packages that don't need it.
 - Remove duplicate append_date prototype.
 - Rename append_date -> add_date to match other add_xxx functions.
 - Added add_expires helper function, removed code that manually added
   expires header.
 - Remove _header suffix on add_diversion_header (no other header adding
   functions have this).
 - Don't pass req->debug to request handle_request_XXXXX handlers if req
   is also being passed.
 - Don't pass req->ignore to check_auth as req is already being passed.
 - Don't create a subscription in handle_request_subscribe if
   p->expiry == 0.
 - Don't walk of the back of referred_by_name when splitting string in
   get_refer_info
 - Remove duplicate check for no dialog in handle_incoming when
   sipmethod == SIP_REFER, handle_request_refer checks for that.
Review: https://reviewboard.asterisk.org/r/1993/
Patch-by: gareth
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@370636 65c4cc65-6c06-0410-ace0-fbb531ad65f3
											
										 
											2012-07-31 19:10:41 +00:00
										 |  |  | 		.challenge	    = p->nonce, | 
					
						
							| 
									
										
										
										
											2011-09-22 16:35:20 +00:00
										 |  |  | 		.received_challenge = response_challenge, | 
					
						
							|  |  |  | 		.received_hash	    = response_hash, | 
					
						
							|  |  |  |         }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         snprintf(session_id, sizeof(session_id), "%p", p); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         ast_security_event_report(AST_SEC_EVT(&inval_password)); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-12-01 13:54:26 -06:00
										 |  |  | void sip_report_auth_success(const struct sip_pvt *p, uint32_t using_password) | 
					
						
							| 
									
										
										
										
											2011-09-22 16:35:20 +00:00
										 |  |  | { | 
					
						
							|  |  |  |         char session_id[32]; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         struct ast_security_event_successful_auth successful_auth = { | 
					
						
							|  |  |  |                 .common.event_type  = AST_SECURITY_EVENT_SUCCESSFUL_AUTH, | 
					
						
							|  |  |  |                 .common.version     = AST_SECURITY_EVENT_SUCCESSFUL_AUTH_VERSION, | 
					
						
							|  |  |  |                 .common.service     = "SIP", | 
					
						
							|  |  |  |                 .common.account_id  = p->exten, | 
					
						
							|  |  |  |                 .common.local_addr  = { | 
					
						
							| 
									
										
										
										
											2012-04-16 21:20:50 +00:00
										 |  |  |                         .addr       = &p->ourip, | 
					
						
							| 
									
										
										
										
											2011-09-22 16:35:20 +00:00
										 |  |  |                         .transport  = security_event_get_transport(p) | 
					
						
							|  |  |  |                 }, | 
					
						
							|  |  |  |                 .common.remote_addr = { | 
					
						
							| 
									
										
										
										
											2012-04-16 21:20:50 +00:00
										 |  |  |                         .addr       = &p->sa, | 
					
						
							| 
									
										
										
										
											2011-09-22 16:35:20 +00:00
										 |  |  |                         .transport  = security_event_get_transport(p) | 
					
						
							|  |  |  |                 }, | 
					
						
							|  |  |  |                 .common.session_id  = session_id, | 
					
						
							|  |  |  |                 .using_password     = using_password, | 
					
						
							|  |  |  |         }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         snprintf(session_id, sizeof(session_id), "%p", p); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         ast_security_event_report(AST_SEC_EVT(&successful_auth)); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void sip_report_session_limit(const struct sip_pvt *p) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |         char session_id[32]; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         struct ast_security_event_session_limit session_limit = { | 
					
						
							|  |  |  |                 .common.event_type = AST_SECURITY_EVENT_SESSION_LIMIT, | 
					
						
							|  |  |  |                 .common.version    = AST_SECURITY_EVENT_SESSION_LIMIT_VERSION, | 
					
						
							|  |  |  |                 .common.service    = "SIP", | 
					
						
							|  |  |  |                 .common.account_id = p->exten, | 
					
						
							|  |  |  |                 .common.local_addr = { | 
					
						
							| 
									
										
										
										
											2012-04-16 21:20:50 +00:00
										 |  |  |                         .addr      = &p->ourip, | 
					
						
							| 
									
										
										
										
											2011-09-22 16:35:20 +00:00
										 |  |  |                         .transport = security_event_get_transport(p) | 
					
						
							|  |  |  |                 }, | 
					
						
							|  |  |  |                 .common.remote_addr = { | 
					
						
							| 
									
										
										
										
											2012-04-16 21:20:50 +00:00
										 |  |  |                         .addr      = &p->sa, | 
					
						
							| 
									
										
										
										
											2011-09-22 16:35:20 +00:00
										 |  |  |                         .transport = security_event_get_transport(p) | 
					
						
							|  |  |  |                 }, | 
					
						
							|  |  |  |                 .common.session_id = session_id, | 
					
						
							|  |  |  |         }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         snprintf(session_id, sizeof(session_id), "%p", p); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         ast_security_event_report(AST_SEC_EVT(&session_limit)); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void sip_report_failed_challenge_response(const struct sip_pvt *p, const char *response, const char *expected_response) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2012-04-16 21:20:50 +00:00
										 |  |  | 	char session_id[32]; | 
					
						
							| 
									
										
										
										
											2011-09-22 16:35:20 +00:00
										 |  |  | 	char account_id[256]; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	struct ast_security_event_chal_resp_failed chal_resp_failed = { | 
					
						
							|  |  |  |                 .common.event_type = AST_SECURITY_EVENT_CHAL_RESP_FAILED, | 
					
						
							|  |  |  |                 .common.version    = AST_SECURITY_EVENT_CHAL_RESP_FAILED_VERSION, | 
					
						
							|  |  |  |                 .common.service    = "SIP", | 
					
						
							|  |  |  |                 .common.account_id = account_id, | 
					
						
							|  |  |  |                 .common.local_addr = { | 
					
						
							| 
									
										
										
										
											2012-04-16 21:20:50 +00:00
										 |  |  |                         .addr      = &p->ourip, | 
					
						
							| 
									
										
										
										
											2011-09-22 16:35:20 +00:00
										 |  |  |                         .transport = security_event_get_transport(p) | 
					
						
							|  |  |  |                 }, | 
					
						
							|  |  |  |                 .common.remote_addr = { | 
					
						
							| 
									
										
										
										
											2012-04-16 21:20:50 +00:00
										 |  |  |                         .addr      = &p->sa, | 
					
						
							| 
									
										
										
										
											2011-09-22 16:35:20 +00:00
										 |  |  |                         .transport = security_event_get_transport(p) | 
					
						
							|  |  |  |                 }, | 
					
						
							|  |  |  |                 .common.session_id = session_id, | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
											  
											
												Clean up chan_sip
This clean up was broken out from
https://reviewboard.asterisk.org/r/1976/ and addresses the following:
 - struct sip_refer converted to use the stringfields API.
 - sip_{refer|notify}_allocate -> sip_{notify|refer}_alloc to match
   other *alloc functions.
 - Replace get_msg_text, get_msg_text2 and get_pidf_body -> No, not
   get_pidf_msg_text_body3 but get_content, to match add_content.
 - get_body doesn't get the request body, renamed to get_content_line.
 - get_body_by_line doesn't get the body line, and is just a simple if
   test. Moved code inline and removed function.
 - Remove camelCase in struct sip_peer peer state variables,
   onHold -> onhold, inUse -> inuse, inRinging -> ringing.
 - Remove camelCase in struct sip_request rlPart1 -> rlpart1,
   rlPart2 -> rlpart2.
 - Rename instances of pvt->randdata to pvt->nonce because that is what
   it is, no need to update struct sip_pvt because _it already has a
   nonce field_.
 - Removed struct sip_pvt randdata stringfield.
 - Remove useless (and inconsistent) 'header' suffix on variables in
   handle_request_subscribe.
 - Use ast_strdupa on Event header in handle_request_subscribe to avoid
   overly complicated strncmp calls to find the event package.
 - Move get_destination check in handle_request_subscribe to avoid
   duplicate checking for packages that don't need it.
 - Move extension state callback management in handle_request_subscribe
   to avoid duplicate checking for packages that don't need it.
 - Remove duplicate append_date prototype.
 - Rename append_date -> add_date to match other add_xxx functions.
 - Added add_expires helper function, removed code that manually added
   expires header.
 - Remove _header suffix on add_diversion_header (no other header adding
   functions have this).
 - Don't pass req->debug to request handle_request_XXXXX handlers if req
   is also being passed.
 - Don't pass req->ignore to check_auth as req is already being passed.
 - Don't create a subscription in handle_request_subscribe if
   p->expiry == 0.
 - Don't walk of the back of referred_by_name when splitting string in
   get_refer_info
 - Remove duplicate check for no dialog in handle_incoming when
   sipmethod == SIP_REFER, handle_request_refer checks for that.
Review: https://reviewboard.asterisk.org/r/1993/
Patch-by: gareth
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@370636 65c4cc65-6c06-0410-ace0-fbb531ad65f3
											
										 
											2012-07-31 19:10:41 +00:00
										 |  |  |                 .challenge         = p->nonce, | 
					
						
							| 
									
										
										
										
											2011-09-22 16:35:20 +00:00
										 |  |  |                 .response          = response, | 
					
						
							|  |  |  |                 .expected_response = expected_response, | 
					
						
							|  |  |  |         }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (!ast_strlen_zero(p->from)) { /* When dialing, show account making call */ | 
					
						
							|  |  |  |                 ast_copy_string(account_id, p->from, sizeof(account_id)); | 
					
						
							|  |  |  |         } else { | 
					
						
							|  |  |  |                 ast_copy_string(account_id, p->exten, sizeof(account_id)); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         snprintf(session_id, sizeof(session_id), "%p", p); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         ast_security_event_report(AST_SEC_EVT(&chal_resp_failed)); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void sip_report_chal_sent(const struct sip_pvt *p) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2012-04-16 21:20:50 +00:00
										 |  |  | 	char session_id[32]; | 
					
						
							| 
									
										
										
										
											2011-09-22 16:35:20 +00:00
										 |  |  | 	char account_id[256]; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-04-16 21:20:50 +00:00
										 |  |  | 	struct ast_security_event_chal_sent chal_sent = { | 
					
						
							| 
									
										
										
										
											2011-09-22 16:35:20 +00:00
										 |  |  |                 .common.event_type = AST_SECURITY_EVENT_CHAL_SENT, | 
					
						
							|  |  |  |                 .common.version    = AST_SECURITY_EVENT_CHAL_SENT_VERSION, | 
					
						
							|  |  |  |                 .common.service    = "SIP", | 
					
						
							|  |  |  |                 .common.account_id = account_id, | 
					
						
							|  |  |  |                 .common.local_addr = { | 
					
						
							| 
									
										
										
										
											2012-04-16 21:20:50 +00:00
										 |  |  |                         .addr      = &p->ourip, | 
					
						
							| 
									
										
										
										
											2011-09-22 16:35:20 +00:00
										 |  |  |                         .transport = security_event_get_transport(p) | 
					
						
							|  |  |  |                 }, | 
					
						
							|  |  |  |                 .common.remote_addr = { | 
					
						
							| 
									
										
										
										
											2012-04-16 21:20:50 +00:00
										 |  |  |                         .addr      = &p->sa, | 
					
						
							| 
									
										
										
										
											2011-09-22 16:35:20 +00:00
										 |  |  |                         .transport = security_event_get_transport(p) | 
					
						
							|  |  |  |                 }, | 
					
						
							|  |  |  |                 .common.session_id = session_id, | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
											  
											
												Clean up chan_sip
This clean up was broken out from
https://reviewboard.asterisk.org/r/1976/ and addresses the following:
 - struct sip_refer converted to use the stringfields API.
 - sip_{refer|notify}_allocate -> sip_{notify|refer}_alloc to match
   other *alloc functions.
 - Replace get_msg_text, get_msg_text2 and get_pidf_body -> No, not
   get_pidf_msg_text_body3 but get_content, to match add_content.
 - get_body doesn't get the request body, renamed to get_content_line.
 - get_body_by_line doesn't get the body line, and is just a simple if
   test. Moved code inline and removed function.
 - Remove camelCase in struct sip_peer peer state variables,
   onHold -> onhold, inUse -> inuse, inRinging -> ringing.
 - Remove camelCase in struct sip_request rlPart1 -> rlpart1,
   rlPart2 -> rlpart2.
 - Rename instances of pvt->randdata to pvt->nonce because that is what
   it is, no need to update struct sip_pvt because _it already has a
   nonce field_.
 - Removed struct sip_pvt randdata stringfield.
 - Remove useless (and inconsistent) 'header' suffix on variables in
   handle_request_subscribe.
 - Use ast_strdupa on Event header in handle_request_subscribe to avoid
   overly complicated strncmp calls to find the event package.
 - Move get_destination check in handle_request_subscribe to avoid
   duplicate checking for packages that don't need it.
 - Move extension state callback management in handle_request_subscribe
   to avoid duplicate checking for packages that don't need it.
 - Remove duplicate append_date prototype.
 - Rename append_date -> add_date to match other add_xxx functions.
 - Added add_expires helper function, removed code that manually added
   expires header.
 - Remove _header suffix on add_diversion_header (no other header adding
   functions have this).
 - Don't pass req->debug to request handle_request_XXXXX handlers if req
   is also being passed.
 - Don't pass req->ignore to check_auth as req is already being passed.
 - Don't create a subscription in handle_request_subscribe if
   p->expiry == 0.
 - Don't walk of the back of referred_by_name when splitting string in
   get_refer_info
 - Remove duplicate check for no dialog in handle_incoming when
   sipmethod == SIP_REFER, handle_request_refer checks for that.
Review: https://reviewboard.asterisk.org/r/1993/
Patch-by: gareth
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@370636 65c4cc65-6c06-0410-ace0-fbb531ad65f3
											
										 
											2012-07-31 19:10:41 +00:00
										 |  |  |                 .challenge         = p->nonce, | 
					
						
							| 
									
										
										
										
											2011-09-22 16:35:20 +00:00
										 |  |  |         }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (!ast_strlen_zero(p->from)) { /* When dialing, show account making call */ | 
					
						
							|  |  |  | 		ast_copy_string(account_id, p->from, sizeof(account_id)); | 
					
						
							|  |  |  | 	} else { | 
					
						
							|  |  |  | 		ast_copy_string(account_id, p->exten, sizeof(account_id)); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         snprintf(session_id, sizeof(session_id), "%p", p); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         ast_security_event_report(AST_SEC_EVT(&chal_sent)); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void sip_report_inval_transport(const struct sip_pvt *p, const char *transport) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |         char session_id[32]; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         struct ast_security_event_inval_transport inval_transport = { | 
					
						
							|  |  |  |                 .common.event_type = AST_SECURITY_EVENT_INVAL_TRANSPORT, | 
					
						
							|  |  |  |                 .common.version    = AST_SECURITY_EVENT_INVAL_TRANSPORT_VERSION, | 
					
						
							|  |  |  |                 .common.service    = "SIP", | 
					
						
							|  |  |  |                 .common.account_id = p->exten, | 
					
						
							|  |  |  |                 .common.local_addr = { | 
					
						
							| 
									
										
										
										
											2012-04-16 21:20:50 +00:00
										 |  |  |                         .addr      = &p->ourip, | 
					
						
							| 
									
										
										
										
											2011-09-22 16:35:20 +00:00
										 |  |  |                         .transport = security_event_get_transport(p) | 
					
						
							|  |  |  |                 }, | 
					
						
							|  |  |  |                 .common.remote_addr = { | 
					
						
							| 
									
										
										
										
											2012-04-16 21:20:50 +00:00
										 |  |  |                         .addr      = &p->sa, | 
					
						
							| 
									
										
										
										
											2011-09-22 16:35:20 +00:00
										 |  |  |                         .transport = security_event_get_transport(p) | 
					
						
							|  |  |  |                 }, | 
					
						
							|  |  |  |                 .common.session_id = session_id, | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                 .transport         = transport, | 
					
						
							|  |  |  |         }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         snprintf(session_id, sizeof(session_id), "%p", p); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         ast_security_event_report(AST_SEC_EVT(&inval_transport)); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-08-12 12:59:53 -05:00
										 |  |  | int sip_report_security_event(const char *peer, struct ast_sockaddr *addr, const struct sip_pvt *p, | 
					
						
							| 
									
										
										
										
											2017-12-01 13:54:26 -06:00
										 |  |  |     const struct sip_request *req, const int res) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2011-09-22 16:35:20 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	struct sip_peer *peer_report; | 
					
						
							|  |  |  | 	enum check_auth_result res_report = res; | 
					
						
							|  |  |  | 	struct ast_str *buf; | 
					
						
							|  |  |  | 	char *c; | 
					
						
							|  |  |  | 	const char *authtoken; | 
					
						
							|  |  |  | 	char *reqheader, *respheader; | 
					
						
							|  |  |  | 	int result = 0; | 
					
						
							|  |  |  | 	char aclname[256]; | 
					
						
							|  |  |  | 	struct digestkeys keys[] = { | 
					
						
							|  |  |  | 		[K_RESP]  = { "response=", "" }, | 
					
						
							|  |  |  | 		[K_URI]   = { "uri=", "" }, | 
					
						
							|  |  |  | 		[K_USER]  = { "username=", "" }, | 
					
						
							|  |  |  | 		[K_NONCE] = { "nonce=", "" }, | 
					
						
							|  |  |  | 		[K_LAST]  = { NULL, NULL} | 
					
						
							|  |  |  | 	}; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-08-12 12:59:53 -05:00
										 |  |  | 	peer_report = sip_find_peer(peer, addr, TRUE, FINDPEERS, FALSE, p->socket.type); | 
					
						
							| 
									
										
										
										
											2011-09-22 16:35:20 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	switch(res_report) { | 
					
						
							|  |  |  | 	case AUTH_DONT_KNOW: | 
					
						
							|  |  |  | 		break; | 
					
						
							|  |  |  | 	case AUTH_SUCCESSFUL: | 
					
						
							|  |  |  | 		if (peer_report) { | 
					
						
							|  |  |  | 			if (ast_strlen_zero(peer_report->secret) && ast_strlen_zero(peer_report->md5secret)) { | 
					
						
							| 
									
										
										
										
											2017-12-01 13:54:26 -06:00
										 |  |  | 				sip_report_auth_success(p, 0); | 
					
						
							| 
									
										
										
										
											2011-09-22 16:35:20 +00:00
										 |  |  | 			} else { | 
					
						
							| 
									
										
										
										
											2017-12-01 13:54:26 -06:00
										 |  |  | 				sip_report_auth_success(p, 1); | 
					
						
							| 
									
										
										
										
											2011-09-22 16:35:20 +00:00
										 |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		break; | 
					
						
							|  |  |  | 	case AUTH_CHALLENGE_SENT: | 
					
						
							|  |  |  | 		sip_report_chal_sent(p); | 
					
						
							|  |  |  | 		break; | 
					
						
							|  |  |  | 	case AUTH_SECRET_FAILED: | 
					
						
							|  |  |  | 	case AUTH_USERNAME_MISMATCH: | 
					
						
							|  |  |  | 		sip_auth_headers(WWW_AUTH, &respheader, &reqheader); | 
					
						
							|  |  |  | 		authtoken = sip_get_header(req, reqheader); | 
					
						
							|  |  |  | 		buf = ast_str_thread_get(&check_auth_buf, CHECK_AUTH_BUF_INITLEN); | 
					
						
							|  |  |  | 		ast_str_set(&buf, 0, "%s", authtoken); | 
					
						
							| 
									
										
										
										
											2014-11-19 17:22:29 +00:00
										 |  |  | 		c = ast_str_buffer(buf); | 
					
						
							| 
									
										
										
										
											2011-09-22 16:35:20 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		sip_digest_parser(c, keys); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		if (res_report == AUTH_SECRET_FAILED) { | 
					
						
							|  |  |  | 			sip_report_inval_password(p, keys[K_NONCE].s, keys[K_RESP].s); | 
					
						
							|  |  |  | 		} else { | 
					
						
							|  |  |  | 			if (peer_report) { | 
					
						
							|  |  |  | 				sip_report_failed_challenge_response(p, keys[K_USER].s, peer_report->username); | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		break; | 
					
						
							|  |  |  | 	case AUTH_NOT_FOUND: | 
					
						
							|  |  |  | 		/* with sip_cfg.alwaysauthreject on, generates 2 events */ | 
					
						
							|  |  |  | 		sip_report_invalid_peer(p); | 
					
						
							|  |  |  | 		break; | 
					
						
							|  |  |  | 	case AUTH_UNKNOWN_DOMAIN: | 
					
						
							|  |  |  | 		snprintf(aclname, sizeof(aclname), "domain_must_match"); | 
					
						
							|  |  |  | 		sip_report_failed_acl(p, aclname); | 
					
						
							|  |  |  | 		break; | 
					
						
							|  |  |  | 	case AUTH_PEER_NOT_DYNAMIC: | 
					
						
							|  |  |  | 		snprintf(aclname, sizeof(aclname), "peer_not_dynamic"); | 
					
						
							|  |  |  | 		sip_report_failed_acl(p, aclname); | 
					
						
							|  |  |  | 		break; | 
					
						
							|  |  |  | 	case AUTH_ACL_FAILED: | 
					
						
							|  |  |  | 		/* with sip_cfg.alwaysauthreject on, generates 2 events */ | 
					
						
							|  |  |  | 		snprintf(aclname, sizeof(aclname), "device_must_match_acl"); | 
					
						
							|  |  |  | 		sip_report_failed_acl(p, aclname); | 
					
						
							|  |  |  | 		break; | 
					
						
							|  |  |  | 	case AUTH_BAD_TRANSPORT: | 
					
						
							|  |  |  | 		sip_report_inval_transport(p, sip_get_transport(req->socket.type)); | 
					
						
							|  |  |  | 		break; | 
					
						
							|  |  |  | 	case AUTH_RTP_FAILED: | 
					
						
							|  |  |  | 		break; | 
					
						
							|  |  |  | 	case AUTH_SESSION_LIMIT: | 
					
						
							|  |  |  | 		sip_report_session_limit(p); | 
					
						
							|  |  |  | 		break; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (peer_report) { | 
					
						
							|  |  |  | 		sip_unref_peer(peer_report, "sip_report_security_event: sip_unref_peer: from handle_incoming"); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return result; | 
					
						
							|  |  |  | } |