00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031 #include "asterisk.h"
00032
00033 ASTERISK_FILE_VERSION(__FILE__, "$Revision: 412115 $")
00034
00035 #include "include/sip.h"
00036 #include "include/security_events.h"
00037
00038
00039
00040 static enum ast_security_event_transport_type security_event_get_transport(const struct sip_pvt *p)
00041 {
00042 int res = 0;
00043
00044 switch (p->socket.type) {
00045 case SIP_TRANSPORT_UDP:
00046 return AST_SECURITY_EVENT_TRANSPORT_UDP;
00047 case SIP_TRANSPORT_TCP:
00048 case SIP_TRANSPORT_WS:
00049 return AST_SECURITY_EVENT_TRANSPORT_TCP;
00050 case SIP_TRANSPORT_TLS:
00051 case SIP_TRANSPORT_WSS:
00052 return AST_SECURITY_EVENT_TRANSPORT_TLS;
00053 }
00054
00055 return res;
00056 }
00057
00058 void sip_report_invalid_peer(const struct sip_pvt *p)
00059 {
00060 char session_id[32];
00061
00062 struct ast_security_event_inval_acct_id inval_acct_id = {
00063 .common.event_type = AST_SECURITY_EVENT_INVAL_ACCT_ID,
00064 .common.version = AST_SECURITY_EVENT_INVAL_ACCT_ID_VERSION,
00065 .common.service = "SIP",
00066 .common.account_id = p->exten,
00067 .common.local_addr = {
00068 .addr = &p->ourip,
00069 .transport = security_event_get_transport(p)
00070 },
00071 .common.remote_addr = {
00072 .addr = &p->sa,
00073 .transport = security_event_get_transport(p)
00074 },
00075 .common.session_id = session_id,
00076 };
00077
00078 snprintf(session_id, sizeof(session_id), "%p", p);
00079
00080 ast_security_event_report(AST_SEC_EVT(&inval_acct_id));
00081 }
00082
00083 void sip_report_failed_acl(const struct sip_pvt *p, const char *aclname)
00084 {
00085 char session_id[32];
00086
00087 struct ast_security_event_failed_acl failed_acl_event = {
00088 .common.event_type = AST_SECURITY_EVENT_FAILED_ACL,
00089 .common.version = AST_SECURITY_EVENT_FAILED_ACL_VERSION,
00090 .common.service = "SIP",
00091 .common.account_id = p->exten,
00092 .common.local_addr = {
00093 .addr = &p->ourip,
00094 .transport = security_event_get_transport(p)
00095 },
00096 .common.remote_addr = {
00097 .addr = &p->sa,
00098 .transport = security_event_get_transport(p)
00099 },
00100 .common.session_id = session_id,
00101 .acl_name = aclname,
00102 };
00103
00104 snprintf(session_id, sizeof(session_id), "%p", p);
00105
00106 ast_security_event_report(AST_SEC_EVT(&failed_acl_event));
00107 }
00108
00109 void sip_report_inval_password(const struct sip_pvt *p, const char *response_challenge, const char *response_hash)
00110 {
00111 char session_id[32];
00112
00113 struct ast_security_event_inval_password inval_password = {
00114 .common.event_type = AST_SECURITY_EVENT_INVAL_PASSWORD,
00115 .common.version = AST_SECURITY_EVENT_INVAL_PASSWORD_VERSION,
00116 .common.service = "SIP",
00117 .common.account_id = p->exten,
00118 .common.local_addr = {
00119 .addr = &p->ourip,
00120 .transport = security_event_get_transport(p)
00121 },
00122 .common.remote_addr = {
00123 .addr = &p->sa,
00124 .transport = security_event_get_transport(p)
00125 },
00126 .common.session_id = session_id,
00127
00128 .challenge = p->nonce,
00129 .received_challenge = response_challenge,
00130 .received_hash = response_hash,
00131 };
00132
00133 snprintf(session_id, sizeof(session_id), "%p", p);
00134
00135 ast_security_event_report(AST_SEC_EVT(&inval_password));
00136 }
00137
00138 void sip_report_auth_success(const struct sip_pvt *p, uint32_t *using_password)
00139 {
00140 char session_id[32];
00141
00142 struct ast_security_event_successful_auth successful_auth = {
00143 .common.event_type = AST_SECURITY_EVENT_SUCCESSFUL_AUTH,
00144 .common.version = AST_SECURITY_EVENT_SUCCESSFUL_AUTH_VERSION,
00145 .common.service = "SIP",
00146 .common.account_id = p->exten,
00147 .common.local_addr = {
00148 .addr = &p->ourip,
00149 .transport = security_event_get_transport(p)
00150 },
00151 .common.remote_addr = {
00152 .addr = &p->sa,
00153 .transport = security_event_get_transport(p)
00154 },
00155 .common.session_id = session_id,
00156 .using_password = using_password,
00157 };
00158
00159 snprintf(session_id, sizeof(session_id), "%p", p);
00160
00161 ast_security_event_report(AST_SEC_EVT(&successful_auth));
00162 }
00163
00164 void sip_report_session_limit(const struct sip_pvt *p)
00165 {
00166 char session_id[32];
00167
00168 struct ast_security_event_session_limit session_limit = {
00169 .common.event_type = AST_SECURITY_EVENT_SESSION_LIMIT,
00170 .common.version = AST_SECURITY_EVENT_SESSION_LIMIT_VERSION,
00171 .common.service = "SIP",
00172 .common.account_id = p->exten,
00173 .common.local_addr = {
00174 .addr = &p->ourip,
00175 .transport = security_event_get_transport(p)
00176 },
00177 .common.remote_addr = {
00178 .addr = &p->sa,
00179 .transport = security_event_get_transport(p)
00180 },
00181 .common.session_id = session_id,
00182 };
00183
00184 snprintf(session_id, sizeof(session_id), "%p", p);
00185
00186 ast_security_event_report(AST_SEC_EVT(&session_limit));
00187 }
00188
00189 void sip_report_failed_challenge_response(const struct sip_pvt *p, const char *response, const char *expected_response)
00190 {
00191 char session_id[32];
00192 char account_id[256];
00193
00194 struct ast_security_event_chal_resp_failed chal_resp_failed = {
00195 .common.event_type = AST_SECURITY_EVENT_CHAL_RESP_FAILED,
00196 .common.version = AST_SECURITY_EVENT_CHAL_RESP_FAILED_VERSION,
00197 .common.service = "SIP",
00198 .common.account_id = account_id,
00199 .common.local_addr = {
00200 .addr = &p->ourip,
00201 .transport = security_event_get_transport(p)
00202 },
00203 .common.remote_addr = {
00204 .addr = &p->sa,
00205 .transport = security_event_get_transport(p)
00206 },
00207 .common.session_id = session_id,
00208
00209 .challenge = p->nonce,
00210 .response = response,
00211 .expected_response = expected_response,
00212 };
00213
00214 if (!ast_strlen_zero(p->from)) {
00215 ast_copy_string(account_id, p->from, sizeof(account_id));
00216 } else {
00217 ast_copy_string(account_id, p->exten, sizeof(account_id));
00218 }
00219
00220 snprintf(session_id, sizeof(session_id), "%p", p);
00221
00222 ast_security_event_report(AST_SEC_EVT(&chal_resp_failed));
00223 }
00224
00225 void sip_report_chal_sent(const struct sip_pvt *p)
00226 {
00227 char session_id[32];
00228 char account_id[256];
00229
00230 struct ast_security_event_chal_sent chal_sent = {
00231 .common.event_type = AST_SECURITY_EVENT_CHAL_SENT,
00232 .common.version = AST_SECURITY_EVENT_CHAL_SENT_VERSION,
00233 .common.service = "SIP",
00234 .common.account_id = account_id,
00235 .common.local_addr = {
00236 .addr = &p->ourip,
00237 .transport = security_event_get_transport(p)
00238 },
00239 .common.remote_addr = {
00240 .addr = &p->sa,
00241 .transport = security_event_get_transport(p)
00242 },
00243 .common.session_id = session_id,
00244
00245 .challenge = p->nonce,
00246 };
00247
00248 if (!ast_strlen_zero(p->from)) {
00249 ast_copy_string(account_id, p->from, sizeof(account_id));
00250 } else {
00251 ast_copy_string(account_id, p->exten, sizeof(account_id));
00252 }
00253
00254 snprintf(session_id, sizeof(session_id), "%p", p);
00255
00256 ast_security_event_report(AST_SEC_EVT(&chal_sent));
00257 }
00258
00259 void sip_report_inval_transport(const struct sip_pvt *p, const char *transport)
00260 {
00261 char session_id[32];
00262
00263 struct ast_security_event_inval_transport inval_transport = {
00264 .common.event_type = AST_SECURITY_EVENT_INVAL_TRANSPORT,
00265 .common.version = AST_SECURITY_EVENT_INVAL_TRANSPORT_VERSION,
00266 .common.service = "SIP",
00267 .common.account_id = p->exten,
00268 .common.local_addr = {
00269 .addr = &p->ourip,
00270 .transport = security_event_get_transport(p)
00271 },
00272 .common.remote_addr = {
00273 .addr = &p->sa,
00274 .transport = security_event_get_transport(p)
00275 },
00276 .common.session_id = session_id,
00277
00278 .transport = transport,
00279 };
00280
00281 snprintf(session_id, sizeof(session_id), "%p", p);
00282
00283 ast_security_event_report(AST_SEC_EVT(&inval_transport));
00284 }
00285
00286 int sip_report_security_event(const struct sip_pvt *p, const struct sip_request *req, const int res) {
00287
00288 struct sip_peer *peer_report;
00289 enum check_auth_result res_report = res;
00290 struct ast_str *buf;
00291 char *c;
00292 const char *authtoken;
00293 char *reqheader, *respheader;
00294 int result = 0;
00295 char aclname[256];
00296 struct digestkeys keys[] = {
00297 [K_RESP] = { "response=", "" },
00298 [K_URI] = { "uri=", "" },
00299 [K_USER] = { "username=", "" },
00300 [K_NONCE] = { "nonce=", "" },
00301 [K_LAST] = { NULL, NULL}
00302 };
00303
00304 peer_report = sip_find_peer(p->exten, NULL, TRUE, FINDPEERS, FALSE, 0);
00305
00306 switch(res_report) {
00307 case AUTH_DONT_KNOW:
00308 break;
00309 case AUTH_SUCCESSFUL:
00310 if (peer_report) {
00311 if (ast_strlen_zero(peer_report->secret) && ast_strlen_zero(peer_report->md5secret)) {
00312 sip_report_auth_success(p, (uint32_t *) 0);
00313 } else {
00314 sip_report_auth_success(p, (uint32_t *) 1);
00315 }
00316 }
00317 break;
00318 case AUTH_CHALLENGE_SENT:
00319 sip_report_chal_sent(p);
00320 break;
00321 case AUTH_SECRET_FAILED:
00322 case AUTH_USERNAME_MISMATCH:
00323 sip_auth_headers(WWW_AUTH, &respheader, &reqheader);
00324 authtoken = sip_get_header(req, reqheader);
00325 buf = ast_str_thread_get(&check_auth_buf, CHECK_AUTH_BUF_INITLEN);
00326 ast_str_set(&buf, 0, "%s", authtoken);
00327 c = buf->str;
00328
00329 sip_digest_parser(c, keys);
00330
00331 if (res_report == AUTH_SECRET_FAILED) {
00332 sip_report_inval_password(p, keys[K_NONCE].s, keys[K_RESP].s);
00333 } else {
00334 if (peer_report) {
00335 sip_report_failed_challenge_response(p, keys[K_USER].s, peer_report->username);
00336 }
00337 }
00338 break;
00339 case AUTH_NOT_FOUND:
00340
00341 sip_report_invalid_peer(p);
00342 break;
00343 case AUTH_UNKNOWN_DOMAIN:
00344 snprintf(aclname, sizeof(aclname), "domain_must_match");
00345 sip_report_failed_acl(p, aclname);
00346 break;
00347 case AUTH_PEER_NOT_DYNAMIC:
00348 snprintf(aclname, sizeof(aclname), "peer_not_dynamic");
00349 sip_report_failed_acl(p, aclname);
00350 break;
00351 case AUTH_ACL_FAILED:
00352
00353 snprintf(aclname, sizeof(aclname), "device_must_match_acl");
00354 sip_report_failed_acl(p, aclname);
00355 break;
00356 case AUTH_BAD_TRANSPORT:
00357 sip_report_inval_transport(p, sip_get_transport(req->socket.type));
00358 break;
00359 case AUTH_RTP_FAILED:
00360 break;
00361 case AUTH_SESSION_LIMIT:
00362 sip_report_session_limit(p);
00363 break;
00364 }
00365
00366 if (peer_report) {
00367 sip_unref_peer(peer_report, "sip_report_security_event: sip_unref_peer: from handle_incoming");
00368 }
00369
00370 return result;
00371 }
00372