diff options
-rw-r--r-- | README-SERIOUSLY.bestpractices.md (renamed from README-SERIOUSLY.bestpractices.txt) | 126 | ||||
-rw-r--r-- | autoconf/ast_check_pwlib.m4 | 2 | ||||
-rw-r--r-- | autoconf/ast_ext_lib.m4 | 18 | ||||
-rw-r--r-- | autoconf/ast_gcc_attribute.m4 | 6 | ||||
-rw-r--r-- | channels/sip/include/security_events.h | 2 | ||||
-rw-r--r-- | channels/sip/security_events.c | 9 | ||||
-rw-r--r-- | configs/samples/rtp.conf.sample | 4 | ||||
-rw-r--r-- | include/asterisk/security_events_defs.h | 2 | ||||
-rw-r--r-- | main/config.c | 16 | ||||
-rw-r--r-- | main/config_options.c | 6 | ||||
-rw-r--r-- | main/xml.c | 3 | ||||
-rw-r--r-- | res/res_http_post.c | 2 | ||||
-rw-r--r-- | res/res_pjsip/security_events.c | 2 |
13 files changed, 108 insertions, 90 deletions
diff --git a/README-SERIOUSLY.bestpractices.txt b/README-SERIOUSLY.bestpractices.md index 7a656022e..7e18c4aa8 100644 --- a/README-SERIOUSLY.bestpractices.txt +++ b/README-SERIOUSLY.bestpractices.md @@ -1,51 +1,34 @@ -================== -| Best Practices | -================== +# Best Practices The purpose of this document is to define best practices when working with Asterisk in order to minimize possible security breaches and to provide tried examples in field deployments. This is a living document and is subject to change over time as best practices are defined. --------- -Sections --------- - -* Filtering Data: +* [Filtering Data]: How to protect yourself from redial attacks - -* Proper Device Naming: +* [Proper Device Naming]: Why to not use numbered extensions for devices - -* Secure Passwords: +* [Secure Passwords]: Secure passwords limit your risk to brute force attacks - -* Reducing Pattern Match Typos: +* [Reducing Pattern Match Typos]: Using the 'same' prefix, or using Goto() - -* Manager Class Authorizations: +* [Manager Class Authorizations]: Recognizing potential issues with certain classes of authorization - -* Avoid Privilege Escalations: +* [Avoid Privilege Escalations]: Disable the ability to execute functions that may escalate privileges ----------------- -Additional Links ----------------- + +## Additional Links Additional links that contain useful information about best practices or security are listed below. -* Seven Steps to Better SIP Security: - http://blogs.digium.com/2009/03/28/sip-security/ +* [Seven Steps to Better SIP Security][blog-sip-security] +* [Asterisk VoIP Security (webinar)][voip-security-webinar] -* Asterisk VoIP Security (webinar): - https://www.asterisk.org/security/webinar/ - -============== -Filtering Data -============== +## Filtering Data In the Asterisk dialplan, several channel variables contain data potentially supplied by outside sources. This could lead to a potential security concern @@ -61,20 +44,21 @@ For example, this common dialplan takes 2 or more characters of data, starting with a number 0-9, and then accepts any additional information supplied by the request. -[NOTE: We use SIP in this example, but is not limited to SIP only; protocols - such as Jabber/XMPP or IAX2 are also susceptible to the same sort of - injection problem.] - +**NOTE**: +> We use SIP in this example, but is not limited to SIP only; protocols such as +> Jabber/XMPP or IAX2 are also susceptible to the same sort of injection problem. +```INI [incoming] exten => _X.,1,Verbose(2,Incoming call to extension ${EXTEN}) exten => _X.,n,Dial(SIP/${EXTEN}) exten => _X.,n,Hangup() +``` This dialplan may be utilized to accept calls to extensions, which then dial a numbered device name configured in one of the channel configuration files (such -as sip.conf, iax.conf, etc...) (see the section Proper Device Naming for more -information on why this approach is flawed). +as sip.conf, iax.conf, etc...) (see [Proper Device Naming] for more information +on why this approach is flawed). The example we've given above looks harmless enough until you take into consideration that several channel technologies accept characters that could @@ -87,7 +71,9 @@ The string "500&SIP/itsp/14165551212" would then be contained within the ${EXTEN} channel variable, which is then utilized by the Dial() application in our example, thereby giving you the dialplan line of: +```INI exten => _X.,n,Dial(SIP/500&SIP/itsp/14165551212) +``` Our example above has now provided someone with a method to place calls out of your ITSP in a place where you didn't expect to allow it. There are a couple of @@ -101,8 +87,8 @@ or the SHELL() dialplan function, you can allow injection of arbitrary operating system command execution. The FILTER() dialplan function is available to remove dangerous characters from untrusted strings to block the command injection. -Strict Pattern Matching ------------------------ + +### Strict Pattern Matching The simple way to mitigate this problem is with a strict pattern match that does not utilize the period (.) or bang (!) characters to match on one-or-more @@ -110,7 +96,9 @@ characters or zero-or-more characters (respectively). To fine tune our example to only accept three digit extensions, we could change our pattern match to be: +```INI exten => _XXX,n,Dial(SIP/${EXTEN}) +``` In this way, we have minimized our impact because we're not allowing anything other than the numbers zero through nine. But in some cases we really do need to @@ -118,8 +106,8 @@ handle variable pattern matches, such as when dialing international numbers or when we want to handle something like a SIP URI. In this case, we'll need to utilize the FILTER() dialplan function. -Using FILTER() --------------- + +### Using FILTER() The FILTER() dialplan function is used to filter strings by only allowing characters that you have specified. This is a perfect candidate for controlling @@ -132,10 +120,12 @@ Using our previous example to accept any string length of 2 or more characters, starting with a number of zero through nine, we can use FILTER() to limit what we will accept to just numbers. Our example would then change to something like: +```INI [incoming] exten => _X.,1,Verbose(2,Incoming call to extension ${EXTEN}) exten => _X.,n,Dial(SIP/${FILTER(0-9,${EXTEN})}) exten => _X.,n,Hangup() +``` Note how we've wrapped the ${EXTEN} channel variable with the FILTER() function which will then only pass back characters that fit into the numerical range that @@ -146,17 +136,20 @@ Dial() application directly, we could save the value to a channel variable, which has a side effect of being usable in other locations of your dialplan if necessary, and to handle error checking in a separate location. +```INI [incoming] exten => _X.,1,Verbose(2,Incoming call to extension ${EXTEN}) exten => _X.,n,Set(SAFE_EXTEN=${FILTER(0-9,${EXTEN})}) exten => _X.,n,Dial(SIP/${SAFE_EXTEN}) exten => _X.,n,Hangup() +``` Now we can use the ${SAFE_EXTEN} channel variable anywhere throughout the rest of our dialplan, knowing we've already filtered it. We could also perform an error check to verify that what we've received in ${EXTEN} also matches the data passed back by FILTER(), and to fail the call if things do not match. +```INI [incoming] exten => _X.,1,Verbose(2,Incoming call to extension ${EXTEN}) exten => _X.,n,Set(SAFE_EXTEN=${FILTER(0-9,${EXTEN})}) @@ -168,14 +161,17 @@ exten => error,1,Verbose(2,Values of EXTEN and SAFE_EXTEN did not match.) exten => error,n,Verbose(2,EXTEN: "${EXTEN}" -- SAFE_EXTEN: "${SAFE_EXTEN}") exten => error,n,Playback(silence/1&invalid) exten => error,n,Hangup() +``` Another example would be using FILTER() to control the characters we accept when we're expecting to get a SIP URI for dialing. +```INI [incoming] exten => _[0-9a-zA-Z].,1,Verbose(2,Incoming call to extension ${EXTEN}) exten => _[0-9a-zA-Z].,n,Dial(SIP/${FILTER(.@0-9a-zA-Z,${EXTEN}) exten => _[0-9a-zA-Z].,n,Hangup() +``` Of course the FILTER() function doesn't check the formatting of the incoming request. There is also the REGEX() dialplan function which can be used to @@ -188,9 +184,7 @@ by typing "core show function FILTER" and "core show function REGEX" from your Asterisk console. -==================== -Proper Device Naming -==================== +## Proper Device Naming In Asterisk, the concept of an extension number being tied to a specific device does not exist. Asterisk is aware of devices it can call or receive calls from, @@ -208,10 +202,12 @@ device configurations which utilize a number, and even worse, a password that matches the devices name. For example, take a look at this poorly created device in sip.conf: +```INI [1000] type=friend context=international_dialing secret=1000 +``` As implied by the context, we've permitted a device named 1000 with a password of 1000 to place calls internationally. If your PBX system is accessible via @@ -224,10 +220,12 @@ A more secure example for the device would be to use something like the MAC address of the device, along with a strong password (see the section Secure Passwords). The following example would be more secure: +```INI [0004f2040001] type=friend context=international_dialing secret=aE3%B8*$jk^G +``` Then in your dialplan, you would reference the device via the MAC address of the device (or if using the softphone, a MAC address of a network interface on the @@ -237,9 +235,7 @@ Also note that you should NOT use this password, as it will likely be one of the first ones added to the dictionary for brute force attacks. -================ -Secure Passwords -================ +## Secure Passwords Secure passwords are necessary in many (if not all) environments, and Asterisk is certainly no exception, especially when it comes to expensive long distance @@ -252,7 +248,9 @@ for a device configuration, a database connection, or any other secure connection, be sure to use a secure password. A good example of a secure password would be something like: +``` aE3%B8*$jk^G +``` Our password also contains 12 characters with a mixture of upper and lower case characters, numbers, and symbols. Because these passwords are likely @@ -263,19 +261,18 @@ that contains a weak password that was forgotten prior to putting a system into production. Using a web search you can find several online password generators such as -https://www.strongpasswordgenerator.com or there are several scripts that can be +[Strong Password Generator] or there are several scripts that can be used to generate a strong password. -============================ -Reducing Pattern Match Typos -============================ +## Reducing Pattern Match Typos As of Asterisk 1.6.2, a new method for reducing the number of complex pattern matches you need to enter, which can reduce typos in your dialplan, has been implemented. Traditionally, a dialplan with a complex pattern match would look something like: +```INI exten => _[3-5]XXX,1,Verbose(Incoming call to ${EXTEN}) exten => _[3-5]XXX,n,Set(DEVICE=${DB(device/mac_address/${EXTEN})}) exten => _[3-5]XXX,n,Set(TECHNOLOGY=${DB(device/technology/${EXTEN})}) @@ -288,12 +285,14 @@ exten => _[3-5]XXX,n,Hangup() exten => error,1,Verbose(2,Unable to lookup technology or device for extension) exten => error,n,Playback(silence/1&num-not-in-db) exten => error,n,Hangup() +``` Of course there exists the possibility for a typo when retyping the pattern -match _[3-5]XXX which will match on extensions 3000 through 5999. We can +match _\[3-5\]XXX which will match on extensions 3000 through 5999. We can minimize this error by utilizing the same => prefix on all lines beyond the first one. Our same dialplan with using same => would look like the following: +```INI exten => _[3-5]XXX,1,Verbose(Incoming call to ${EXTEN}) same => n,Set(DEVICE=${DB(device/mac_address/${EXTEN})}) same => n,Set(TECHNOLOGY=${DB(device/technology/${EXTEN})}) @@ -306,11 +305,10 @@ same => n,Hangup() exten => error,1,Verbose(2,Unable to lookup technology or device for extension) same => n,Playback(silence/1&num-not-in-db) same => n,Hangup() +``` -============================ -Manager Class Authorizations -============================ +## Manager Class Authorizations Manager accounts have associated class authorizations that define what actions and events that account can execute/receive. In order to run Asterisk commands @@ -322,6 +320,7 @@ have the potential to alter or affect the system as well, even though the class authorization for origination commands is "originate". Take, for example, the Originate manager command: +``` Action: Originate Channel: SIP/foo Exten: s @@ -329,6 +328,7 @@ Context: default Priority: 1 Application: System Data: echo hello world! +``` This manager command will attempt to execute an Asterisk application, System, which is normally associated with the "system" class authorication. While some @@ -336,10 +336,12 @@ checks have been put into Asterisk to take this into account, certain dialplan configurations and/or clever manipulation of the Originate manager action can circumvent these checks. For example, take the following dialplan: +```INI exten => s,1,Verbose(Incoming call) same => n,MixMonitor(foo.wav,,${EXEC_COMMAND}) same => n,Dial(SIP/bar) same => n,Hangup() +``` Whatever has been defined in the variable EXEC_COMMAND will be executed after MixMonitor has finished recording the call. The dialplan writer may have @@ -354,9 +356,8 @@ same as the class authorization "system". Good system configuration, such as not running Asterisk as root, can prevent serious problems from arising when allowing external connections to originate calls into Asterisk. -=========================== -Avoid Privilege Escalations -=========================== + +## Avoid Privilege Escalations External control protocols, such as Manager, often have the ability to get and set channel variables; which allows the execution of dialplan functions. @@ -370,7 +371,18 @@ write access to. When these functions are executed from an external protocol, that execution could result in a privilege escalation. Asterisk can inhibit the execution of -these functions, if live_dangerously in the [options] section of asterisk.conf +these functions, if live_dangerously in the \[options\] section of asterisk.conf is set to no. In Asterisk 12 and later, live_dangerously defaults to no. + + +[voip-security-webinar]: https://www.asterisk.org/security/webinar/ +[blog-sip-security]: http://blogs.digium.com/2009/03/28/sip-security/ +[Strong Password Generator]: https://www.strongpasswordgenerator.com +[Filtering Data]: #filtering-data +[Proper Device Naming]: #proper-device-naming +[Secure Passwords]: #secure-passwords +[Reducing Pattern Match Typos]: #reducing-pattern-match-typos +[Manager Class Authorizations]: #manager-class-authorizations +[Avoid Privilege Escalations]: #avoid-privilege-escalations diff --git a/autoconf/ast_check_pwlib.m4 b/autoconf/ast_check_pwlib.m4 index 4588fa3b1..8ec2d58a0 100644 --- a/autoconf/ast_check_pwlib.m4 +++ b/autoconf/ast_check_pwlib.m4 @@ -200,7 +200,7 @@ AC_DEFUN([AST_CHECK_PWLIB_VERSION], [ $2_BUILD_NUMBER=`echo ${$2_VERSION} | cut -f3 -d.` $2_VER=$((${$2_MAJOR_VERSION}*10000+${$2_MINOR_VERSION}*100+${$2_BUILD_NUMBER})) $2_REQ=$(($4*10000+$5*100+$6)) - $2_MAX=m4_ifblank([$10], [9999999], [$(($8*10000+$9*100+$10))]) + $2_MAX=m4_ifval([$10], [$(($8*10000+$9*100+$10))], [9999999]) AC_MSG_CHECKING(if $1 version ${$2_VERSION} is compatible with chan_h323) if test ${$2_VER} -lt ${$2_REQ}; then diff --git a/autoconf/ast_ext_lib.m4 b/autoconf/ast_ext_lib.m4 index e8ce2013d..080b8c34d 100644 --- a/autoconf/ast_ext_lib.m4 +++ b/autoconf/ast_ext_lib.m4 @@ -117,14 +117,14 @@ if test "x${PBX_$1}" != "x1" -a "${USE_$1}" != "no"; then pbxlibdir="-L${$1_DIR}" fi fi - m4_ifblank([$3], [ - # empty lib, assume only headers - AST_$1_FOUND=yes - ], [ + m4_ifval([$3], [ ast_ext_lib_check_save_CFLAGS="${CFLAGS}" CFLAGS="${CFLAGS} $6" AC_CHECK_LIB([$2], [$3], [AST_$1_FOUND=yes], [AST_$1_FOUND=no], [${pbxlibdir} $5]) CFLAGS="${ast_ext_lib_check_save_CFLAGS}" + ], [ + # empty lib, assume only headers + AST_$1_FOUND=yes ]) # now check for the header. @@ -135,21 +135,21 @@ if test "x${PBX_$1}" != "x1" -a "${USE_$1}" != "no"; then $1_INCLUDE="-I${$1_DIR}/include" fi $1_INCLUDE="${$1_INCLUDE} $6" - m4_ifblank([$4], [ - # no header, assume found - $1_HEADER_FOUND="1" - ], [ + m4_ifval([$4], [ # check for the header ast_ext_lib_check_saved_CPPFLAGS="${CPPFLAGS}" CPPFLAGS="${CPPFLAGS} ${$1_INCLUDE}" AC_CHECK_HEADER([$4], [$1_HEADER_FOUND=1], [$1_HEADER_FOUND=0]) CPPFLAGS="${ast_ext_lib_check_saved_CPPFLAGS}" + ], [ + # no header, assume found + $1_HEADER_FOUND="1" ]) if test "x${$1_HEADER_FOUND}" = "x0" ; then $1_LIB="" $1_INCLUDE="" else - m4_ifblank([$3], [ + m4_ifval([$3], [], [ # only checking headers -> no library $1_LIB="" ]) diff --git a/autoconf/ast_gcc_attribute.m4 b/autoconf/ast_gcc_attribute.m4 index 9d5a32045..0286853fc 100644 --- a/autoconf/ast_gcc_attribute.m4 +++ b/autoconf/ast_gcc_attribute.m4 @@ -11,9 +11,9 @@ ax_cv_have_func_attribute_$1=0 AC_COMPILE_IFELSE( [AC_LANG_PROGRAM( - m4_ifblank([$2], - [$3 void __attribute__(($1)) *test(void *muffin, ...) {return (void *) 0;}], - [$3 void __attribute__(($2)) *test(void *muffin, ...) ;]))], + m4_ifval([$2], + [$3 void __attribute__(($2)) *test(void *muffin, ...) ;], + [$3 void __attribute__(($1)) *test(void *muffin, ...) {return (void *) 0;}]))], AC_MSG_RESULT(yes) m4_ifval([$4],$4=1) ax_cv_have_func_attribute_$1=1 diff --git a/channels/sip/include/security_events.h b/channels/sip/include/security_events.h index 1d0f58b41..9f4bb2ec9 100644 --- a/channels/sip/include/security_events.h +++ b/channels/sip/include/security_events.h @@ -32,7 +32,7 @@ void sip_report_invalid_peer(const struct sip_pvt *p); void sip_report_failed_acl(const struct sip_pvt *p, const char *aclname); void sip_report_inval_password(const struct sip_pvt *p, const char *responsechallenge, const char *responsehash); -void sip_report_auth_success(const struct sip_pvt *p, uint32_t *using_password); +void sip_report_auth_success(const struct sip_pvt *p, uint32_t using_password); void sip_report_session_limit(const struct sip_pvt *p); void sip_report_failed_challenge_response(const struct sip_pvt *p, const char *response, const char *expected_response); void sip_report_chal_sent(const struct sip_pvt *p); diff --git a/channels/sip/security_events.c b/channels/sip/security_events.c index b51c4736c..86ab6c2f5 100644 --- a/channels/sip/security_events.c +++ b/channels/sip/security_events.c @@ -120,7 +120,7 @@ void sip_report_inval_password(const struct sip_pvt *p, const char *response_cha ast_security_event_report(AST_SEC_EVT(&inval_password)); } -void sip_report_auth_success(const struct sip_pvt *p, uint32_t *using_password) +void sip_report_auth_success(const struct sip_pvt *p, uint32_t using_password) { char session_id[32]; @@ -269,7 +269,8 @@ void sip_report_inval_transport(const struct sip_pvt *p, const char *transport) } 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) { + const struct sip_request *req, const int res) +{ struct sip_peer *peer_report; enum check_auth_result res_report = res; @@ -295,9 +296,9 @@ int sip_report_security_event(const char *peer, struct ast_sockaddr *addr, const case AUTH_SUCCESSFUL: if (peer_report) { if (ast_strlen_zero(peer_report->secret) && ast_strlen_zero(peer_report->md5secret)) { - sip_report_auth_success(p, (uint32_t *) 0); + sip_report_auth_success(p, 0); } else { - sip_report_auth_success(p, (uint32_t *) 1); + sip_report_auth_success(p, 1); } } break; diff --git a/configs/samples/rtp.conf.sample b/configs/samples/rtp.conf.sample index eae7d8baf..9bc3de3cf 100644 --- a/configs/samples/rtp.conf.sample +++ b/configs/samples/rtp.conf.sample @@ -33,8 +33,8 @@ rtpend=20000 ; connected. This option is set to 4 by default. ; probation=8 ; -; Whether to enable or disable ICE support. This option is disabled by default. -; icesupport=true +; Whether to enable or disable ICE support. This option is enabled by default. +; icesupport=false ; ; Hostname or address for the STUN server used when determining the external ; IP address and port an RTP session can be reached at. The port number is diff --git a/include/asterisk/security_events_defs.h b/include/asterisk/security_events_defs.h index 30a713606..1cae046f9 100644 --- a/include/asterisk/security_events_defs.h +++ b/include/asterisk/security_events_defs.h @@ -394,7 +394,7 @@ struct ast_security_event_successful_auth { * \brief Using password - if a password was used or not * \note required, 0 = no, 1 = yes */ - uint32_t *using_password; + uint32_t using_password; }; /*! diff --git a/main/config.c b/main/config.c index 3d8dcfb3d..a76d0870c 100644 --- a/main/config.c +++ b/main/config.c @@ -986,13 +986,15 @@ struct ast_category *ast_category_new_template(const char *name, const char *in_ } static struct ast_category *category_get_sep(const struct ast_config *config, - const char *category_name, const char *filter, char sep) + const char *category_name, const char *filter, char sep, char pointer_match_possible) { struct ast_category *cat; - for (cat = config->root; cat; cat = cat->next) { - if (cat->name == category_name && does_category_match(cat, category_name, filter, sep)) { - return cat; + if (pointer_match_possible) { + for (cat = config->root; cat; cat = cat->next) { + if (cat->name == category_name && does_category_match(cat, category_name, filter, sep)) { + return cat; + } } } @@ -1008,7 +1010,7 @@ static struct ast_category *category_get_sep(const struct ast_config *config, struct ast_category *ast_category_get(const struct ast_config *config, const char *category_name, const char *filter) { - return category_get_sep(config, category_name, filter, ','); + return category_get_sep(config, category_name, filter, ',', 1); } const char *ast_category_get_name(const struct ast_category *category) @@ -1792,7 +1794,7 @@ static int process_text_line(struct ast_config *cfg, struct ast_category **cat, if (cur[1] != ',') { filter = &cur[1]; } - *cat = category_get_sep(cfg, catname, filter, '&'); + *cat = category_get_sep(cfg, catname, filter, '&', 0); if (!(*cat)) { if (newcat) { ast_category_destroy(newcat); @@ -1810,7 +1812,7 @@ static int process_text_line(struct ast_config *cfg, struct ast_category **cat, } else { struct ast_category *base; - base = ast_category_get(cfg, cur, "TEMPLATES=include"); + base = category_get_sep(cfg, cur, "TEMPLATES=include", ',', 0); if (!base) { if (newcat) { ast_category_destroy(newcat); diff --git a/main/config_options.c b/main/config_options.c index 3c0959ea3..a9a145b96 100644 --- a/main/config_options.c +++ b/main/config_options.c @@ -998,11 +998,11 @@ static int xmldoc_update_config_type(const char *module, const char *name, const /* If we already have a syntax element, bail. This isn't an error, since we may unload a module which * has updated the docs and then load it again. */ - if ((results = ast_xmldoc_query("//configInfo[@name='%s']/*/configObject[@name='%s']/syntax", module, name))) { + if ((results = ast_xmldoc_query("/docs/configInfo[@name='%s']/configFile/configObject[@name='%s']/syntax", module, name))) { return 0; } - if (!(results = ast_xmldoc_query("//configInfo[@name='%s']/*/configObject[@name='%s']", module, name))) { + if (!(results = ast_xmldoc_query("/docs/configInfo[@name='%s']/configFile/configObject[@name='%s']", module, name))) { ast_log(LOG_WARNING, "Cannot update type '%s' in module '%s' because it has no existing documentation!\n", name, module); return XMLDOC_STRICT ? -1 : 0; } @@ -1068,7 +1068,7 @@ static int xmldoc_update_config_option(struct aco_type **types, const char *modu return XMLDOC_STRICT ? -1 : 0; } - if (!(results = ast_xmldoc_query("//configInfo[@name='%s']/*/configObject[@name='%s']/configOption[@name='%s']", module, object_name, name))) { + if (!(results = ast_xmldoc_query("/docs/configInfo[@name='%s']/configFile/configObject[@name='%s']/configOption[@name='%s']", module, object_name, name))) { ast_log(LOG_WARNING, "Could not find option '%s' with type '%s' in module '%s'\n", name, object_name, module); return XMLDOC_STRICT ? -1 : 0; } diff --git a/main/xml.c b/main/xml.c index d32a8c5e4..d476c1d4f 100644 --- a/main/xml.c +++ b/main/xml.c @@ -96,6 +96,9 @@ struct ast_xml_doc *ast_xml_open(char *filename) ast_log(LOG_NOTICE, "XSLT support not found. XML documentation may be incomplete.\n"); #endif /* HAVE_LIBXSLT */ + /* Optimize for XPath */ + xmlXPathOrderDocElems(doc); + return (struct ast_xml_doc *) doc; } diff --git a/res/res_http_post.c b/res/res_http_post.c index 9f5b1837a..dca18a6ad 100644 --- a/res/res_http_post.c +++ b/res/res_http_post.c @@ -55,7 +55,7 @@ #ifdef GMIME_TYPE_CONTENT_TYPE #define AST_GMIME_VER_24 #endif -#if GMIME_MAJOR_VERSION >= 3 +#if defined(GMIME_MAJOR_VERSION) && (GMIME_MAJOR_VERSION >= 3) #define AST_GMIME_VER_30 #endif diff --git a/res/res_pjsip/security_events.c b/res/res_pjsip/security_events.c index ea3810bfd..b31445b0c 100644 --- a/res/res_pjsip/security_events.c +++ b/res/res_pjsip/security_events.c @@ -186,7 +186,7 @@ void ast_sip_report_auth_success(struct ast_sip_endpoint *endpoint, pjsip_rx_dat .transport = transport, }, .common.session_id = call_id, - .using_password = auth ? (uint32_t *)1 : (uint32_t *)0, + .using_password = auth ? 1 : 0, }; security_event_populate(rdata, call_id, sizeof(call_id), &local, &remote); |