Wed May 16 06:33:40 2012

Asterisk developer's documentation


channels/sip/security_events.c

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

Generated on Wed May 16 06:33:40 2012 for Asterisk - The Open Source Telephony Project by  doxygen 1.5.6