asterisk-16.x: bump to 16.22.0

- add new modules
- add res_timing_timerfd to base package (see commit e538fc3)
- update some module dependencies
- refresh patches
- remove upstreamed patches

Signed-off-by: Sebastian Kemper <sebastian_ml@gmx.net>
This commit is contained in:
Sebastian Kemper 2021-11-03 21:43:57 +01:00
parent 70937306b8
commit abc7a17142
15 changed files with 40 additions and 1257 deletions

View file

@ -9,12 +9,12 @@ include $(TOPDIR)/rules.mk
AST_MAJOR_VERSION:=16 AST_MAJOR_VERSION:=16
PKG_NAME:=asterisk$(AST_MAJOR_VERSION) PKG_NAME:=asterisk$(AST_MAJOR_VERSION)
PKG_VERSION:=$(AST_MAJOR_VERSION).3.0 PKG_VERSION:=$(AST_MAJOR_VERSION).22.0
PKG_RELEASE:=9 PKG_RELEASE:=1
PKG_SOURCE:=asterisk-$(PKG_VERSION).tar.gz PKG_SOURCE:=asterisk-$(PKG_VERSION).tar.gz
PKG_SOURCE_URL:=https://downloads.asterisk.org/pub/telephony/asterisk/releases PKG_SOURCE_URL:=https://downloads.asterisk.org/pub/telephony/asterisk/releases
PKG_HASH:=8b22ee7c0c0b5557eff273118703c6fce8b743c12bbeb679ed86b3f197444a8e PKG_HASH:=46992482762818e096d92654b9ac96d42fa9505ad4bc8e628a683413793ab26f
PKG_BUILD_DIR:=$(BUILD_DIR)/asterisk-$(PKG_VERSION) PKG_BUILD_DIR:=$(BUILD_DIR)/asterisk-$(PKG_VERSION)
PKG_BUILD_DEPENDS:=libxml2/host PKG_BUILD_DEPENDS:=libxml2/host
@ -43,7 +43,9 @@ MODULES_AVAILABLE:= \
app-agent-pool \ app-agent-pool \
app-alarmreceiver \ app-alarmreceiver \
app-amd \ app-amd \
app-attended-transfer \
app-authenticate \ app-authenticate \
app-blind-transfer \
app-bridgeaddchan \ app-bridgeaddchan \
app-bridgewait \ app-bridgewait \
app-celgenuserevent \ app-celgenuserevent \
@ -57,6 +59,7 @@ MODULES_AVAILABLE:= \
app-directed-pickup \ app-directed-pickup \
app-directory \ app-directory \
app-disa \ app-disa \
app-dtmfstore \
app-dumpchan \ app-dumpchan \
app-exec \ app-exec \
app-externalivr \ app-externalivr \
@ -67,6 +70,7 @@ MODULES_AVAILABLE:= \
app-ices \ app-ices \
app-image \ app-image \
app-ivrdemo \ app-ivrdemo \
app-mf \
app-milliwatt \ app-milliwatt \
app-minivm \ app-minivm \
app-mixmonitor \ app-mixmonitor \
@ -80,6 +84,7 @@ MODULES_AVAILABLE:= \
app-read \ app-read \
app-readexten \ app-readexten \
app-record \ app-record \
app-reload \
app-saycounted \ app-saycounted \
app-sayunixtime \ app-sayunixtime \
app-senddtmf \ app-senddtmf \
@ -99,6 +104,7 @@ MODULES_AVAILABLE:= \
app-url \ app-url \
app-userevent \ app-userevent \
app-verbose \ app-verbose \
app-waitforcond \
app-waitforring \ app-waitforring \
app-waitforsilence \ app-waitforsilence \
app-waituntil \ app-waituntil \
@ -176,6 +182,7 @@ MODULES_AVAILABLE:= \
func-enum \ func-enum \
func-env \ func-env \
func-extstate \ func-extstate \
func-frame-drop \
func-frame-trace \ func-frame-trace \
func-global \ func-global \
func-groupcount \ func-groupcount \
@ -192,6 +199,8 @@ MODULES_AVAILABLE:= \
func-presencestate \ func-presencestate \
func-rand \ func-rand \
func-realtime \ func-realtime \
func-sayfiles \
func-scramble \
func-sha1 \ func-sha1 \
func-shell \ func-shell \
func-sorcery \ func-sorcery \
@ -271,6 +280,7 @@ MODULES_AVAILABLE:= \
res-parking \ res-parking \
res-phoneprov \ res-phoneprov \
res-pjsip-phoneprov \ res-pjsip-phoneprov \
res-pjsip-stir-shaken \
res-pjproject \ res-pjproject \
res-pktccops \ res-pktccops \
res-realtime \ res-realtime \
@ -293,10 +303,11 @@ MODULES_AVAILABLE:= \
res-stasis-recording \ res-stasis-recording \
res-stasis-snoop \ res-stasis-snoop \
res-statsd \ res-statsd \
res-stir-shaken \
res-stun-monitor \ res-stun-monitor \
res-timing-dahdi \ res-timing-dahdi \
res-timing-pthread \ res-timing-pthread \
res-timing-timerfd \ res-tonedetect \
res-xmpp \ res-xmpp \
voicemail voicemail
@ -485,7 +496,7 @@ AST_CFG_FILES:= \
AST_EMB_MODULES:=\ AST_EMB_MODULES:=\
app_dial app_echo app_macro app_playback \ app_dial app_echo app_macro app_playback \
func_callerid func_logic func_strings func_timeout \ func_callerid func_logic func_strings func_timeout \
pbx_config res_crypto pbx_config res_crypto res_timing_timerfd
define Package/$(PKG_NAME)/install define Package/$(PKG_NAME)/install
$(call Package/$(PKG_NAME)/install/lib,$(1),libasteriskssl) $(call Package/$(PKG_NAME)/install/lib,$(1),libasteriskssl)
@ -757,7 +768,9 @@ $(eval $(call BuildAsteriskModule,app-adsiprog,ADSI programming,Asterisk ADSI pr
$(eval $(call BuildAsteriskModule,app-agent-pool,Call center agent pool,Call center agent pool applications.,,agents.conf,app_agent_pool,,)) $(eval $(call BuildAsteriskModule,app-agent-pool,Call center agent pool,Call center agent pool applications.,,agents.conf,app_agent_pool,,))
$(eval $(call BuildAsteriskModule,app-alarmreceiver,Alarm receiver,Alarm receiver for Asterisk.,,,app_alarmreceiver,,)) $(eval $(call BuildAsteriskModule,app-alarmreceiver,Alarm receiver,Alarm receiver for Asterisk.,,,app_alarmreceiver,,))
$(eval $(call BuildAsteriskModule,app-amd,Answering machine detection,Answering Machine Detection application.,,amd.conf,app_amd,,)) $(eval $(call BuildAsteriskModule,app-amd,Answering machine detection,Answering Machine Detection application.,,amd.conf,app_amd,,))
$(eval $(call BuildAsteriskModule,app-attended-transfer,Attended transfer,Queues up an attended transfer to a given extension.,,,app_attended_transfer,,))
$(eval $(call BuildAsteriskModule,app-authenticate,Authenticate commands,Authentication application.,,,app_authenticate,,)) $(eval $(call BuildAsteriskModule,app-authenticate,Authenticate commands,Authentication application.,,,app_authenticate,,))
$(eval $(call BuildAsteriskModule,app-blind-transfer,Blind transfer,Redirects all channels currently bridged to the caller channel to a specified destination.,,,app_blind_transfer,,))
$(eval $(call BuildAsteriskModule,app-bridgeaddchan,Bridge add channel,Bridge-add-channel application.,,,app_bridgeaddchan,,)) $(eval $(call BuildAsteriskModule,app-bridgeaddchan,Bridge add channel,Bridge-add-channel application.,,,app_bridgeaddchan,,))
$(eval $(call BuildAsteriskModule,app-bridgewait,Holding bridge,Application to place a channel into a holding bridge.,+$(PKG_NAME)-bridge-holding,,app_bridgewait,,)) $(eval $(call BuildAsteriskModule,app-bridgewait,Holding bridge,Application to place a channel into a holding bridge.,+$(PKG_NAME)-bridge-holding,,app_bridgewait,,))
$(eval $(call BuildAsteriskModule,app-celgenuserevent,User-defined CEL event,Generate a user defined CEL event.,,,app_celgenuserevent,,)) $(eval $(call BuildAsteriskModule,app-celgenuserevent,User-defined CEL event,Generate a user defined CEL event.,,,app_celgenuserevent,,))
@ -771,16 +784,18 @@ $(eval $(call BuildAsteriskModule,app-dictate,Virtual dictation machine,Virtual
$(eval $(call BuildAsteriskModule,app-directed-pickup,Directed call pickup,Directed call pickup application.,,,app_directed_pickup,,)) $(eval $(call BuildAsteriskModule,app-directed-pickup,Directed call pickup,Directed call pickup application.,,,app_directed_pickup,,))
$(eval $(call BuildAsteriskModule,app-directory,Extension directory,Extension directory.,,,app_directory,,)) $(eval $(call BuildAsteriskModule,app-directory,Extension directory,Extension directory.,,,app_directory,,))
$(eval $(call BuildAsteriskModule,app-disa,Direct Inward System Access,Direct Inward System Access application.,,,app_disa,,)) $(eval $(call BuildAsteriskModule,app-disa,Direct Inward System Access,Direct Inward System Access application.,,,app_disa,,))
$(eval $(call BuildAsteriskModule,app-dtmfstore,DTMF storage,Technology independent async DTMF storage.,,,app_dtmfstore,,))
$(eval $(call BuildAsteriskModule,app-dumpchan,Dump info about channel,Dump info about the calling channel.,,,app_dumpchan,,)) $(eval $(call BuildAsteriskModule,app-dumpchan,Dump info about channel,Dump info about the calling channel.,,,app_dumpchan,,))
$(eval $(call BuildAsteriskModule,app-exec,Exec application,Executes dialplan applications.,,,app_exec,,)) $(eval $(call BuildAsteriskModule,app-exec,Exec application,Executes dialplan applications.,,,app_exec,,))
$(eval $(call BuildAsteriskModule,app-externalivr,External IVR interface,External IVR interface application.,,,app_externalivr,,)) $(eval $(call BuildAsteriskModule,app-externalivr,External IVR interface,External IVR interface application.,,,app_externalivr,,))
$(eval $(call BuildAsteriskModule,app-festival,Simple festival interface,Simple Festival interface.,,festival.conf,app_festival,,)) $(eval $(call BuildAsteriskModule,app-festival,Simple festival interface,Simple Festival interface.,,festival.conf,app_festival,,))
$(eval $(call BuildAsteriskModule,app-flash,Flash channel,Flash channel application.,+$(PKG_NAME)-chan-dahdi,,app_flash,,)) $(eval $(call BuildAsteriskModule,app-flash,Flash channel,Flash channel application.,+$(PKG_NAME)-chan-dahdi,,app_flash,,))
$(eval $(call BuildAsteriskModule,app-followme,Find-me/follow-me,Find-Me/Follow-Me application.,,followme.conf,app_followme,,)) $(eval $(call BuildAsteriskModule,app-followme,Find-me/follow-me,Find-Me/Follow-Me application.,,followme.conf,app_followme,,))
$(eval $(call BuildAsteriskModule,app-getcpeid,Get ADSI CPE ID,Get ADSI CPE ID.,,,app_getcpeid,,)) $(eval $(call BuildAsteriskModule,app-getcpeid,Get ADSI CPE ID,Get ADSI CPE ID.,+$(PKG_NAME)-res-adsi,,app_getcpeid,,))
$(eval $(call BuildAsteriskModule,app-ices,Encode and stream,Encode and stream via Icecast and IceS.,,,app_ices,,)) $(eval $(call BuildAsteriskModule,app-ices,Encode and stream,Encode and stream via Icecast and IceS.,,,app_ices,,))
$(eval $(call BuildAsteriskModule,app-image,Image transmission,Image transmission application.,,,app_image,,)) $(eval $(call BuildAsteriskModule,app-image,Image transmission,Image transmission application.,,,app_image,,))
$(eval $(call BuildAsteriskModule,app-ivrdemo,IVR demo,IVR demo application.,,,app_ivrdemo,,)) $(eval $(call BuildAsteriskModule,app-ivrdemo,IVR demo,IVR demo application.,,,app_ivrdemo,,))
$(eval $(call BuildAsteriskModule,app-mf,MF digits,Send MF digits Application.,,,app_mf,,))
$(eval $(call BuildAsteriskModule,app-milliwatt,Digital milliwatt [mu-law] test app,Digital milliwatt test application.,,,app_milliwatt,,)) $(eval $(call BuildAsteriskModule,app-milliwatt,Digital milliwatt [mu-law] test app,Digital milliwatt test application.,,,app_milliwatt,,))
$(eval $(call BuildAsteriskModule,app-minivm,Minimal voicemail system,A minimal voicemail e-mail system.,,extensions_minivm.conf minivm.conf,app_minivm,,)) $(eval $(call BuildAsteriskModule,app-minivm,Minimal voicemail system,A minimal voicemail e-mail system.,,extensions_minivm.conf minivm.conf,app_minivm,,))
$(eval $(call BuildAsteriskModule,app-mixmonitor,Record a call and mix the audio,Mixed audio monitoring application.,,,app_mixmonitor,,)) $(eval $(call BuildAsteriskModule,app-mixmonitor,Record a call and mix the audio,Mixed audio monitoring application.,,,app_mixmonitor,,))
@ -794,6 +809,7 @@ $(eval $(call BuildAsteriskModule,app-queue,True Call Queueing,True call queuein
$(eval $(call BuildAsteriskModule,app-read,Variable read,Read variable application.,,,app_read,,)) $(eval $(call BuildAsteriskModule,app-read,Variable read,Read variable application.,,,app_read,,))
$(eval $(call BuildAsteriskModule,app-readexten,Extension to variable,Read and evaluate extension validity.,,,app_readexten,,)) $(eval $(call BuildAsteriskModule,app-readexten,Extension to variable,Read and evaluate extension validity.,,,app_readexten,,))
$(eval $(call BuildAsteriskModule,app-record,Record sound file,Trivial record application.,,,app_record,,)) $(eval $(call BuildAsteriskModule,app-record,Record sound file,Trivial record application.,,,app_record,,))
$(eval $(call BuildAsteriskModule,app-reload,Reload,Reload module[s].,,,app_reload,,))
$(eval $(call BuildAsteriskModule,app-saycounted,Decline words,Decline words according to channel language.,,,app_saycounted,,)) $(eval $(call BuildAsteriskModule,app-saycounted,Decline words,Decline words according to channel language.,,,app_saycounted,,))
$(eval $(call BuildAsteriskModule,app-sayunixtime,Say Unix time,Say time.,,,app_sayunixtime,,)) $(eval $(call BuildAsteriskModule,app-sayunixtime,Say Unix time,Say time.,,,app_sayunixtime,,))
$(eval $(call BuildAsteriskModule,app-senddtmf,Send DTMF digits,Send DTMF digits application.,,,app_senddtmf,,)) $(eval $(call BuildAsteriskModule,app-senddtmf,Send DTMF digits,Send DTMF digits application.,,,app_senddtmf,,))
@ -813,6 +829,7 @@ $(eval $(call BuildAsteriskModule,app-transfer,Transfers caller to other ext,Tra
$(eval $(call BuildAsteriskModule,app-url,Send URL,Send URL applications.,,,app_url,,)) $(eval $(call BuildAsteriskModule,app-url,Send URL,Send URL applications.,,,app_url,,))
$(eval $(call BuildAsteriskModule,app-userevent,Custom user event,Custom user event application.,,,app_userevent,,)) $(eval $(call BuildAsteriskModule,app-userevent,Custom user event,Custom user event application.,,,app_userevent,,))
$(eval $(call BuildAsteriskModule,app-verbose,Verbose logging,Send verbose output.,,,app_verbose,,)) $(eval $(call BuildAsteriskModule,app-verbose,Verbose logging,Send verbose output.,,,app_verbose,,))
$(eval $(call BuildAsteriskModule,app-waitforcond,Wait for condition,Wait until condition is true.,,,app_waitforcond,,))
$(eval $(call BuildAsteriskModule,app-waitforring,Wait for first ring,Waits until first ring after time.,,,app_waitforring,,)) $(eval $(call BuildAsteriskModule,app-waitforring,Wait for first ring,Waits until first ring after time.,,,app_waitforring,,))
$(eval $(call BuildAsteriskModule,app-waitforsilence,Wait for silence/noise,Wait for silence/noise.,,,app_waitforsilence,,)) $(eval $(call BuildAsteriskModule,app-waitforsilence,Wait for silence/noise,Wait for silence/noise.,,,app_waitforsilence,,))
$(eval $(call BuildAsteriskModule,app-waituntil,Sleep,Wait until specified time.,,,app_waituntil,,)) $(eval $(call BuildAsteriskModule,app-waituntil,Sleep,Wait until specified time.,,,app_waituntil,,))
@ -834,14 +851,14 @@ $(eval $(call BuildAsteriskModule,chan-alsa,ALSA channel,ALSA console channel dr
$(eval $(call BuildAsteriskModule,chan-bridge-media,Bridge media channel driver,Bridge media channel driver.,,,chan_bridge_media,,)) $(eval $(call BuildAsteriskModule,chan-bridge-media,Bridge media channel driver,Bridge media channel driver.,,,chan_bridge_media,,))
$(eval $(call BuildAsteriskModule,chan-console,Console channel driver,Console channel driver.,+portaudio,console.conf,chan_console,,)) $(eval $(call BuildAsteriskModule,chan-console,Console channel driver,Console channel driver.,+portaudio,console.conf,chan_console,,))
$(eval $(call BuildAsteriskModule,chan-dahdi,DAHDI channel,DAHDI telephony.,+dahdi-tools-libtonezone +kmod-dahdi +libpri @!aarch64,chan_dahdi.conf,chan_dahdi,,)) $(eval $(call BuildAsteriskModule,chan-dahdi,DAHDI channel,DAHDI telephony.,+dahdi-tools-libtonezone +kmod-dahdi +libpri @!aarch64,chan_dahdi.conf,chan_dahdi,,))
$(eval $(call BuildAsteriskModule,chan-iax2,IAX2 channel,Inter Asterisk eXchange.,+$(PKG_NAME)-res-timing-timerfd,iax.conf iaxprov.conf,chan_iax2,,)) $(eval $(call BuildAsteriskModule,chan-iax2,IAX2 channel,Inter Asterisk eXchange.,,iax.conf iaxprov.conf,chan_iax2,,))
$(eval $(call BuildAsteriskModule,chan-mgcp,MGCP,Media Gateway Control Protocol.,,mgcp.conf,chan_mgcp,,)) $(eval $(call BuildAsteriskModule,chan-mgcp,MGCP,Media Gateway Control Protocol.,,mgcp.conf,chan_mgcp,,))
$(eval $(call BuildAsteriskModule,chan-mobile,Bluetooth channel,Bluetooth mobile device channel driver.,+bluez-libs,chan_mobile.conf,chan_mobile,,)) $(eval $(call BuildAsteriskModule,chan-mobile,Bluetooth channel,Bluetooth mobile device channel driver.,+bluez-libs,chan_mobile.conf,chan_mobile,,))
$(eval $(call BuildAsteriskModule,chan-motif,Jingle channel,Motif Jingle channel driver.,+$(PKG_NAME)-res-xmpp,motif.conf,chan_motif,,)) $(eval $(call BuildAsteriskModule,chan-motif,Jingle channel,Motif Jingle channel driver.,+$(PKG_NAME)-res-xmpp,motif.conf,chan_motif,,))
$(eval $(call BuildAsteriskModule,chan-ooh323,H.323 channel,Objective Systems H.323 channel.,,ooh323.conf,chan_ooh323,,)) $(eval $(call BuildAsteriskModule,chan-ooh323,H.323 channel,Objective Systems H.323 channel.,,ooh323.conf,chan_ooh323,,))
$(eval $(call BuildAsteriskModule,chan-oss,OSS channel,OSS console channel driver.,,oss.conf,chan_oss,,)) $(eval $(call BuildAsteriskModule,chan-oss,OSS channel,OSS console channel driver.,,oss.conf,chan_oss,,))
$(eval $(call BuildAsteriskModule,chan-phone,Linux telephony API,Linux telephony API support.,,phone.conf,chan_phone,,)) $(eval $(call BuildAsteriskModule,chan-phone,Linux telephony API,Linux telephony API support.,,phone.conf,chan_phone,,))
$(eval $(call BuildAsteriskModule,chan-rtp,RTP media channel,RTP media channel.,,,chan_rtp,,)) $(eval $(call BuildAsteriskModule,chan-rtp,RTP media channel,RTP media channel.,+$(PKG_NAME)-res-rtp-multicast,,chan_rtp,,))
$(eval $(call BuildAsteriskModule,chan-sip,SIP channel,Session Initiation Protocol.,+$(PKG_NAME)-app-confbridge,sip.conf sip_notify.conf,chan_sip,,)) $(eval $(call BuildAsteriskModule,chan-sip,SIP channel,Session Initiation Protocol.,+$(PKG_NAME)-app-confbridge,sip.conf sip_notify.conf,chan_sip,,))
$(eval $(call BuildAsteriskModule,chan-skinny,Skinny channel,Skinny Client Control Protocol.,,skinny.conf,chan_skinny,,)) $(eval $(call BuildAsteriskModule,chan-skinny,Skinny channel,Skinny Client Control Protocol.,,skinny.conf,chan_skinny,,))
$(eval $(call BuildAsteriskModule,chan-unistim,Unistim channel,UNISTIM protocol.,,unistim.conf,chan_unistim,,)) $(eval $(call BuildAsteriskModule,chan-unistim,Unistim channel,UNISTIM protocol.,,unistim.conf,chan_unistim,,))
@ -890,6 +907,7 @@ $(eval $(call BuildAsteriskModule,func-dialplan,Dialplan context/extension/prior
$(eval $(call BuildAsteriskModule,func-enum,ENUM,ENUM related dialplan functions.,,enum.conf,func_enum,,)) $(eval $(call BuildAsteriskModule,func-enum,ENUM,ENUM related dialplan functions.,,enum.conf,func_enum,,))
$(eval $(call BuildAsteriskModule,func-env,Environment functions,Environment/filesystem dialplan functions.,,,func_env,,)) $(eval $(call BuildAsteriskModule,func-env,Environment functions,Environment/filesystem dialplan functions.,,,func_env,,))
$(eval $(call BuildAsteriskModule,func-extstate,Hinted extension state,Gets the state of an extension in the dialplan.,,,func_extstate,,)) $(eval $(call BuildAsteriskModule,func-extstate,Hinted extension state,Gets the state of an extension in the dialplan.,,,func_extstate,,))
$(eval $(call BuildAsteriskModule,func-frame-drop,Frame drop,Function to drop frames on a channel.,,,func_frame_drop,,))
$(eval $(call BuildAsteriskModule,func-frame-trace,Frame trace for internal ast_frame debugging,Frame trace for internal ast_frame debugging.,,,func_frame_trace,,)) $(eval $(call BuildAsteriskModule,func-frame-trace,Frame trace for internal ast_frame debugging,Frame trace for internal ast_frame debugging.,,,func_frame_trace,,))
$(eval $(call BuildAsteriskModule,func-global,Global variable,Variable dialplan functions.,,,func_global,,)) $(eval $(call BuildAsteriskModule,func-global,Global variable,Variable dialplan functions.,,,func_global,,))
$(eval $(call BuildAsteriskModule,func-groupcount,Group count,Channel group dialplan functions.,,,func_groupcount,,)) $(eval $(call BuildAsteriskModule,func-groupcount,Group count,Channel group dialplan functions.,,,func_groupcount,,))
@ -906,6 +924,8 @@ $(eval $(call BuildAsteriskModule,func-pitchshift,Audio effects dialplan functio
$(eval $(call BuildAsteriskModule,func-presencestate,Hinted presence state,Gets or sets a presence state in the dialplan.,,,func_presencestate,,)) $(eval $(call BuildAsteriskModule,func-presencestate,Hinted presence state,Gets or sets a presence state in the dialplan.,,,func_presencestate,,))
$(eval $(call BuildAsteriskModule,func-rand,RAND dialplan function,Random number dialplan function.,,,func_rand,,)) $(eval $(call BuildAsteriskModule,func-rand,RAND dialplan function,Random number dialplan function.,,,func_rand,,))
$(eval $(call BuildAsteriskModule,func-realtime,REALTIME dialplan function,Read/write/store/destroy values from a realtime repository.,,,func_realtime,,)) $(eval $(call BuildAsteriskModule,func-realtime,REALTIME dialplan function,Read/write/store/destroy values from a realtime repository.,,,func_realtime,,))
$(eval $(call BuildAsteriskModule,func-sayfiles,Say files,Say application files.,,,func_sayfiles,,))
$(eval $(call BuildAsteriskModule,func-scramble,Scramble,Frequency inverting voice scrambler.,,,func_scramble,,))
$(eval $(call BuildAsteriskModule,func-sha1,SHA-1 computation dialplan function,SHA-1 computation dialplan function.,,,func_sha1,,)) $(eval $(call BuildAsteriskModule,func-sha1,SHA-1 computation dialplan function,SHA-1 computation dialplan function.,,,func_sha1,,))
$(eval $(call BuildAsteriskModule,func-shell,Shell,Collects the output generated by a command executed by the system shell.,,,func_shell,,)) $(eval $(call BuildAsteriskModule,func-shell,Shell,Collects the output generated by a command executed by the system shell.,,,func_shell,,))
$(eval $(call BuildAsteriskModule,func-sorcery,Get a field from a sorcery object,Get a field from a sorcery object.,,,func_sorcery,,)) $(eval $(call BuildAsteriskModule,func-sorcery,Get a field from a sorcery object,Get a field from a sorcery object.,,,func_sorcery,,))
@ -960,7 +980,7 @@ $(eval $(call BuildAsteriskModule,res-hep,HEPv3 API,HEPv3 API.,,hep.conf,res_hep
$(eval $(call BuildAsteriskModule,res-hep-pjsip,PJSIP HEPv3 Logger,PJSIP HEPv3 logger.,+$(PKG_NAME)-res-hep +$(PKG_NAME)-pjsip,,res_hep_pjsip,,)) $(eval $(call BuildAsteriskModule,res-hep-pjsip,PJSIP HEPv3 Logger,PJSIP HEPv3 logger.,+$(PKG_NAME)-res-hep +$(PKG_NAME)-pjsip,,res_hep_pjsip,,))
$(eval $(call BuildAsteriskModule,res-hep-rtcp,RTCP HEPv3 Logger,RTCP HEPv3 logger.,+$(PKG_NAME)-res-hep,,res_hep_rtcp,,)) $(eval $(call BuildAsteriskModule,res-hep-rtcp,RTCP HEPv3 Logger,RTCP HEPv3 logger.,+$(PKG_NAME)-res-hep,,res_hep_rtcp,,))
$(eval $(call BuildAsteriskModule,res-fax-spandsp,Spandsp T.38 and G.711,Spandsp G.711 and T.38 FAX technologies.,+$(PKG_NAME)-res-fax +libspandsp +libtiff,,res_fax_spandsp,,)) $(eval $(call BuildAsteriskModule,res-fax-spandsp,Spandsp T.38 and G.711,Spandsp G.711 and T.38 FAX technologies.,+$(PKG_NAME)-res-fax +libspandsp +libtiff,,res_fax_spandsp,,))
$(eval $(call BuildAsteriskModule,res-fax,FAX modules,Generic FAX applications.,+$(PKG_NAME)-res-timing-pthread,res_fax.conf,res_fax,,)) $(eval $(call BuildAsteriskModule,res-fax,FAX modules,Generic FAX applications.,,res_fax.conf,res_fax,,))
$(eval $(call BuildAsteriskModule,res-format-attr-celt,CELT format attribute module,CELT format attribute module.,,,res_format_attr_celt,,)) $(eval $(call BuildAsteriskModule,res-format-attr-celt,CELT format attribute module,CELT format attribute module.,,,res_format_attr_celt,,))
$(eval $(call BuildAsteriskModule,res-format-attr-g729,G.729 format attribute module,G.729 format attribute module.,,,res_format_attr_g729,,)) $(eval $(call BuildAsteriskModule,res-format-attr-g729,G.729 format attribute module,G.729 format attribute module.,,,res_format_attr_g729,,))
$(eval $(call BuildAsteriskModule,res-format-attr-h263,H.263 format attribute module,H.263 format attribute module.,,,res_format_attr_h263,,)) $(eval $(call BuildAsteriskModule,res-format-attr-h263,H.263 format attribute module,H.263 format attribute module.,,,res_format_attr_h263,,))
@ -984,8 +1004,9 @@ $(eval $(call BuildAsteriskModule,res-mwi-external,Core external MWI resource,Co
$(eval $(call BuildAsteriskModule,res-mwi-external-ami,AMI for external MWI,AMI support for external MWI.,+$(PKG_NAME)-res-mwi-external,,res_mwi_external_ami,,)) $(eval $(call BuildAsteriskModule,res-mwi-external-ami,AMI for external MWI,AMI support for external MWI.,+$(PKG_NAME)-res-mwi-external,,res_mwi_external_ami,,))
$(eval $(call BuildAsteriskModule,res-parking,Phone Parking,Call parking resource.,+$(PKG_NAME)-bridge-holding,res_parking.conf,res_parking,,)) $(eval $(call BuildAsteriskModule,res-parking,Phone Parking,Call parking resource.,+$(PKG_NAME)-bridge-holding,res_parking.conf,res_parking,,))
$(eval $(call BuildAsteriskModule,res-phoneprov,Phone Provisioning,HTTP phone provisioning.,,phoneprov.conf,res_phoneprov,,)) $(eval $(call BuildAsteriskModule,res-phoneprov,Phone Provisioning,HTTP phone provisioning.,,phoneprov.conf,res_phoneprov,,))
$(eval $(call BuildAsteriskModule,res-pjsip-stir-shaken,PJSIP STIR/SHAKEN resource,PJSIP STIR/SHAKEN resource module.,+$(PKG_NAME)-pjsip +$(PKG_NAME)-res-stir-shaken,,res_pjsip_stir_shaken,,))
$(eval $(call BuildAsteriskModule,res-pjsip-phoneprov,PJSIP Phone Provisioning,PJSIP phone provisioning.,+$(PKG_NAME)-pjsip +$(PKG_NAME)-res-phoneprov,,res_pjsip_phoneprov_provider,,)) $(eval $(call BuildAsteriskModule,res-pjsip-phoneprov,PJSIP Phone Provisioning,PJSIP phone provisioning.,+$(PKG_NAME)-pjsip +$(PKG_NAME)-res-phoneprov,,res_pjsip_phoneprov_provider,,))
$(eval $(call BuildAsteriskModule,res-pjproject,Bridge PJPROJECT to Asterisk logging,PJProject log and utility support.,+libpj +libpjlib-util +libpjmedia +libpjmedia +libpjnath +libpjsip-simple +libpjsip-ua +libpjsip +libpjsua +libpjsua2 +libsrtp2,pjproject.conf,res_pjproject,,)) $(eval $(call BuildAsteriskModule,res-pjproject,Bridge PJPROJECT to Asterisk logging,PJProject log and utility support.,+libpj +libpjlib-util +libpjmedia +libpjmedia +libpjnath +libpjsip-simple +libpjsip-ua +libpjsip +libpjsua +libpjsua2 +libsrtp2 +$(PKG_NAME)-res-sorcery,pjproject.conf,res_pjproject,,))
$(eval $(call BuildAsteriskModule,res-pktccops,PktcCOPS manager for MGCP,PktcCOPS manager for MGCP.,,res_pktccops.conf,res_pktccops,,)) $(eval $(call BuildAsteriskModule,res-pktccops,PktcCOPS manager for MGCP,PktcCOPS manager for MGCP.,,res_pktccops.conf,res_pktccops,,))
$(eval $(call BuildAsteriskModule,res-realtime,RealTime CLI,Realtime data lookup/rewrite.,,,res_realtime,,)) $(eval $(call BuildAsteriskModule,res-realtime,RealTime CLI,Realtime data lookup/rewrite.,,,res_realtime,,))
$(eval $(call BuildAsteriskModule,res-remb-modifier,REMB modifier,REMB modifier module.,,,res_remb_modifier,,)) $(eval $(call BuildAsteriskModule,res-remb-modifier,REMB modifier,REMB modifier module.,,,res_remb_modifier,,))
@ -1007,10 +1028,11 @@ $(eval $(call BuildAsteriskModule,res-stasis-playback,Stasis application playbac
$(eval $(call BuildAsteriskModule,res-stasis-recording,Stasis application recording,Stasis application recording support.,+$(PKG_NAME)-res-stasis,,res_stasis_recording,,)) $(eval $(call BuildAsteriskModule,res-stasis-recording,Stasis application recording,Stasis application recording support.,+$(PKG_NAME)-res-stasis,,res_stasis_recording,,))
$(eval $(call BuildAsteriskModule,res-stasis-snoop,Stasis application snoop,Stasis application snoop support.,+$(PKG_NAME)-res-stasis-recording,,res_stasis_snoop,,)) $(eval $(call BuildAsteriskModule,res-stasis-snoop,Stasis application snoop,Stasis application snoop support.,+$(PKG_NAME)-res-stasis-recording,,res_stasis_snoop,,))
$(eval $(call BuildAsteriskModule,res-statsd,statsd client,Statsd client support.,,statsd.conf,res_statsd,,)) $(eval $(call BuildAsteriskModule,res-statsd,statsd client,Statsd client support.,,statsd.conf,res_statsd,,))
$(eval $(call BuildAsteriskModule,res-stir-shaken,STIR/SHAKEN resource module,STIR/SHAKEN resource module.,+$(PKG_NAME)-curl,stir_shaken.conf,res_stir_shaken,,))
$(eval $(call BuildAsteriskModule,res-stun-monitor,STUN monitoring,STUN network monitor.,,res_stun_monitor.conf,res_stun_monitor,,)) $(eval $(call BuildAsteriskModule,res-stun-monitor,STUN monitoring,STUN network monitor.,,res_stun_monitor.conf,res_stun_monitor,,))
$(eval $(call BuildAsteriskModule,res-timing-dahdi,DAHDI Timing Interface,DAHDI timing interface.,+$(PKG_NAME)-chan-dahdi,,res_timing_dahdi,,)) $(eval $(call BuildAsteriskModule,res-timing-dahdi,DAHDI Timing Interface,DAHDI timing interface.,+$(PKG_NAME)-chan-dahdi,,res_timing_dahdi,,))
$(eval $(call BuildAsteriskModule,res-timing-pthread,pthread Timing Interface,pthread timing interface.,,,res_timing_pthread,,)) $(eval $(call BuildAsteriskModule,res-timing-pthread,pthread Timing Interface,pthread timing interface.,,,res_timing_pthread,,))
$(eval $(call BuildAsteriskModule,res-timing-timerfd,Timerfd Timing Interface,Timerfd timing interface.,,,res_timing_timerfd,,)) $(eval $(call BuildAsteriskModule,res-tonedetect,Tone detection,Tone detection module.,,,res_tonedetect,,))
$(eval $(call BuildAsteriskModule,res-xmpp,XMPP client and component module,Asterisk XMPP interface.,+libiksemel +libopenssl,xmpp.conf,res_xmpp,,)) $(eval $(call BuildAsteriskModule,res-xmpp,XMPP client and component module,Asterisk XMPP interface.,+libiksemel +libopenssl,xmpp.conf,res_xmpp,,))
$(eval $(call BuildAsteriskModule,voicemail,Voicemail,Voicemail modules.,+$(PKG_NAME)-res-adsi +$(PKG_NAME)-res-smdi,voicemail.conf,app_voicemail,vm-*,)) $(eval $(call BuildAsteriskModule,voicemail,Voicemail,Voicemail modules.,+$(PKG_NAME)-res-adsi +$(PKG_NAME)-res-smdi,voicemail.conf,app_voicemail,vm-*,))

View file

@ -1,6 +1,6 @@
--- a/configure.ac --- a/configure.ac
+++ b/configure.ac +++ b/configure.ac
@@ -1018,15 +1018,18 @@ AC_LINK_IFELSE( @@ -1033,15 +1033,18 @@ AC_LINK_IFELSE(
# Some platforms define sem_init(), but only support sem_open(). joyous. # Some platforms define sem_init(), but only support sem_open(). joyous.
AC_MSG_CHECKING(for working unnamed semaphores) AC_MSG_CHECKING(for working unnamed semaphores)

View file

@ -18,7 +18,7 @@ Signed-off-by: Bernd Kuhls <bernd.kuhls@t-online.de>
--- a/configure.ac --- a/configure.ac
+++ b/configure.ac +++ b/configure.ac
@@ -1412,7 +1412,11 @@ AC_LINK_IFELSE( @@ -1427,7 +1427,11 @@ AC_LINK_IFELSE(
#include <arpa/nameser.h> #include <arpa/nameser.h>
#endif #endif
#include <resolv.h>], #include <resolv.h>],

View file

@ -1,38 +0,0 @@
From 06e8d5ad8e4728a716bf357c8d7f70367ae10280 Mon Sep 17 00:00:00 2001
From: Sebastian Kemper <sebastian_ml@gmx.net>
Date: Sun, 12 Jan 2020 12:37:46 +0100
Subject: [PATCH] check_expr2: fix cross-compile/hardening issues
When building check_expr2 with ASLR PIE hardening enabled the linker
fails. This is resolved by adding the regular compiler flags when
building the object files from ast_expr2f.c and ast_expr2.c.
Note: The STANDALONE define is removed because it is already defined in
_ASTCFLAGS. YY_NO_INPUT is defined so that the compile survives
'--enable-dev-mode'.
ASTERISK-28685 #close
Signed-off-by: Sebastian Kemper <sebastian_ml@gmx.net>
Change-Id: If435b7db9f9ad8266245bda51c81c220f9658915
Taken just Makefile changes from commit: 06e8d5ad8e4728a716bf357c8d7f70367ae10280
---
--- a/utils/Makefile
+++ b/utils/Makefile
@@ -180,14 +180,13 @@ conf2ael: conf2ael.o ast_expr2f.o ast_ex
check_expr2: $(ASTTOPDIR)/main/ast_expr2f.c $(ASTTOPDIR)/main/ast_expr2.c $(ASTTOPDIR)/main/ast_expr2.h astmm.o
$(ECHO_PREFIX) echo " [CC] ast_expr2f.c -> ast_expr2fz.o"
- $(CC) -g -c -I$(ASTTOPDIR)/include -DSTANDALONE $(ASTTOPDIR)/main/ast_expr2f.c -o ast_expr2fz.o
+ $(CC) -g -c -I$(ASTTOPDIR)/include $(_ASTCFLAGS) $(ASTTOPDIR)/main/ast_expr2f.c -o ast_expr2fz.o
$(ECHO_PREFIX) echo " [CC] ast_expr2.c -> ast_expr2z.o"
- $(CC) -g -c -I$(ASTTOPDIR)/include -DSTANDALONE2 $(ASTTOPDIR)/main/ast_expr2.c -o ast_expr2z.o
+ $(CC) -g -c -I$(ASTTOPDIR)/include $(_ASTCFLAGS) -DSTANDALONE2 $(ASTTOPDIR)/main/ast_expr2.c -o ast_expr2z.o
$(ECHO_PREFIX) echo " [LD] ast_expr2fz.o ast_expr2z.o -> check_expr2"
$(CC) -g -o check_expr2 ast_expr2fz.o ast_expr2z.o astmm.o -lm $(_ASTLDFLAGS)
$(ECHO_PREFIX) echo " [RM] ast_expr2fz.o ast_expr2z.o"
rm ast_expr2z.o ast_expr2fz.o
- ./check_expr2 expr2.testinput
smsq: smsq.o strcompat.o
smsq: LIBS+=$(POPT_LIB)

View file

@ -17,12 +17,12 @@
* build.h * build.h
--- a/Makefile --- a/Makefile
+++ b/Makefile +++ b/Makefile
@@ -484,7 +484,7 @@ doc/core-en_US.xml: makeopts .lastclean @@ -489,7 +489,7 @@ doc/core-en_US.xml: makeopts .lastclean
@echo "<docs xmlns:xi=\"http://www.w3.org/2001/XInclude\">" >> $@ @echo "<docs xmlns:xi=\"http://www.w3.org/2001/XInclude\">" >> $@
@for x in $(MOD_SUBDIRS); do \ @for x in $(MOD_SUBDIRS); do \
printf "$$x " ; \ printf "$$x " ; \
- for i in `find $$x -name '*.c'`; do \ - for i in `find $$x -name '*.c'`; do \
+ for i in `find $$x -name '*.c' | LC_ALL=C sort`; do \ + for i in `find $$x -name '*.c' | LC_ALL=C sort`; do \
$(AWK) -f build_tools/get_documentation $$i >> $@ ; \ MODULEINFO=$$($(AWK) -f build_tools/get_moduleinfo $$i) ; \
done ; \ if [ -n "$$MODULEINFO" ] ; \
done then \

View file

@ -1,247 +0,0 @@
commit 02fda2b478f98cf3b8a1df76f772bf0be73bddd5
Author: Sebastian Kemper <sebastian_ml@gmx.net>
Date: Tue Apr 2 22:49:52 2019 +0200
loader: support for permanent dlopen()
Asterisk assumes that dlopen() will always run the constructor of a
shared library and every dlclose() will run its destructor. But dlopen()
may be permanent, meaning the constructor will only be run once, as is
the case with musl libc.
With a permanent dlopen() the Asterisk module loader does not work
correctly, because it's expectations regarding when the constructors and
destructors are run are not met. In fact a segmentation fault will occur
when the first module is "re-opened" that has AST_MODFLAG_GLOBAL_SYMBOLS
set (the dlopen() does not call the constructor, resource_being_loaded
is not set to NULL, then strlen is called with NULL instead of a string,
see issue ASTERISK-28319).
This commit adds code to the loader that will manually run the
constructors/destructors of the (non-builtin) modules where needed. To
achieve this a new ao2 container (linked list) is started and filled
with objects that contain the names of the modules and the pointers to
their respective info structs.
This behavior can be activated when configuring Asterisk
(--enable-permanent-dlopen). By default this is disabled, of course.
ASTERISK-28319 #close
Signed-off-by: Sebastian Kemper <sebastian_ml@gmx.net>
Change-Id: I86693a0ecf25d5ba81c73773a03df4abc3426875
--- a/configure.ac
+++ b/configure.ac
@@ -727,6 +727,20 @@ if test "${DISABLE_XMLDOC}" != "yes"; th
fi
+AC_ARG_ENABLE([permanent-dlopen],
+ [AS_HELP_STRING([--enable-permanent-dlopen],
+ [Enable when your libc has a permanent dlopen like musl])],
+ [case "${enableval}" in
+ y|ye|yes) PERMANENT_DLOPEN=yes ;;
+ n|no) PERMANENT_DLOPEN=no ;;
+ *) AC_MSG_ERROR(bad value ${enableval} for --enable-permanent-dlopen) ;;
+ esac], [PERMANENT_DLOPEN=no])
+
+AC_SUBST([PERMANENT_DLOPEN])
+if test "${PERMANENT_DLOPEN}" == "yes"; then
+ AC_DEFINE([HAVE_PERMANENT_DLOPEN], 1, [Define to support libc with permanent dlopen.])
+fi
+
# some embedded systems omit internationalization (locale) support
AC_CHECK_HEADERS([xlocale.h])
--- a/main/loader.c
+++ b/main/loader.c
@@ -153,6 +153,117 @@ static unsigned int loader_ready;
static struct ast_vector_string startup_errors;
static struct ast_str *startup_error_builder;
+#if defined(HAVE_PERMANENT_DLOPEN)
+#define FIRST_DLOPEN 999
+
+struct ao2_container *info_list = NULL;
+
+struct info_list_obj {
+ const struct ast_module_info *info;
+ int dlopened;
+ char name[0];
+};
+
+static struct info_list_obj *info_list_obj_alloc(const char *name,
+ const struct ast_module_info *info)
+{
+ struct info_list_obj *new_entry;
+
+ new_entry = ao2_alloc(sizeof(*new_entry) + strlen(name) + 1, NULL);
+
+ if (!new_entry) {
+ return NULL;
+ }
+
+ strcpy(new_entry->name, name); /* SAFE */
+ new_entry->info = info;
+ new_entry->dlopened = FIRST_DLOPEN;
+
+ return new_entry;
+}
+
+AO2_STRING_FIELD_CMP_FN(info_list_obj, name)
+
+static char *get_name_from_resource(const char *resource)
+{
+ int len;
+ const char *last_three;
+ char *mod_name;
+
+ if (!resource) {
+ return NULL;
+ }
+
+ len = strlen(resource);
+ if (len > 3) {
+ last_three = &resource[len-3];
+ if (!strcasecmp(last_three, ".so")) {
+ mod_name = ast_calloc(1, len - 2);
+ if (mod_name) {
+ ast_copy_string(mod_name, resource, len - 2);
+ return mod_name;
+ } else {
+ /* Unable to allocate memory. */
+ return NULL;
+ }
+ }
+ }
+
+ /* Resource is the name - happens when manually unloading a module. */
+ mod_name = ast_calloc(1, len + 1);
+ if (mod_name) {
+ ast_copy_string(mod_name, resource, len + 1);
+ return mod_name;
+ }
+
+ /* Unable to allocate memory. */
+ return NULL;
+}
+
+static void manual_mod_reg(const void *lib, const char *resource)
+{
+ struct info_list_obj *obj_tmp;
+ char *mod_name;
+
+ if (lib) {
+ mod_name = get_name_from_resource(resource);
+ if (mod_name) {
+ obj_tmp = ao2_find(info_list, mod_name, OBJ_SEARCH_KEY);
+ if (obj_tmp) {
+ if (obj_tmp->dlopened == FIRST_DLOPEN) {
+ obj_tmp->dlopened = 1;
+ } else {
+ ast_module_register(obj_tmp->info);
+ }
+ ao2_ref(obj_tmp, -1);
+ }
+ ast_free(mod_name);
+ }
+ }
+}
+
+static void manual_mod_unreg(const char *resource)
+{
+ struct info_list_obj *obj_tmp;
+ char *mod_name;
+
+ /* When Asterisk shuts down the destructor is called automatically. */
+ if (ast_shutdown_final()) {
+ return;
+ }
+
+ mod_name = get_name_from_resource(resource);
+ if (mod_name) {
+ obj_tmp = ao2_find(info_list, mod_name, OBJ_SEARCH_KEY);
+ if (obj_tmp) {
+ ast_module_unregister(obj_tmp->info);
+ ao2_ref(obj_tmp, -1);
+ }
+ ast_free(mod_name);
+ }
+}
+#endif
+
static __attribute__((format(printf, 1, 2))) void module_load_error(const char *fmt, ...)
{
char *copy = NULL;
@@ -597,6 +708,23 @@ void ast_module_register(const struct as
/* give the module a copy of its own handle, for later use in registrations and the like */
*((struct ast_module **) &(info->self)) = mod;
+
+#if defined(HAVE_PERMANENT_DLOPEN)
+ if (mod->flags.builtin != 1) {
+ struct info_list_obj *obj_tmp = ao2_find(info_list, info->name,
+ OBJ_SEARCH_KEY);
+
+ if (!obj_tmp) {
+ obj_tmp = info_list_obj_alloc(info->name, info);
+ if (obj_tmp) {
+ ao2_link(info_list, obj_tmp);
+ ao2_ref(obj_tmp, -1);
+ }
+ } else {
+ ao2_ref(obj_tmp, -1);
+ }
+ }
+#endif
}
static int module_post_register(struct ast_module *mod)
@@ -843,6 +971,10 @@ static void logged_dlclose(const char *n
error = dlerror();
ast_log(AST_LOG_ERROR, "Failure in dlclose for module '%s': %s\n",
S_OR(name, "unknown"), S_OR(error, "Unknown error"));
+#if defined(HAVE_PERMANENT_DLOPEN)
+ } else {
+ manual_mod_unreg(name);
+#endif
}
}
@@ -949,6 +1081,9 @@ static struct ast_module *load_dlopen(co
resource_being_loaded = mod;
mod->lib = dlopen(filename, flags);
+#if defined(HAVE_PERMANENT_DLOPEN)
+ manual_mod_reg(mod->lib, mod->resource);
+#endif
if (resource_being_loaded) {
struct ast_str *list;
int c = 0;
@@ -968,6 +1103,9 @@ static struct ast_module *load_dlopen(co
resource_being_loaded = mod;
mod->lib = dlopen(filename, RTLD_LAZY | RTLD_LOCAL);
+#if defined(HAVE_PERMANENT_DLOPEN)
+ manual_mod_reg(mod->lib, mod->resource);
+#endif
if (resource_being_loaded) {
resource_being_loaded = NULL;
@@ -2206,6 +2344,15 @@ int load_modules(void)
ast_verb(1, "Asterisk Dynamic Loader Starting:\n");
+#if defined(HAVE_PERMANENT_DLOPEN)
+ info_list = ao2_container_alloc_list(AO2_ALLOC_OPT_LOCK_NOLOCK, 0, NULL,
+ info_list_obj_cmp_fn); /* must not be cleaned at shutdown */
+ if (!info_list) {
+ fprintf(stderr, "Module info list allocation failure.\n");
+ return 1;
+ }
+#endif
+
AST_LIST_HEAD_INIT_NOLOCK(&load_order);
AST_DLLIST_LOCK(&module_list);

View file

@ -1,6 +1,6 @@
--- a/configure.ac --- a/configure.ac
+++ b/configure.ac +++ b/configure.ac
@@ -1205,7 +1205,7 @@ if test "${ac_cv_have_variable_fdset}x" @@ -1206,7 +1206,7 @@ if test "${ac_cv_have_variable_fdset}x"
fi fi
AC_MSG_CHECKING([if we have usable eventfd support]) AC_MSG_CHECKING([if we have usable eventfd support])

View file

@ -1,40 +0,0 @@
From 785bf3a755e47d92caef110e6040295764d08127 Mon Sep 17 00:00:00 2001
From: George Joseph <gjoseph@digium.com>
Date: Wed, 12 Jun 2019 12:03:04 -0600
Subject: [PATCH] res_pjsip_messaging: Check for body in in-dialog message
We now check that a body exists and it has a length > 0 before
attempting to process it.
ASTERISK-28447
Reported-by: Gil Richard
Change-Id: Ic469544b22ab848734636588d4c93426cc6f4b1f
---
res/res_pjsip_messaging.c | 9 ++++++---
1 file changed, 6 insertions(+), 3 deletions(-)
diff --git a/res/res_pjsip_messaging.c b/res/res_pjsip_messaging.c
index 0e10a8f047..930cf84a53 100644
--- a/res/res_pjsip_messaging.c
+++ b/res/res_pjsip_messaging.c
@@ -90,10 +90,13 @@ static enum pjsip_status_code check_content_type_in_dialog(const pjsip_rx_data *
static const pj_str_t text = { "text", 4};
static const pj_str_t application = { "application", 11};
+ if (!(rdata->msg_info.msg->body && rdata->msg_info.msg->body->len > 0)) {
+ return res;
+ }
+
/* We'll accept any text/ or application/ content type */
- if (rdata->msg_info.msg->body && rdata->msg_info.msg->body->len
- && (pj_stricmp(&rdata->msg_info.msg->body->content_type.type, &text) == 0
- || pj_stricmp(&rdata->msg_info.msg->body->content_type.type, &application) == 0)) {
+ if (pj_stricmp(&rdata->msg_info.msg->body->content_type.type, &text) == 0
+ || pj_stricmp(&rdata->msg_info.msg->body->content_type.type, &application) == 0) {
res = PJSIP_SC_OK;
} else if (rdata->msg_info.ctype
&& (pj_stricmp(&rdata->msg_info.ctype->media.type, &text) == 0
--
2.21.0

View file

@ -1,39 +0,0 @@
From 1e4df0215af4f192ed06a7fc7589c799f1ec6091 Mon Sep 17 00:00:00 2001
From: Francesco Castellano <francesco.castellano@messagenet.it>
Date: Fri, 28 Jun 2019 18:15:31 +0200
Subject: [PATCH] chan_sip: Handle invalid SDP answer to T.38 re-invite
The chan_sip module performs a T.38 re-invite using a single media
stream of udptl, and expects the SDP answer to be the same.
If an SDP answer is received instead that contains an additional
media stream with no joint codec a crash will occur as the code
assumes that at least one joint codec will exist in this
scenario.
This change removes this assumption.
ASTERISK-28465
Change-Id: I8b02845b53344c6babe867a3f0a5231045c7ac87
---
diff --git a/channels/chan_sip.c b/channels/chan_sip.c
index 898b646..a609ff8 100644
--- a/channels/chan_sip.c
+++ b/channels/chan_sip.c
@@ -10965,7 +10965,13 @@
ast_rtp_lookup_mime_multiple2(s3, NULL, newnoncodeccapability, 0, 0));
}
- if (portno != -1 || vportno != -1 || tportno != -1) {
+ /* When UDPTL is negotiated it is expected that there are no compatible codecs as audio or
+ * video is not being transported, thus we continue in this function further up if that is
+ * the case. If we receive an SDP answer containing both a UDPTL stream and another media
+ * stream however we need to check again to ensure that there is at least one joint codec
+ * instead of assuming there is one.
+ */
+ if ((portno != -1 || vportno != -1 || tportno != -1) && ast_format_cap_count(newjointcapability)) {
/* We are now ready to change the sip session and RTP structures with the offered codecs, since
they are acceptable */
unsigned int framing;

View file

@ -1,171 +0,0 @@
From 69ed619a6d9b64a297d3099b6455756912e21d0b Mon Sep 17 00:00:00 2001
From: Kevin Harwell <kharwell@digium.com>
Date: Tue, 20 Aug 2019 15:05:45 -0500
Subject: [PATCH] AST-2019-004 - res_pjsip_t38.c: Add NULL checks before using session media
After receiving a 200 OK with a declined stream in response to a T.38
initiated re-invite Asterisk would crash when attempting to dereference
a NULL session media object.
This patch checks to make sure the session media object is not NULL before
attempting to use it.
ASTERISK-28495
patches:
ast-2019-004.patch submitted by Alexei Gradinari (license 5691)
Change-Id: I168f45f4da29cfe739acf87e597baa2aae7aa572
---
diff --git a/res/res_pjsip_t38.c b/res/res_pjsip_t38.c
index 11804e2..e5c6090 100644
--- a/res/res_pjsip_t38.c
+++ b/res/res_pjsip_t38.c
@@ -203,7 +203,6 @@
{
RAII_VAR(struct ast_sip_session *, session, obj, ao2_cleanup);
RAII_VAR(struct ast_datastore *, datastore, ast_sip_session_get_datastore(session, "t38"), ao2_cleanup);
- struct ast_sip_session_media *session_media;
if (!datastore) {
return 0;
@@ -212,8 +211,7 @@
ast_debug(2, "Automatically rejecting T.38 request on channel '%s'\n",
session->channel ? ast_channel_name(session->channel) : "<gone>");
- session_media = session->pending_media_state->default_session[AST_MEDIA_TYPE_IMAGE];
- t38_change_state(session, session_media, datastore->data, T38_REJECTED);
+ t38_change_state(session, NULL, datastore->data, T38_REJECTED);
ast_sip_session_resume_reinvite(session);
return 0;
@@ -322,28 +320,37 @@
int index;
session_media = session->active_media_state->default_session[AST_MEDIA_TYPE_IMAGE];
- t38_change_state(session, session_media, state, T38_ENABLED);
+ if (!session_media) {
+ ast_log(LOG_WARNING, "Received %d response to T.38 re-invite on '%s' but no active session media\n",
+ status.code, session->channel ? ast_channel_name(session->channel) : "unknown channel");
+ } else {
+ t38_change_state(session, session_media, state, T38_ENABLED);
- /* Stop all the streams in the stored away active state, they'll go back to being active once
- * we reinvite back.
- */
- for (index = 0; index < AST_VECTOR_SIZE(&state->media_state->sessions); ++index) {
- struct ast_sip_session_media *session_media = AST_VECTOR_GET(&state->media_state->sessions, index);
+ /* Stop all the streams in the stored away active state, they'll go back to being active once
+ * we reinvite back.
+ */
+ for (index = 0; index < AST_VECTOR_SIZE(&state->media_state->sessions); ++index) {
+ struct ast_sip_session_media *session_media = AST_VECTOR_GET(&state->media_state->sessions, index);
- if (session_media && session_media->handler && session_media->handler->stream_stop) {
- session_media->handler->stream_stop(session_media);
+ if (session_media && session_media->handler && session_media->handler->stream_stop) {
+ session_media->handler->stream_stop(session_media);
+ }
}
+
+ return 0;
}
} else {
session_media = session->pending_media_state->default_session[AST_MEDIA_TYPE_IMAGE];
- t38_change_state(session, session_media, state, T38_REJECTED);
-
- /* Abort this attempt at switching to T.38 by resetting the pending state and freeing our stored away active state */
- ast_sip_session_media_state_free(state->media_state);
- state->media_state = NULL;
- ast_sip_session_media_state_reset(session->pending_media_state);
}
+ /* If no session_media then response contained a declined stream, so disable */
+ t38_change_state(session, NULL, state, session_media ? T38_REJECTED : T38_DISABLED);
+
+ /* Abort this attempt at switching to T.38 by resetting the pending state and freeing our stored away active state */
+ ast_sip_session_media_state_free(state->media_state);
+ state->media_state = NULL;
+ ast_sip_session_media_state_reset(session->pending_media_state);
+
return 0;
}
@@ -426,12 +433,10 @@
/* Negotiation can not take place without a valid max_ifp value. */
if (!parameters->max_ifp) {
if (data->session->t38state == T38_PEER_REINVITE) {
- session_media = data->session->pending_media_state->default_session[AST_MEDIA_TYPE_IMAGE];
- t38_change_state(data->session, session_media, state, T38_REJECTED);
+ t38_change_state(data->session, NULL, state, T38_REJECTED);
ast_sip_session_resume_reinvite(data->session);
} else if (data->session->t38state == T38_ENABLED) {
- session_media = data->session->active_media_state->default_session[AST_MEDIA_TYPE_IMAGE];
- t38_change_state(data->session, session_media, state, T38_DISABLED);
+ t38_change_state(data->session, NULL, state, T38_DISABLED);
ast_sip_session_refresh(data->session, NULL, NULL, NULL,
AST_SIP_SESSION_REFRESH_METHOD_INVITE, 1, state->media_state);
state->media_state = NULL;
@@ -454,6 +459,11 @@
state->our_parms.version = MIN(state->our_parms.version, state->their_parms.version);
state->our_parms.rate_management = state->their_parms.rate_management;
session_media = data->session->pending_media_state->default_session[AST_MEDIA_TYPE_IMAGE];
+ if (!session_media) {
+ ast_log(LOG_ERROR, "Failed to negotiate parameters for reinvite on channel '%s' (No pending session media).\n",
+ data->session->channel ? ast_channel_name(data->session->channel) : "unknown channel");
+ break;
+ }
ast_udptl_set_local_max_ifp(session_media->udptl, state->our_parms.max_ifp);
t38_change_state(data->session, session_media, state, T38_ENABLED);
ast_sip_session_resume_reinvite(data->session);
@@ -468,8 +478,13 @@
}
state->our_parms = *parameters;
session_media = media_state->default_session[AST_MEDIA_TYPE_IMAGE];
+ if (!session_media) {
+ ast_log(LOG_ERROR, "Failed to negotiate parameters on channel '%s' (No default session media).\n",
+ data->session->channel ? ast_channel_name(data->session->channel) : "unknown channel");
+ break;
+ }
ast_udptl_set_local_max_ifp(session_media->udptl, state->our_parms.max_ifp);
- t38_change_state(data->session, session_media, state, T38_LOCAL_REINVITE);
+ t38_change_state(data->session, NULL, state, T38_LOCAL_REINVITE);
ast_sip_session_refresh(data->session, NULL, t38_reinvite_sdp_cb, t38_reinvite_response_cb,
AST_SIP_SESSION_REFRESH_METHOD_INVITE, 1, media_state);
}
@@ -478,12 +493,10 @@
case AST_T38_REFUSED:
case AST_T38_REQUEST_TERMINATE: /* Shutdown T38 */
if (data->session->t38state == T38_PEER_REINVITE) {
- session_media = data->session->pending_media_state->default_session[AST_MEDIA_TYPE_IMAGE];
- t38_change_state(data->session, session_media, state, T38_REJECTED);
+ t38_change_state(data->session, NULL, state, T38_REJECTED);
ast_sip_session_resume_reinvite(data->session);
} else if (data->session->t38state == T38_ENABLED) {
- session_media = data->session->active_media_state->default_session[AST_MEDIA_TYPE_IMAGE];
- t38_change_state(data->session, session_media, state, T38_DISABLED);
+ t38_change_state(data->session, NULL, state, T38_DISABLED);
ast_sip_session_refresh(data->session, NULL, NULL, NULL, AST_SIP_SESSION_REFRESH_METHOD_INVITE, 1, state->media_state);
state->media_state = NULL;
}
@@ -493,6 +506,11 @@
if (data->session->t38state == T38_PEER_REINVITE) {
session_media = data->session->pending_media_state->default_session[AST_MEDIA_TYPE_IMAGE];
+ if (!session_media) {
+ ast_log(LOG_ERROR, "Failed to request parameters for reinvite on channel '%s' (No pending session media).\n",
+ data->session->channel ? ast_channel_name(data->session->channel) : "unknown channel");
+ break;
+ }
parameters.max_ifp = ast_udptl_get_far_max_ifp(session_media->udptl);
parameters.request_response = AST_T38_REQUEST_NEGOTIATE;
ast_queue_control_data(data->session->channel, AST_CONTROL_T38_PARAMETERS, &parameters, sizeof(parameters));
@@ -788,7 +806,7 @@
if ((session->t38state == T38_REJECTED) || (session->t38state == T38_DISABLED)) {
ast_debug(3, "Declining; T.38 state is rejected or declined\n");
- t38_change_state(session, session_media, state, T38_DISABLED);
+ t38_change_state(session, NULL, state, T38_DISABLED);
return 0;
}

View file

@ -1,73 +0,0 @@
From 8cdaa93e658a46e7baf6b606468b5e2c88a0133b Mon Sep 17 00:00:00 2001
From: Ben Ford <bford@digium.com>
Date: Mon, 21 Oct 2019 14:55:06 -0500
Subject: [PATCH] chan_sip.c: Prevent address change on unauthenticated SIP request.
If the name of a peer is known and a SIP request is sent using that
peer's name, the address of the peer will change even if the request
fails the authentication challenge. This means that an endpoint can
be altered and even rendered unusuable, even if it was in a working
state previously. This can only occur when the nat option is set to the
default, or auto_force_rport.
This change checks the result of authentication first to ensure it is
successful before setting the address and the nat option.
ASTERISK-28589 #close
Change-Id: I581c5ed1da60ca89f590bd70872de2b660de02df
---
diff --git a/channels/chan_sip.c b/channels/chan_sip.c
index 6ac2e61..4d79a47 100644
--- a/channels/chan_sip.c
+++ b/channels/chan_sip.c
@@ -19245,18 +19245,6 @@
bogus_peer = NULL;
}
- /* build_peer, called through sip_find_peer, is not able to check the
- * sip_pvt->natdetected flag in order to determine if the peer is behind
- * NAT or not when SIP_PAGE3_NAT_AUTO_RPORT or SIP_PAGE3_NAT_AUTO_COMEDIA
- * are set on the peer. So we check for that here and set the peer's
- * address accordingly.
- */
- set_peer_nat(p, peer);
-
- if (p->natdetected && ast_test_flag(&peer->flags[2], SIP_PAGE3_NAT_AUTO_RPORT)) {
- ast_sockaddr_copy(&peer->addr, &p->recv);
- }
-
if (!ast_apply_acl(peer->acl, addr, "SIP Peer ACL: ")) {
ast_debug(2, "Found peer '%s' for '%s', but fails host access\n", peer->name, of);
sip_unref_peer(peer, "sip_unref_peer: check_peer_ok: from sip_find_peer call, early return of AUTH_ACL_FAILED");
@@ -19325,6 +19313,21 @@
ast_string_field_set(p, peermd5secret, NULL);
}
if (!(res = check_auth(p, req, peer->name, p->peersecret, p->peermd5secret, sipmethod, uri2, reliable))) {
+
+ /* build_peer, called through sip_find_peer, is not able to check the
+ * sip_pvt->natdetected flag in order to determine if the peer is behind
+ * NAT or not when SIP_PAGE3_NAT_AUTO_RPORT or SIP_PAGE3_NAT_AUTO_COMEDIA
+ * are set on the peer. So we check for that here and set the peer's
+ * address accordingly. The address should ONLY be set once we are sure
+ * authentication was a success. If, for example, an INVITE was sent that
+ * matched the peer name but failed the authentication check, the address
+ * would be updated, which is bad.
+ */
+ set_peer_nat(p, peer);
+ if (p->natdetected && ast_test_flag(&peer->flags[2], SIP_PAGE3_NAT_AUTO_RPORT)) {
+ ast_sockaddr_copy(&peer->addr, &p->recv);
+ }
+
/* If we have a call limit, set flag */
if (peer->call_limit)
ast_set_flag(&p->flags[0], SIP_CALL_LIMIT);
@@ -19424,6 +19427,7 @@
}
}
sip_unref_peer(peer, "check_peer_ok: sip_unref_peer: tossing temp ptr to peer from sip_find_peer");
+
return res;
}

View file

@ -1,41 +0,0 @@
From 7574be5110e049a44b8c8ead52cd1c2a5d442afa Mon Sep 17 00:00:00 2001
From: George Joseph <gjoseph@digium.com>
Date: Thu, 24 Oct 2019 11:41:23 -0600
Subject: [PATCH] manager.c: Prevent the Originate action from running the Originate app
If an AMI user without the "system" authorization calls the
Originate AMI command with the Originate application,
the second Originate could run the "System" command.
Action: Originate
Channel: Local/1111
Application: Originate
Data: Local/2222,app,System,touch /tmp/owned
If the "system" authorization isn't set, we now block the
Originate app as well as the System, Exec, etc. apps.
ASTERISK-28580
Reported by: Eliel Sardañons
Change-Id: Ic4c9dedc34c426f03c8c14fce334a71386d8a5fa
---
--- /dev/null
+++ b/doc/UPGRADE-staging/AMI-Originate.txt
@@ -0,0 +1,5 @@
+Subject: AMI
+
+The AMI Originate action, which optionally takes a dialplan application as
+an argument, no longer accepts "Originate" as the application due to
+security concerns.
--- a/main/manager.c
+++ b/main/manager.c
@@ -5697,6 +5697,7 @@ static int action_originate(struct manse
EAGI(/bin/rm,-rf /) */
strcasestr(app, "mixmonitor") || /* MixMonitor(blah,,rm -rf) */
strcasestr(app, "externalivr") || /* ExternalIVR(rm -rf) */
+ strcasestr(app, "originate") || /* Originate(Local/1234,app,System,rm -rf) */
(strstr(appdata, "SHELL") && (bad_appdata = 1)) || /* NoOp(${SHELL(rm -rf /)}) */
(strstr(appdata, "EVAL") && (bad_appdata = 1)) /* NoOp(${EVAL(${some_var_containing_SHELL})}) */
)) {

View file

@ -1,401 +0,0 @@
commit 523ed150b16d799bcf223b841abd82f25b8cd6a0
Author: Kevin Harwell <kharwell@digium.com>
Date: Mon Oct 19 17:21:57 2020 -0500
AST-2020-001 - res_pjsip: Return dialog locked and referenced
pjproject returns the dialog locked and with a reference. However,
in Asterisk the method that handles this decrements the reference
and removes the lock prior to returning. This makes it possible,
under some circumstances, for another thread to free said dialog
before the thread that created it attempts to use it again. Of
course when the thread that created it tries to use a freed dialog
a crash can occur.
This patch makes it so Asterisk now returns the newly created
dialog both locked, and with an added reference. This allows the
caller to de-reference, and unlock the dialog when it is safe to
do so.
In the case of a new SIP Invite the lock, and reference are now
held for the entirety of the new invite handling process.
Otherwise it's possible for the dialog, or its dependent objects,
like the transaction, to disappear. For example if there is a TCP
transport error.
Change-Id: I5ef645a47829596f402cf383dc02c629c618969e
--- a/include/asterisk/res_pjsip.h
+++ b/include/asterisk/res_pjsip.h
@@ -1908,6 +1908,11 @@ pjsip_dialog *ast_sip_create_dialog_uac(
/*!
* \brief General purpose method for creating a UAS dialog with an endpoint
*
+ * \deprecated This function is unsafe (due to the returned object not being locked nor
+ * having its reference incremented) and should no longer be used. Instead
+ * use ast_sip_create_dialog_uas_locked so a properly locked and referenced
+ * object is returned.
+ *
* \param endpoint A pointer to the endpoint
* \param rdata The request that is starting the dialog
* \param[out] status On failure, the reason for failure in creating the dialog
@@ -1915,6 +1920,44 @@ pjsip_dialog *ast_sip_create_dialog_uac(
pjsip_dialog *ast_sip_create_dialog_uas(const struct ast_sip_endpoint *endpoint, pjsip_rx_data *rdata, pj_status_t *status);
/*!
+ * \brief General purpose method for creating a UAS dialog with an endpoint
+ *
+ * This function creates and returns a locked, and referenced counted pjsip
+ * dialog object. The caller is thus responsible for freeing the allocated
+ * memory, decrementing the reference, and releasing the lock when done with
+ * the returned object.
+ *
+ * \note The safest way to unlock the object, and decrement its reference is by
+ * calling pjsip_dlg_dec_lock. Alternatively, pjsip_dlg_dec_session can be
+ * used to decrement the reference only.
+ *
+ * The dialog is returned locked and with a reference in order to ensure that the
+ * dialog object, and any of its associated objects (e.g. transaction) are not
+ * untimely destroyed. For instance, that could happen when a transport error
+ * occurs.
+ *
+ * As long as the caller maintains a reference to the dialog there should be no
+ * worry that it might unknowningly be destroyed. However, once the caller unlocks
+ * the dialog there is a danger that some of the dialog's internal objects could
+ * be lost and/or compromised. For example, when the aforementioned transport error
+ * occurs the dialog's associated transaction gets destroyed (see pjsip_dlg_on_tsx_state
+ * in sip_dialog.c, and mod_inv_on_tsx_state in sip_inv.c).
+ *
+ * In this case and before using the dialog again the caller should re-lock the
+ * dialog, check to make sure the dialog is still established, and the transaction
+ * still exists and has not been destroyed.
+ *
+ * \param endpoint A pointer to the endpoint
+ * \param rdata The request that is starting the dialog
+ * \param[out] status On failure, the reason for failure in creating the dialog
+ *
+ * \retval A locked, and reference counted pjsip_dialog object.
+ * \retval NULL on failure
+ */
+pjsip_dialog *ast_sip_create_dialog_uas_locked(const struct ast_sip_endpoint *endpoint,
+ pjsip_rx_data *rdata, pj_status_t *status);
+
+/*!
* \brief General purpose method for creating an rdata structure using specific information
* \since 13.15.0
*
--- a/res/res_pjsip.c
+++ b/res/res_pjsip.c
@@ -3645,7 +3645,11 @@ static int uas_use_sips_contact(pjsip_rx
return 0;
}
-pjsip_dialog *ast_sip_create_dialog_uas(const struct ast_sip_endpoint *endpoint, pjsip_rx_data *rdata, pj_status_t *status)
+typedef pj_status_t (*create_dlg_uac)(pjsip_user_agent *ua, pjsip_rx_data *rdata,
+ const pj_str_t *contact, pjsip_dialog **p_dlg);
+
+static pjsip_dialog *create_dialog_uas(const struct ast_sip_endpoint *endpoint,
+ pjsip_rx_data *rdata, pj_status_t *status, create_dlg_uac create_fun)
{
pjsip_dialog *dlg;
pj_str_t contact;
@@ -3680,11 +3684,7 @@ pjsip_dialog *ast_sip_create_dialog_uas(
(type != PJSIP_TRANSPORT_UDP && type != PJSIP_TRANSPORT_UDP6) ? ";transport=" : "",
(type != PJSIP_TRANSPORT_UDP && type != PJSIP_TRANSPORT_UDP6) ? pjsip_transport_get_type_name(type) : "");
-#ifdef HAVE_PJSIP_DLG_CREATE_UAS_AND_INC_LOCK
- *status = pjsip_dlg_create_uas_and_inc_lock(pjsip_ua_instance(), rdata, &contact, &dlg);
-#else
- *status = pjsip_dlg_create_uas(pjsip_ua_instance(), rdata, &contact, &dlg);
-#endif
+ *status = create_fun(pjsip_ua_instance(), rdata, &contact, &dlg);
if (*status != PJ_SUCCESS) {
char err[PJ_ERR_MSG_SIZE];
@@ -3697,11 +3697,46 @@ pjsip_dialog *ast_sip_create_dialog_uas(
dlg->sess_count++;
pjsip_dlg_set_transport(dlg, &selector);
dlg->sess_count--;
+
+ return dlg;
+}
+
+pjsip_dialog *ast_sip_create_dialog_uas(const struct ast_sip_endpoint *endpoint, pjsip_rx_data *rdata, pj_status_t *status)
+{
#ifdef HAVE_PJSIP_DLG_CREATE_UAS_AND_INC_LOCK
- pjsip_dlg_dec_lock(dlg);
+ pjsip_dialog *dlg;
+
+ dlg = create_dialog_uas(endpoint, rdata, status, pjsip_dlg_create_uas_and_inc_lock);
+ if (dlg) {
+ pjsip_dlg_dec_lock(dlg);
+ }
+
+ return dlg;
+#else
+ return create_dialog_uas(endpoint, rdata, status, pjsip_dlg_create_uas);
#endif
+}
+
+pjsip_dialog *ast_sip_create_dialog_uas_locked(const struct ast_sip_endpoint *endpoint,
+ pjsip_rx_data *rdata, pj_status_t *status)
+{
+#ifdef HAVE_PJSIP_DLG_CREATE_UAS_AND_INC_LOCK
+ return create_dialog_uas(endpoint, rdata, status, pjsip_dlg_create_uas_and_inc_lock);
+#else
+ /*
+ * This is put here in order to be compatible with older versions of pjproject.
+ * Best we can do in this case is immediately lock after getting the dialog.
+ * However, that does leave a "gap" between creating and locking.
+ */
+ pjsip_dialog *dlg;
+
+ dlg = create_dialog_uas(endpoint, rdata, status, pjsip_dlg_create_uas);
+ if (dlg) {
+ pjsip_dlg_inc_lock(dlg);
+ }
return dlg;
+#endif
}
int ast_sip_create_rdata_with_contact(pjsip_rx_data *rdata, char *packet, const char *src_name, int src_port,
--- a/res/res_pjsip_pubsub.c
+++ b/res/res_pjsip_pubsub.c
@@ -1457,7 +1457,7 @@ static struct sip_subscription_tree *cre
}
sub_tree->role = AST_SIP_NOTIFIER;
- dlg = ast_sip_create_dialog_uas(endpoint, rdata, dlg_status);
+ dlg = ast_sip_create_dialog_uas_locked(endpoint, rdata, dlg_status);
if (!dlg) {
if (*dlg_status != PJ_EEXISTS) {
ast_log(LOG_WARNING, "Unable to create dialog for SIP subscription\n");
@@ -1478,8 +1478,16 @@ static struct sip_subscription_tree *cre
}
pjsip_evsub_create_uas(dlg, &pubsub_cb, rdata, 0, &sub_tree->evsub);
+
subscription_setup_dialog(sub_tree, dlg);
+ /*
+ * The evsub and subscription setup both add dialog refs, so the dialog ref that
+ * was added when the dialog was created (see ast_sip_create_dialog_uas_lock) can
+ * now be removed. The lock should no longer be needed so can be removed too.
+ */
+ pjsip_dlg_dec_lock(dlg);
+
#ifdef HAVE_PJSIP_EVSUB_GRP_LOCK
pjsip_evsub_add_ref(sub_tree->evsub);
#endif
--- a/res/res_pjsip_session.c
+++ b/res/res_pjsip_session.c
@@ -2942,6 +2942,75 @@ static enum sip_get_destination_result g
return SIP_GET_DEST_EXTEN_NOT_FOUND;
}
+/*
+ * /internal
+ * /brief Process initial answer for an incoming invite
+ *
+ * This function should only be called during the setup, and handling of a
+ * new incoming invite. Most, if not all of the time, this will be called
+ * when an error occurs and we need to respond as such.
+ *
+ * When a SIP session termination code is given for the answer it's assumed
+ * this call then will be the final bit of processing before ending session
+ * setup. As such, we've been holding a lock, and a reference on the invite
+ * session's dialog. So before returning this function removes that reference,
+ * and unlocks the dialog.
+ *
+ * \param inv_session The session on which to answer
+ * \param rdata The original request
+ * \param answer_code The answer's numeric code
+ * \param terminate_code The termination code if the answer fails
+ * \param notify Whether or not to call on_state_changed
+ *
+ * \retval 0 if invite successfully answered, -1 if an error occurred
+ */
+static int new_invite_initial_answer(pjsip_inv_session *inv_session, pjsip_rx_data *rdata,
+ int answer_code, int terminate_code, pj_bool_t notify)
+{
+ pjsip_tx_data *tdata = NULL;
+ int res = 0;
+
+ if (inv_session->state != PJSIP_INV_STATE_DISCONNECTED) {
+ if (pjsip_inv_initial_answer(
+ inv_session, rdata, answer_code, NULL, NULL, &tdata) != PJ_SUCCESS) {
+
+ pjsip_inv_terminate(inv_session, terminate_code ? terminate_code : answer_code, notify);
+ res = -1;
+ } else {
+ pjsip_inv_send_msg(inv_session, tdata);
+ }
+ }
+
+ if (answer_code >= 300) {
+ /*
+ * A session is ending. The dialog has a reference that needs to be
+ * removed and holds a lock that needs to be unlocked before returning.
+ */
+ pjsip_dlg_dec_lock(inv_session->dlg);
+ }
+
+ return res;
+}
+
+/*
+ * /internal
+ * /brief Create and initialize a pjsip invite session
+
+ * pjsip_inv_session adds, and maintains a reference to the dialog upon a successful
+ * invite session creation until the session is destroyed. However, we'll wait to
+ * remove the reference that was added for the dialog when it gets created since we're
+ * not ready to unlock the dialog in this function.
+ *
+ * So, if this function successfully returns that means it returns with its newly
+ * created, and associated dialog locked and with two references (i.e. dialog's
+ * reference count should be 2).
+ *
+ * \param endpoint A pointer to the endpoint
+ * \param rdata The request that is starting the dialog
+ *
+ * \retval A pjsip invite session object
+ * \retval NULL on error
+ */
static pjsip_inv_session *pre_session_setup(pjsip_rx_data *rdata, const struct ast_sip_endpoint *endpoint)
{
pjsip_tx_data *tdata;
@@ -2960,15 +3029,28 @@ static pjsip_inv_session *pre_session_se
}
return NULL;
}
- dlg = ast_sip_create_dialog_uas(endpoint, rdata, &dlg_status);
+
+ dlg = ast_sip_create_dialog_uas_locked(endpoint, rdata, &dlg_status);
if (!dlg) {
if (dlg_status != PJ_EEXISTS) {
pjsip_endpt_respond_stateless(ast_sip_get_pjsip_endpoint(), rdata, 500, NULL, NULL, NULL);
}
return NULL;
}
+
+ /*
+ * The returned dialog holds a lock and has a reference added. Any paths where the
+ * dialog invite session is not returned must unlock the dialog and remove its reference.
+ */
+
if (pjsip_inv_create_uas(dlg, rdata, NULL, options, &inv_session) != PJ_SUCCESS) {
pjsip_endpt_respond_stateless(ast_sip_get_pjsip_endpoint(), rdata, 500, NULL, NULL, NULL);
+ /*
+ * The acquired dialog holds a lock, and a reference. Since the dialog is not
+ * going to be returned here it must first be unlocked and de-referenced. This
+ * must be done prior to calling dialog termination.
+ */
+ pjsip_dlg_dec_lock(dlg);
pjsip_dlg_terminate(dlg);
return NULL;
}
@@ -2977,12 +3059,13 @@ static pjsip_inv_session *pre_session_se
inv_session->sdp_neg_flags = PJMEDIA_SDP_NEG_ALLOW_MEDIA_CHANGE;
#endif
if (pjsip_dlg_add_usage(dlg, &session_module, NULL) != PJ_SUCCESS) {
- if (pjsip_inv_initial_answer(inv_session, rdata, 500, NULL, NULL, &tdata) != PJ_SUCCESS) {
- pjsip_inv_terminate(inv_session, 500, PJ_FALSE);
- }
- pjsip_inv_send_msg(inv_session, tdata);
+ /* Dialog's lock and a reference are removed in new_invite_initial_answer */
+ new_invite_initial_answer(inv_session, rdata, 500, 500, PJ_FALSE);
+ /* Remove 2nd reference added at inv_session creation */
+ pjsip_dlg_dec_session(inv_session->dlg, &session_module);
return NULL;
}
+
return inv_session;
}
@@ -3121,7 +3204,6 @@ static void handle_new_invite_request(pj
{
RAII_VAR(struct ast_sip_endpoint *, endpoint,
ast_pjsip_rdata_get_endpoint(rdata), ao2_cleanup);
- pjsip_tx_data *tdata = NULL;
pjsip_inv_session *inv_session = NULL;
struct ast_sip_session *session;
struct new_invite invite;
@@ -3134,27 +3216,48 @@ static void handle_new_invite_request(pj
return;
}
+ /*
+ * Upon a successful pre_session_setup the associated dialog is returned locked
+ * and with an added reference. Well actually two references. One added when the
+ * dialog itself was created, and another added when the pjsip invite session was
+ * created and the dialog was added to it.
+ *
+ * In order to ensure the dialog's, and any of its internal attributes, lifetimes
+ * we'll hold the lock and maintain the reference throughout the entire new invite
+ * handling process. See ast_sip_create_dialog_uas_locked for more details but,
+ * basically we do this to make sure a transport failure does not destroy the dialog
+ * and/or transaction out from underneath us between pjsip calls. Alternatively, we
+ * could probably release the lock if we needed to, but then we'd have to re-lock and
+ * check the dialog and transaction prior to every pjsip call.
+ *
+ * That means any off nominal/failure paths in this function must remove the associated
+ * dialog reference added at dialog creation, and remove the lock. As well the
+ * referenced pjsip invite session must be "cleaned up", which should also then
+ * remove its reference to the dialog at that time.
+ *
+ * Nominally we'll unlock the dialog, and release the reference when all new invite
+ * process handling has successfully completed.
+ */
+
#ifdef HAVE_PJSIP_INV_SESSION_REF
if (pjsip_inv_add_ref(inv_session) != PJ_SUCCESS) {
ast_log(LOG_ERROR, "Can't increase the session reference counter\n");
- if (inv_session->state != PJSIP_INV_STATE_DISCONNECTED) {
- if (pjsip_inv_initial_answer(inv_session, rdata, 500, NULL, NULL, &tdata) == PJ_SUCCESS) {
- pjsip_inv_terminate(inv_session, 500, PJ_FALSE);
- } else {
- pjsip_inv_send_msg(inv_session, tdata);
- }
+ /* Dialog's lock and a reference are removed in new_invite_initial_answer */
+ if (!new_invite_initial_answer(inv_session, rdata, 500, 500, PJ_FALSE)) {
+ /* Terminate the session if it wasn't done in the answer */
+ pjsip_inv_terminate(inv_session, 500, PJ_FALSE);
}
return;
}
#endif
-
session = ast_sip_session_alloc(endpoint, NULL, inv_session, rdata);
if (!session) {
- if (pjsip_inv_initial_answer(inv_session, rdata, 500, NULL, NULL, &tdata) == PJ_SUCCESS) {
+ /* Dialog's lock and reference are removed in new_invite_initial_answer */
+ if (!new_invite_initial_answer(inv_session, rdata, 500, 500, PJ_FALSE)) {
+ /* Terminate the session if it wasn't done in the answer */
pjsip_inv_terminate(inv_session, 500, PJ_FALSE);
- } else {
- pjsip_inv_send_msg(inv_session, tdata);
}
+
#ifdef HAVE_PJSIP_INV_SESSION_REF
pjsip_inv_dec_ref(inv_session);
#endif
@@ -3172,6 +3275,17 @@ static void handle_new_invite_request(pj
invite.rdata = rdata;
new_invite(&invite);
+ /*
+ * The dialog lock and reference added at dialog creation time must be
+ * maintained throughout the new invite process. Since we're pretty much
+ * done at this point with things it's safe to go ahead and remove the lock
+ * and the reference here. See ast_sip_create_dialog_uas_locked for more info.
+ *
+ * Note, any future functionality added that does work using the dialog must
+ * be done before this.
+ */
+ pjsip_dlg_dec_lock(inv_session->dlg);
+
ao2_ref(session, -1);
}

View file

@ -1,102 +0,0 @@
From f83efa12f7411dd100f49933bf71297c8ed9f765 Mon Sep 17 00:00:00 2001
From: Ben Ford <bford@digium.com>
Date: Mon, 02 Nov 2020 10:29:31 -0600
Subject: [PATCH] AST-2020-002 - res_pjsip: Stop sending INVITEs after challenge limit.
If Asterisk sends out an INVITE and receives a challenge with a
different nonce value each time, it will continuously send out INVITEs,
even if the call is hung up. The endpoint must be configured for
outbound authentication for this to occur. A limit has been set on
outbound INVITEs so that, once reached, Asterisk will stop sending
INVITEs and the transaction will terminate.
ASTERISK-29013
Change-Id: I2d001ca745b00ca8aa12030f2240cd72363b46f7
---
--- a/include/asterisk/res_pjsip.h
+++ b/include/asterisk/res_pjsip.h
@@ -63,6 +63,9 @@ struct pjsip_tpselector;
/*! \brief Maximum number of ciphers supported for a TLS transport */
#define SIP_TLS_MAX_CIPHERS 64
+/*! Maximum number of challenges before assuming that we are in a loop */
+#define MAX_RX_CHALLENGES 10
+
/*!
* \brief Structure for SIP transport information
*/
--- a/include/asterisk/res_pjsip_session.h
+++ b/include/asterisk/res_pjsip_session.h
@@ -215,8 +215,10 @@ struct ast_sip_session {
enum ast_sip_dtmf_mode dtmf;
/*! Initial incoming INVITE Request-URI. NULL otherwise. */
pjsip_uri *request_uri;
- /* Media statistics for negotiated RTP streams */
+ /*! Media statistics for negotiated RTP streams */
AST_VECTOR(, struct ast_rtp_instance_stats *) media_stats;
+ /*! Number of challenges received during outgoing requests to determine if we are in a loop */
+ unsigned int authentication_challenge_count:4;
};
typedef int (*ast_sip_session_request_creation_cb)(struct ast_sip_session *session, pjsip_tx_data *tdata);
--- a/res/res_pjsip.c
+++ b/res/res_pjsip.c
@@ -4027,8 +4027,6 @@ static pj_bool_t does_method_match(const
return pj_stristr(&method, message_method) ? PJ_TRUE : PJ_FALSE;
}
-/*! Maximum number of challenges before assuming that we are in a loop */
-#define MAX_RX_CHALLENGES 10
#define TIMER_INACTIVE 0
#define TIMEOUT_TIMER2 5
--- a/res/res_pjsip_session.c
+++ b/res/res_pjsip_session.c
@@ -2052,7 +2052,6 @@ static pjsip_module session_reinvite_mod
.on_rx_request = session_reinvite_on_rx_request,
};
-
void ast_sip_session_send_request_with_cb(struct ast_sip_session *session, pjsip_tx_data *tdata,
ast_sip_session_response_cb on_response)
{
@@ -2301,6 +2300,9 @@ struct ast_sip_session *ast_sip_session_
return NULL;
}
+ /* Track the number of challenges received on outbound requests */
+ session->authentication_challenge_count = 0;
+
/* Fire seesion begin handlers */
handle_session_begin(session);
@@ -2470,6 +2472,11 @@ static pj_bool_t outbound_invite_auth(pj
session = inv->mod_data[session_module.id];
+ if (++session->authentication_challenge_count > MAX_RX_CHALLENGES) {
+ ast_debug(1, "Initial INVITE reached maximum number of auth attempts.\n");
+ return PJ_FALSE;
+ }
+
if (ast_sip_create_request_with_auth(&session->endpoint->outbound_auths, rdata,
tsx->last_tx, &tdata)) {
return PJ_FALSE;
@@ -3846,6 +3853,7 @@ static void session_inv_on_tsx_state_cha
ast_debug(1, "reINVITE received final response code %d\n",
tsx->status_code);
if ((tsx->status_code == 401 || tsx->status_code == 407)
+ && ++session->authentication_challenge_count < MAX_RX_CHALLENGES
&& !ast_sip_create_request_with_auth(
&session->endpoint->outbound_auths,
e->body.tsx_state.src.rdata, tsx->last_tx, &tdata)) {
@@ -3920,6 +3928,7 @@ static void session_inv_on_tsx_state_cha
(int) pj_strlen(&tsx->method.name), pj_strbuf(&tsx->method.name),
tsx->status_code);
if ((tsx->status_code == 401 || tsx->status_code == 407)
+ && ++session->authentication_challenge_count < MAX_RX_CHALLENGES
&& !ast_sip_create_request_with_auth(
&session->endpoint->outbound_auths,
e->body.tsx_state.src.rdata, tsx->last_tx, &tdata)) {

View file

@ -1,87 +0,0 @@
From 757b7f8d7cfee4f541e8d7586e2408556a74201d Mon Sep 17 00:00:00 2001
From: Ivan Poddubnyi <ivan.poddubny@gmail.com>
Date: Mon, 28 Dec 2020 13:43:23 +0100
Subject: [PATCH] res_pjsip_diversion: Fix adding more than one histinfo to
Supported
New responses sent within a PJSIP sessions are based on those that were
sent before. Therefore, adding/modifying a header once causes it to be
sent on all responses that follow.
Sending 181 Call Is Being Forwarded many times first adds "histinfo"
duplicated more and more, and eventually overflows past the array
boundary.
This commit adds a check preventing adding "histinfo" more than once,
and skipping it if there is no more space in the header.
Similar overflow situations can also occur in res_pjsip_path and
res_pjsip_outbound_registration so those were also modified to
check the bounds and suppress duplicate Supported values.
ASTERISK-29227
Reported by: Ivan Poddubny
Change-Id: Id43704a1f1a0293e35cc7f844026f0b04f2ac322
---
res/res_pjsip_diversion.c | 14 ++++++++++++++
res/res_pjsip_outbound_registration.c | 12 ++++++++++++
res/res_pjsip_path.c | 12 ++++++++++++
3 files changed, 38 insertions(+)
--- a/res/res_pjsip_outbound_registration.c
+++ b/res/res_pjsip_outbound_registration.c
@@ -580,6 +580,7 @@ static int handle_client_registration(vo
if (client_state->support_path) {
pjsip_supported_hdr *hdr;
+ int i;
hdr = pjsip_msg_find_hdr(tdata->msg, PJSIP_H_SUPPORTED, NULL);
if (!hdr) {
@@ -593,6 +594,17 @@ static int handle_client_registration(vo
pjsip_msg_add_hdr(tdata->msg, (pjsip_hdr *)hdr);
}
+ /* Don't add the value if it's already there */
+ for (i = 0; i < hdr->count; ++i) {
+ if (pj_stricmp(&hdr->values[i], &PATH_NAME) == 0) {
+ return 1;
+ }
+ }
+
+ if (hdr->count >= PJSIP_GENERIC_ARRAY_MAX_COUNT) {
+ return 0;
+ }
+
/* add on to the existing Supported header */
pj_strassign(&hdr->values[hdr->count++], &PATH_NAME);
}
--- a/res/res_pjsip_path.c
+++ b/res/res_pjsip_path.c
@@ -122,6 +122,7 @@ static int path_get_string(pj_pool_t *po
static int add_supported(pjsip_tx_data *tdata)
{
pjsip_supported_hdr *hdr;
+ int i;
hdr = pjsip_msg_find_hdr(tdata->msg, PJSIP_H_SUPPORTED, NULL);
if (!hdr) {
@@ -134,6 +135,17 @@ static int add_supported(pjsip_tx_data *
pjsip_msg_add_hdr(tdata->msg, (pjsip_hdr *)hdr);
}
+ /* Don't add the value if it's already there */
+ for (i = 0; i < hdr->count; ++i) {
+ if (pj_stricmp(&hdr->values[i], &PATH_SUPPORTED_NAME) == 0) {
+ return 0;
+ }
+ }
+
+ if (hdr->count >= PJSIP_GENERIC_ARRAY_MAX_COUNT) {
+ return -1;
+ }
+
/* add on to the existing Supported header */
pj_strassign(&hdr->values[hdr->count++], &PATH_SUPPORTED_NAME);