Merge lp:~ari-tczew/ubuntu/saucy/asterisk/lp-1205644 into lp:ubuntu/saucy/asterisk

Proposed by Artur Rona
Status: Merged
Merge reported by: Artur Rona
Merged at revision: not available
Proposed branch: lp:~ari-tczew/ubuntu/saucy/asterisk/lp-1205644
Merge into: lp:ubuntu/saucy/asterisk
Diff against target: 1735 lines (+1684/-2)
8 files modified
debian/changelog (+49/-0)
debian/patches/AST-2012-014 (+162/-0)
debian/patches/AST-2012-015 (+1012/-0)
debian/patches/AST-2013-002 (+55/-0)
debian/patches/AST-2013-003 (+370/-0)
debian/patches/armhf-fixes (+1/-2)
debian/patches/bluetooth_bind (+30/-0)
debian/patches/series (+5/-0)
To merge this branch: bzr merge lp:~ari-tczew/ubuntu/saucy/asterisk/lp-1205644
Reviewer Review Type Date Requested Status
Daniel Holbach (community) Approve
Review via email: mp+177296@code.launchpad.net
To post a comment you must log in.
Revision history for this message
Daniel Holbach (dholbach) wrote :

Thanks. Uploaded.

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'debian/changelog'
2--- debian/changelog 2013-06-13 13:23:50 +0000
3+++ debian/changelog 2013-07-28 21:58:23 +0000
4@@ -1,3 +1,52 @@
5+asterisk (1:1.8.13.1~dfsg-3ubuntu1) saucy; urgency=low
6+
7+ * Merge from Debian unstable. (LP: #1205644) Remaining changes:
8+ - debian/asterisk.init:
9+ + chown /dev/dahdi
10+ - debian/control, debian/rules:
11+ + Enable Hardening Wrapper (PIE and BIND_NOW).
12+ + Build against libical 1.0.
13+ - debian/patches/armhf-fixes:
14+ + Fix FTBFS on armhf.
15+ * Fixed security issues:
16+ - CVE-2012-5976 (LP: #1097687)
17+ - CVE-2012-5977 (LP: #1097691)
18+ - CVE-2013-2686
19+ - CVE-2013-2264
20+
21+ -- Artur Rona <ari-tczew@tlen.pl> Sat, 27 Jul 2013 14:56:17 +0200
22+
23+asterisk (1:1.8.13.1~dfsg-3) unstable; urgency=high
24+
25+ * Rewrtote sip.conf parts of AST-2012-014: dropped patches
26+ fix-sip-tcp-no-FILE and fix-sip-tls-leak.
27+ * Reverting other changes rejected by the release team: README.Debian,
28+ powerpcspe and fix_xmpp_19532 dropped (#545272 and #701505 reopened).
29+
30+ -- Tzafrir Cohen <tzafrir@debian.org> Tue, 09 Apr 2013 13:23:07 +0300
31+
32+asterisk (1:1.8.13.1~dfsg-2) unstable; urgency=high
33+
34+ * Patches backported from Asterisk 1.8.19.1 (Closes: #697230):
35+ - Patch AST-2012-014 (CVE-2012-5976) - fixes Crashes due to large stack
36+ allocations when using TCP.
37+ The following two fixes were also pulled in order to easily apply it:
38+ - Patch fix-sip-tcp-no-FILE - Switch to reading with a recv loop
39+ - Patch fix-sip-tls-leak - Memory leak in the SIP TLS code
40+ - Patch AST-2012-015 (CVE-2012-5977) - Denial of Service Through
41+ Exploitation of Device State Caching
42+ * Patch powerpcspe: Fix OSARCH for powerpcspe (Closes: #701505).
43+ * README.Debian: document running the testsuite.
44+ * Patch fix_xmpp_19532: fix a crash of the XMPP code (Closes: #545272).
45+ * Patches backported from Asterisk 1.8.20.2 (Closes: #704114):
46+ - Patch AST-2013-002 (CVE-2013-2686): Prevent DoS in HTTP server with
47+ a large POST.
48+ - Patch AST-2013-003 (CVE-2013-2264): Prevent username disclosure in
49+ SIP channel driver.
50+ * Patch bluetooth_bind - fix breakage of chan_mobile (Closes: #614786).
51+
52+ -- Tzafrir Cohen <tzafrir@debian.org> Sat, 06 Apr 2013 14:15:41 +0300
53+
54 asterisk (1:1.8.13.1~dfsg-1ubuntu4) saucy; urgency=low
55
56 * Build against libical 1.0
57
58=== added file 'debian/patches/AST-2012-014'
59--- debian/patches/AST-2012-014 1970-01-01 00:00:00 +0000
60+++ debian/patches/AST-2012-014 2013-07-28 21:58:23 +0000
61@@ -0,0 +1,162 @@
62+From: Matthew Jordan <mjordan@digium.com>
63+Date: Wed, 2 Jan 2013 15:16:10 +0000
64+Subject: Resolve crashes due to large stack allocations when using TCP
65+Origin: http://svnview.digium.com/svn/asterisk?view=rev&rev=378269
66+CVE: CVE-2012-5976
67+Bug: https://issues.asterisk.org/jira/browse/ASTERISK-20658
68+
69+Asterisk had several places where messages received over various network
70+transports may be copied in a single stack allocation. In the case of TCP,
71+since multiple packets in a stream may be concatenated together, this can
72+lead to large allocations that overflow the stack.
73+
74+This patch modifies those portions of Asterisk using TCP to either
75+favor heap allocations or use an upper bound to ensure that the stack will not
76+overflow:
77+ * For SIP, the allocation now has an upper limit
78+ * For HTTP, the allocation is now a heap allocation instead of a stack
79+ allocation
80+ * For XMPP (in res_jabber), the allocation has been eliminated since it was
81+ unnecesary.
82+
83+Note that the HTTP portion of this issue was independently found by Brandon
84+Edwards of Exodus Intelligence.
85+
86+Reported by: wdoekes, Brandon Edwards
87+Tested by: mmichelson, wdoekes
88+See also: http://downloads.asterisk.org/pub/security/AST-2012-014.html
89+
90+---
91+ channels/chan_sip.c | 58 +++++++++++++++++++++++++++++++-------------
92+ channels/sip/include/sip.h | 1 +
93+ main/http.c | 20 ++++++++++++---
94+ res/res_jabber.c | 5 ++--
95+ 4 files changed, 60 insertions(+), 24 deletions(-)
96+
97+--- a/channels/chan_sip.c
98++++ b/channels/chan_sip.c
99+@@ -2504,6 +2504,7 @@ static void *_sip_tcp_helper_thread(stru
100+ int res, cl, timeout = -1, authenticated = 0, flags, after_poll = 0, need_poll = 1;
101+ time_t start;
102+ struct sip_request req = { 0, } , reqcpy = { 0, };
103++ size_t datalen;
104+ struct sip_threadinfo *me = NULL;
105+ char buf[1024] = "";
106+ struct pollfd fds[2] = { { 0 }, { 0 }, };
107+@@ -2640,8 +2641,9 @@ static void *_sip_tcp_helper_thread(stru
108+ }
109+ req.socket.fd = tcptls_session->fd;
110+
111++ datalen = ast_str_strlen(req.data);
112+ /* Read in headers one line at a time */
113+- while (ast_str_strlen(req.data) < 4 || strncmp(REQ_OFFSET_TO_STR(&req, data->used - 4), "\r\n\r\n", 4)) {
114++ while (datalen < 4 || strncmp(REQ_OFFSET_TO_STR(&req, data->used - 4), "\r\n\r\n", 4)) {
115+ if (!tcptls_session->client && !authenticated ) {
116+ if ((timeout = sip_check_authtimeout(start)) < 0) {
117+ goto cleanup;
118+@@ -2688,6 +2690,14 @@ static void *_sip_tcp_helper_thread(stru
119+ goto cleanup;
120+ }
121+ ast_str_append(&req.data, 0, "%s", buf);
122++ datalen = ast_str_strlen(req.data);
123++ if (datalen > SIP_MAX_PACKET_SIZE) {
124++ ast_log(LOG_WARNING, "Rejecting SIP %s packet from '%s' because way too large: %zu\n",
125++ tcptls_session->ssl ? "SSL" : "TCP",
126++ ast_sockaddr_stringify(&tcptls_session->remote_address),
127++ datalen);
128++ goto cleanup;
129++ }
130+ }
131+ copy_request(&reqcpy, &req);
132+ parse_request(&reqcpy);
133+--- a/channels/sip/include/sip.h
134++++ b/channels/sip/include/sip.h
135+@@ -96,6 +96,7 @@
136+
137+ #define SIP_MAX_HEADERS 64 /*!< Max amount of SIP headers to read */
138+ #define SIP_MAX_LINES 256 /*!< Max amount of lines in SIP attachment (like SDP) */
139++#define SIP_MAX_PACKET_SIZE 20480 /*!< Max SIP packet size */
140+ #define SIP_MIN_PACKET 4096 /*!< Initialize size of memory to allocate for packets */
141+ #define MAX_HISTORY_ENTRIES 50 /*!< Max entires in the history list for a sip_pvt */
142+
143+--- a/main/http.c
144++++ b/main/http.c
145+@@ -622,6 +622,7 @@ struct ast_variable *ast_http_get_post_v
146+ int content_length = 0;
147+ struct ast_variable *v, *post_vars=NULL, *prev = NULL;
148+ char *buf, *var, *val;
149++ int res;
150+
151+ for (v = headers; v; v = v->next) {
152+ if (!strcasecmp(v->name, "Content-Type")) {
153+@@ -634,21 +635,27 @@ struct ast_variable *ast_http_get_post_v
154+
155+ for (v = headers; v; v = v->next) {
156+ if (!strcasecmp(v->name, "Content-Length")) {
157+- content_length = atoi(v->value) + 1;
158++ content_length = atoi(v->value);
159+ break;
160+ }
161+ }
162+
163+- if (!content_length) {
164++ if (content_length <= 0) {
165+ return NULL;
166+ }
167+
168+- if (!(buf = alloca(content_length))) {
169++ buf = ast_malloc(content_length + 1);
170++ if (!buf) {
171+ return NULL;
172+ }
173+- if (!fgets(buf, content_length, ser->f)) {
174+- return NULL;
175++
176++ res = fread(buf, 1, content_length, ser->f);
177++ if (res < content_length) {
178++ /* Error, distinguishable by ferror() or feof(), but neither
179++ * is good. */
180++ goto done;
181+ }
182++ buf[content_length] = '\0';
183+
184+ while ((val = strsep(&buf, "&"))) {
185+ var = strsep(&val, "=");
186+@@ -667,6 +674,9 @@ struct ast_variable *ast_http_get_post_v
187+ prev = v;
188+ }
189+ }
190++
191++done:
192++ ast_free(buf);
193+ return post_vars;
194+ }
195+
196+--- a/res/res_jabber.c
197++++ b/res/res_jabber.c
198+@@ -768,7 +768,7 @@ static struct ast_custom_function jabber
199+ */
200+ static int acf_jabberreceive_read(struct ast_channel *chan, const char *name, char *data, char *buf, size_t buflen)
201+ {
202+- char *aux = NULL, *parse = NULL;
203++ char *parse = NULL;
204+ int timeout;
205+ int jidlen, resourcelen;
206+ struct timeval start;
207+@@ -885,7 +885,7 @@ static int acf_jabberreceive_read(struct
208+ continue;
209+ }
210+ found = 1;
211+- aux = ast_strdupa(tmp->message);
212++ ast_copy_string(buf, tmp->message, buflen);
213+ AST_LIST_REMOVE_CURRENT(list);
214+ aji_message_destroy(tmp);
215+ break;
216+@@ -910,7 +910,6 @@ static int acf_jabberreceive_read(struct
217+ ast_log(LOG_NOTICE, "Timed out : no message received from %s\n", args.jid);
218+ return -1;
219+ }
220+- ast_copy_string(buf, aux, buflen);
221+
222+ return 0;
223+ }
224
225=== added file 'debian/patches/AST-2012-015'
226--- debian/patches/AST-2012-015 1970-01-01 00:00:00 +0000
227+++ debian/patches/AST-2012-015 2013-07-28 21:58:23 +0000
228@@ -0,0 +1,1012 @@
229+From: Matthew Jordan <mjordan@digium.com>
230+Date: Wed, 2 Jan 2013 16:54:20 +0000
231+Subject: Prevent exhaustion of system resources through exploitation of event cache
232+CVE: CVE-2012-5977
233+Origin: http://svnview.digium.com/svn/asterisk?view=rev&rev=378303
234+Bug: https://issues.asterisk.org/jira/browse/ASTERISK-20175
235+
236+Asterisk maintains an internal cache for devices in the event subsystem. The
237+device state cache holds the state of each device known to Asterisk, such that
238+consumers of device state information can query for the last known state for
239+a particular device, even if it is not part of an active call. The concept of
240+a device in Asterisk can include entities that do not have a physical
241+representation. One way that this occurred was when anonymous calls are allowed
242+in Asterisk. A device was automatically created and stored in the cache for
243+each anonymous call that occurred; this was possible in the SIP and IAX2
244+channel drivers and through channel drivers that utilized the
245+res_jabber/res_xmpp resource modules (Gtalk, Jingle, and Motif). These devices
246+are never removed from the system, allowing anonymous calls to potentially
247+exhaust a system's resources.
248+
249+This patch changes the event cache subsystem and device state management to
250+no longer cache devices that are not associated with a physical entity.
251+
252+Reported by: Russell Bryant, Leif Madsen, Joshua Colp
253+Tested by: kmoore
254+See also: http://downloads.asterisk.org/pub/security/AST-2012-015.html
255+
256+---
257+ apps/app_confbridge.c | 4 +--
258+ apps/app_meetme.c | 16 +++++------
259+ channels/chan_agent.c | 12 ++++----
260+ channels/chan_dahdi.c | 7 +++--
261+ channels/chan_iax2.c | 31 +++++++++++---------
262+ channels/chan_local.c | 3 ++
263+ channels/chan_sip.c | 18 +++++++-----
264+ channels/chan_skinny.c | 16 +++++------
265+ funcs/func_devstate.c | 6 ++--
266+ include/asterisk/channel.h | 6 ++++
267+ include/asterisk/devicestate.h | 16 +++++++++--
268+ include/asterisk/event_defs.h | 8 +++++-
269+ main/channel.c | 5 ++--
270+ main/devicestate.c | 51 +++++++++++++++++++++------------
271+ main/event.c | 1 +
272+ main/features.c | 2 +-
273+ res/res_calendar.c | 8 +++---
274+ res/res_jabber.c | 61 ++++++++++++++++++++++++++++++----------
275+ 18 files changed, 177 insertions(+), 94 deletions(-)
276+
277+--- a/apps/app_confbridge.c
278++++ b/apps/app_confbridge.c
279+@@ -486,7 +486,7 @@ static struct conference_bridge *join_co
280+
281+ /* Set the device state for this conference */
282+ if (conference_bridge->users == 1) {
283+- ast_devstate_changed(AST_DEVICE_INUSE, "confbridge:%s", conference_bridge->name);
284++ ast_devstate_changed(AST_DEVICE_INUSE, AST_DEVSTATE_CACHABLE, "confbridge:%s", conference_bridge->name);
285+ }
286+
287+ /* If the caller is a marked user or is waiting for a marked user to enter pass 'em off, otherwise pass them off to do regular joining stuff */
288+@@ -568,7 +568,7 @@ static void leave_conference_bridge(str
289+ }
290+ } else {
291+ /* Set device state to "not in use" */
292+- ast_devstate_changed(AST_DEVICE_NOT_INUSE, "confbridge:%s", conference_bridge->name);
293++ ast_devstate_changed(AST_DEVICE_NOT_INUSE, AST_DEVSTATE_CACHABLE, "confbridge:%s", conference_bridge->name);
294+
295+ ao2_unlink(conference_bridges, conference_bridge);
296+ }
297+--- a/apps/app_meetme.c
298++++ b/apps/app_meetme.c
299+@@ -2489,7 +2489,7 @@ static int conf_run(struct ast_channel *
300+
301+ /* This device changed state now - if this is the first user */
302+ if (conf->users == 1)
303+- ast_devstate_changed(AST_DEVICE_INUSE, "meetme:%s", conf->confno);
304++ ast_devstate_changed(AST_DEVICE_INUSE, (conf->isdynamic ? AST_DEVSTATE_NOT_CACHABLE : AST_DEVSTATE_CACHABLE), "meetme:%s", conf->confno);
305+
306+ ast_mutex_unlock(&conf->playlock);
307+
308+@@ -3783,7 +3783,7 @@ bailoutandtrynormal:
309+
310+ /* Change any states */
311+ if (!conf->users) {
312+- ast_devstate_changed(AST_DEVICE_NOT_INUSE, "meetme:%s", conf->confno);
313++ ast_devstate_changed(AST_DEVICE_NOT_INUSE, (conf->isdynamic ? AST_DEVSTATE_NOT_CACHABLE : AST_DEVSTATE_CACHABLE), "meetme:%s", conf->confno);
314+ }
315+
316+ /* Return the number of seconds the user was in the conf */
317+@@ -5199,8 +5199,8 @@ static void sla_change_trunk_state(const
318+ || trunk_ref == exclude)
319+ continue;
320+ trunk_ref->state = state;
321+- ast_devstate_changed(sla_state_to_devstate(state),
322+- "SLA:%s_%s", station->name, trunk->name);
323++ ast_devstate_changed(sla_state_to_devstate(state), AST_DEVSTATE_CACHABLE,
324++ "SLA:%s_%s", station->name, trunk->name);
325+ break;
326+ }
327+ }
328+@@ -5698,8 +5698,8 @@ static void sla_handle_hold_event(struct
329+ {
330+ ast_atomic_fetchadd_int((int *) &event->trunk_ref->trunk->hold_stations, 1);
331+ event->trunk_ref->state = SLA_TRUNK_STATE_ONHOLD_BYME;
332+- ast_devstate_changed(AST_DEVICE_ONHOLD, "SLA:%s_%s",
333+- event->station->name, event->trunk_ref->trunk->name);
334++ ast_devstate_changed(AST_DEVICE_ONHOLD, AST_DEVSTATE_CACHABLE, "SLA:%s_%s",
335++ event->station->name, event->trunk_ref->trunk->name);
336+ sla_change_trunk_state(event->trunk_ref->trunk, SLA_TRUNK_STATE_ONHOLD,
337+ INACTIVE_TRUNK_REFS, event->trunk_ref);
338+
339+@@ -6208,8 +6208,8 @@ static int sla_station_exec(struct ast_c
340+ sla_change_trunk_state(trunk_ref->trunk, SLA_TRUNK_STATE_UP, ALL_TRUNK_REFS, NULL);
341+ else {
342+ trunk_ref->state = SLA_TRUNK_STATE_UP;
343+- ast_devstate_changed(AST_DEVICE_INUSE,
344+- "SLA:%s_%s", station->name, trunk_ref->trunk->name);
345++ ast_devstate_changed(AST_DEVICE_INUSE, AST_DEVSTATE_CACHABLE,
346++ "SLA:%s_%s", station->name, trunk_ref->trunk->name);
347+ }
348+ } else if (trunk_ref->state == SLA_TRUNK_STATE_RINGING) {
349+ struct sla_ringing_trunk *ringing_trunk;
350+--- a/channels/chan_agent.c
351++++ b/channels/chan_agent.c
352+@@ -611,7 +611,7 @@ static struct ast_frame *agent_read(stru
353+ if (p->chan) {
354+ p->chan->_bridge = NULL;
355+ p->chan = NULL;
356+- ast_devstate_changed(AST_DEVICE_UNAVAILABLE, "Agent/%s", p->agent);
357++ ast_devstate_changed(AST_DEVICE_UNAVAILABLE, AST_DEVSTATE_CACHABLE, "Agent/%s", p->agent);
358+ p->acknowledged = 0;
359+ }
360+ } else {
361+@@ -866,7 +866,7 @@ static int agent_call(struct ast_channel
362+ } else {
363+ /* Agent hung-up */
364+ p->chan = NULL;
365+- ast_devstate_changed(AST_DEVICE_UNAVAILABLE, "Agent/%s", p->agent);
366++ ast_devstate_changed(AST_DEVICE_UNAVAILABLE, AST_DEVSTATE_CACHABLE, "Agent/%s", p->agent);
367+ }
368+
369+ if (!res) {
370+@@ -985,7 +985,7 @@ static int agent_hangup(struct ast_chann
371+ if (!p->loginstart) {
372+ p->logincallerid[0] = '\0';
373+ } else {
374+- ast_devstate_changed(AST_DEVICE_NOT_INUSE, "Agent/%s", p->agent);
375++ ast_devstate_changed(AST_DEVICE_NOT_INUSE, AST_DEVSTATE_CACHABLE, "Agent/%s", p->agent);
376+ }
377+
378+ if (p->abouttograb) {
379+@@ -2128,7 +2128,7 @@ static int login_exec(struct ast_channel
380+ }
381+ ast_mutex_unlock(&p->lock);
382+ AST_LIST_UNLOCK(&agents);
383+- ast_devstate_changed(AST_DEVICE_NOT_INUSE, "Agent/%s", p->agent);
384++ ast_devstate_changed(AST_DEVICE_NOT_INUSE, AST_DEVSTATE_CACHABLE, "Agent/%s", p->agent);
385+ while (res >= 0) {
386+ ast_mutex_lock(&p->lock);
387+ if (p->deferlogoff && p->chan) {
388+@@ -2149,7 +2149,7 @@ static int login_exec(struct ast_channel
389+ if (ast_tvdiff_ms(ast_tvnow(), p->lastdisc) > 0) {
390+ ast_debug(1, "Wrapup time for %s expired!\n", p->agent);
391+ p->lastdisc = ast_tv(0, 0);
392+- ast_devstate_changed(AST_DEVICE_NOT_INUSE, "Agent/%s", p->agent);
393++ ast_devstate_changed(AST_DEVICE_NOT_INUSE, AST_DEVSTATE_CACHABLE, "Agent/%s", p->agent);
394+ if (p->ackcall) {
395+ check_beep(p, 0);
396+ } else {
397+@@ -2209,7 +2209,7 @@ static int login_exec(struct ast_channel
398+ ast_queue_log("NONE", chan->uniqueid, agent, "AGENTLOGOFF", "%s|%ld", chan->name, logintime);
399+ ast_verb(2, "Agent '%s' logged out\n", p->agent);
400+ /* If there is no owner, go ahead and kill it now */
401+- ast_devstate_changed(AST_DEVICE_UNAVAILABLE, "Agent/%s", p->agent);
402++ ast_devstate_changed(AST_DEVICE_UNAVAILABLE, AST_DEVSTATE_CACHABLE, "Agent/%s", p->agent);
403+ if (p->dead && !p->owner) {
404+ ast_mutex_destroy(&p->lock);
405+ ast_cond_destroy(&p->app_complete_cond);
406+--- a/channels/chan_dahdi.c
407++++ b/channels/chan_dahdi.c
408+@@ -3312,7 +3312,7 @@ static void dahdi_pri_update_span_devsta
409+ }
410+ if (pri->congestion_devstate != new_state) {
411+ pri->congestion_devstate = new_state;
412+- ast_devstate_changed(AST_DEVICE_UNKNOWN, "DAHDI/I%d/congestion", pri->span);
413++ ast_devstate_changed(AST_DEVICE_UNKNOWN, AST_DEVSTATE_NOT_CACHABLE, "DAHDI/I%d/congestion", pri->span);
414+ }
415+ #if defined(THRESHOLD_DEVSTATE_PLACEHOLDER)
416+ /* Update the span threshold device state and report any change. */
417+@@ -3328,7 +3328,7 @@ static void dahdi_pri_update_span_devsta
418+ }
419+ if (pri->threshold_devstate != new_state) {
420+ pri->threshold_devstate = new_state;
421+- ast_devstate_changed(AST_DEVICE_UNKNOWN, "DAHDI/I%d/threshold", pri->span);
422++ ast_devstate_changed(AST_DEVICE_UNKNOWN, AST_DEVSTATE_NOT_CACHABLE, "DAHDI/I%d/threshold", pri->span);
423+ }
424+ #endif /* defined(THRESHOLD_DEVSTATE_PLACEHOLDER) */
425+ }
426+@@ -9757,7 +9757,8 @@ static struct ast_channel *dahdi_new(str
427+ if (dashptr) {
428+ *dashptr = '\0';
429+ }
430+- ast_devstate_changed_literal(AST_DEVICE_UNKNOWN, device_name);
431++ tmp->flags |= AST_FLAG_DISABLE_DEVSTATE_CACHE;
432++ ast_devstate_changed_literal(AST_DEVICE_UNKNOWN, AST_DEVSTATE_NOT_CACHABLE, device_name);
433+
434+ for (v = i->vars ; v ; v = v->next)
435+ pbx_builtin_setvar_helper(tmp, v->name, v->value);
436+--- a/channels/chan_iax2.c
437++++ b/channels/chan_iax2.c
438+@@ -5728,7 +5728,7 @@ static int iax2_getpeertrunk(struct sock
439+ }
440+
441+ /*! \brief Create new call, interface with the PBX core */
442+-static struct ast_channel *ast_iax2_new(int callno, int state, format_t capability, const char *linkedid)
443++static struct ast_channel *ast_iax2_new(int callno, int state, format_t capability, const char *linkedid, unsigned int cachable)
444+ {
445+ struct ast_channel *tmp;
446+ struct chan_iax2_pvt *i;
447+@@ -5797,6 +5797,10 @@ static struct ast_channel *ast_iax2_new(
448+ i->owner = tmp;
449+ i->capability = capability;
450+
451++ if (!cachable) {
452++ tmp->flags |= AST_FLAG_DISABLE_DEVSTATE_CACHE;
453++ }
454++
455+ /* Set inherited variables */
456+ if (i->vars) {
457+ for (v = i->vars ; v ; v = v->next)
458+@@ -8085,7 +8089,7 @@ static int register_verify(int callno, s
459+ /* if challenge has been sent, but no challenge response if given, reject. */
460+ goto return_unref;
461+ }
462+- ast_devstate_changed(AST_DEVICE_UNKNOWN, "IAX2/%s", p->name); /* Activate notification */
463++ ast_devstate_changed(AST_DEVICE_UNKNOWN, AST_DEVSTATE_CACHABLE, "IAX2/%s", p->name); /* Activate notification */
464+
465+ /* either Authentication has taken place, or a REGAUTH must be sent before verifying registration */
466+ res = 0;
467+@@ -8639,7 +8643,7 @@ static void __expire_registry(const void
468+ if (!ast_test_flag64(peer, IAX_TEMPONLY))
469+ ast_db_del("IAX/Registry", peer->name);
470+ register_peer_exten(peer, 0);
471+- ast_devstate_changed(AST_DEVICE_UNAVAILABLE, "IAX2/%s", peer->name); /* Activate notification */
472++ ast_devstate_changed(AST_DEVICE_UNAVAILABLE, AST_DEVSTATE_CACHABLE, "IAX2/%s", peer->name); /* Activate notification */
473+ if (iax2_regfunk)
474+ iax2_regfunk(peer->name, 0);
475+
476+@@ -8693,7 +8697,7 @@ static void reg_source_db(struct iax2_pe
477+ }
478+ }
479+
480+- ast_devstate_changed(AST_DEVICE_UNKNOWN, "IAX2/%s", p->name); /* Activate notification */
481++ ast_devstate_changed(AST_DEVICE_UNKNOWN, AST_DEVSTATE_CACHABLE, "IAX2/%s", p->name); /* Activate notification */
482+
483+ p->expire = iax2_sched_add(sched, (p->expiry + 10) * 1000, expire_registry, peer_ref(p));
484+ if (p->expire == -1) {
485+@@ -8770,14 +8774,14 @@ static int update_registry(struct sockad
486+ ast_test_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED) ? "AUTHENTICATED" : "UNAUTHENTICATED", ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port));
487+ manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "ChannelType: IAX2\r\nPeer: IAX2/%s\r\nPeerStatus: Registered\r\n", p->name);
488+ register_peer_exten(p, 1);
489+- ast_devstate_changed(AST_DEVICE_UNKNOWN, "IAX2/%s", p->name); /* Activate notification */
490++ ast_devstate_changed(AST_DEVICE_UNKNOWN, AST_DEVSTATE_CACHABLE, "IAX2/%s", p->name); /* Activate notification */
491+ } else if (!ast_test_flag64(p, IAX_TEMPONLY)) {
492+ ast_verb(3, "Unregistered IAX2 '%s' (%s)\n", p->name,
493+ ast_test_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED) ? "AUTHENTICATED" : "UNAUTHENTICATED");
494+ manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "ChannelType: IAX2\r\nPeer: IAX2/%s\r\nPeerStatus: Unregistered\r\n", p->name);
495+ register_peer_exten(p, 0);
496+ ast_db_del("IAX/Registry", p->name);
497+- ast_devstate_changed(AST_DEVICE_UNAVAILABLE, "IAX2/%s", p->name); /* Activate notification */
498++ ast_devstate_changed(AST_DEVICE_UNAVAILABLE, AST_DEVSTATE_CACHABLE, "IAX2/%s", p->name); /* Activate notification */
499+ }
500+ /* Update the host */
501+ /* Verify that the host is really there */
502+@@ -10278,7 +10282,8 @@ static int socket_process(struct iax2_th
503+ (f.frametype == AST_FRAME_IAX)) {
504+ if (ast_test_flag64(iaxs[fr->callno], IAX_DELAYPBXSTART)) {
505+ ast_clear_flag64(iaxs[fr->callno], IAX_DELAYPBXSTART);
506+- if (!ast_iax2_new(fr->callno, AST_STATE_RING, iaxs[fr->callno]->chosenformat, NULL)) {
507++ if (!ast_iax2_new(fr->callno, AST_STATE_RING, iaxs[fr->callno]->chosenformat, NULL,
508++ ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_AUTHENTICATED))) {
509+ ast_variables_destroy(ies.vars);
510+ ast_mutex_unlock(&iaxsl[fr->callno]);
511+ return 1;
512+@@ -10911,13 +10916,13 @@ static int socket_process(struct iax2_th
513+ if (iaxs[fr->callno]->pingtime <= peer->maxms) {
514+ ast_log(LOG_NOTICE, "Peer '%s' is now REACHABLE! Time: %d\n", peer->name, iaxs[fr->callno]->pingtime);
515+ manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "ChannelType: IAX2\r\nPeer: IAX2/%s\r\nPeerStatus: Reachable\r\nTime: %d\r\n", peer->name, iaxs[fr->callno]->pingtime);
516+- ast_devstate_changed(AST_DEVICE_NOT_INUSE, "IAX2/%s", peer->name); /* Activate notification */
517++ ast_devstate_changed(AST_DEVICE_NOT_INUSE, AST_DEVSTATE_CACHABLE, "IAX2/%s", peer->name); /* Activate notification */
518+ }
519+ } else if ((peer->historicms > 0) && (peer->historicms <= peer->maxms)) {
520+ if (iaxs[fr->callno]->pingtime > peer->maxms) {
521+ ast_log(LOG_NOTICE, "Peer '%s' is now TOO LAGGED (%d ms)!\n", peer->name, iaxs[fr->callno]->pingtime);
522+ manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "ChannelType: IAX2\r\nPeer: IAX2/%s\r\nPeerStatus: Lagged\r\nTime: %d\r\n", peer->name, iaxs[fr->callno]->pingtime);
523+- ast_devstate_changed(AST_DEVICE_UNAVAILABLE, "IAX2/%s", peer->name); /* Activate notification */
524++ ast_devstate_changed(AST_DEVICE_UNAVAILABLE, AST_DEVSTATE_CACHABLE, "IAX2/%s", peer->name); /* Activate notification */
525+ }
526+ }
527+ peer->lastms = iaxs[fr->callno]->pingtime;
528+@@ -11159,7 +11164,7 @@ static int socket_process(struct iax2_th
529+ using_prefs);
530+
531+ ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED);
532+- if (!(c = ast_iax2_new(fr->callno, AST_STATE_RING, format, NULL)))
533++ if (!(c = ast_iax2_new(fr->callno, AST_STATE_RING, format, NULL, 1)))
534+ iax2_destroy(fr->callno);
535+ else if (ies.vars) {
536+ struct ast_datastore *variablestore;
537+@@ -11230,7 +11235,7 @@ immediatedial:
538+ ast_getformatname_multiple(tmp, sizeof(tmp), iaxs[fr->callno]->peerformat));
539+ ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED);
540+ send_command(iaxs[fr->callno], AST_FRAME_CONTROL, AST_CONTROL_PROGRESS, 0, NULL, 0, -1);
541+- if (!(c = ast_iax2_new(fr->callno, AST_STATE_RING, iaxs[fr->callno]->peerformat, NULL)))
542++ if (!(c = ast_iax2_new(fr->callno, AST_STATE_RING, iaxs[fr->callno]->peerformat, NULL, 1)))
543+ iax2_destroy(fr->callno);
544+ else if (ies.vars) {
545+ struct ast_datastore *variablestore;
546+@@ -11982,7 +11987,7 @@ static void __iax2_poke_noanswer(const v
547+ if (peer->lastms > -1) {
548+ ast_log(LOG_NOTICE, "Peer '%s' is now UNREACHABLE! Time: %d\n", peer->name, peer->lastms);
549+ manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "ChannelType: IAX2\r\nPeer: IAX2/%s\r\nPeerStatus: Unreachable\r\nTime: %d\r\n", peer->name, peer->lastms);
550+- ast_devstate_changed(AST_DEVICE_UNAVAILABLE, "IAX2/%s", peer->name); /* Activate notification */
551++ ast_devstate_changed(AST_DEVICE_UNAVAILABLE, AST_DEVSTATE_CACHABLE, "IAX2/%s", peer->name); /* Activate notification */
552+ }
553+ if ((callno = peer->callno) > 0) {
554+ ast_mutex_lock(&iaxsl[callno]);
555+@@ -12150,7 +12155,7 @@ static struct ast_channel *iax2_request(
556+ if (cai.found)
557+ ast_string_field_set(iaxs[callno], host, pds.peer);
558+
559+- c = ast_iax2_new(callno, AST_STATE_DOWN, cai.capability, requestor ? requestor->linkedid : NULL);
560++ c = ast_iax2_new(callno, AST_STATE_DOWN, cai.capability, requestor ? requestor->linkedid : NULL, cai.found);
561+
562+ ast_mutex_unlock(&iaxsl[callno]);
563+
564+--- a/channels/chan_local.c
565++++ b/channels/chan_local.c
566+@@ -1143,6 +1143,9 @@ static struct ast_channel *local_new(str
567+ tmp->tech_pvt = p;
568+ tmp2->tech_pvt = p;
569+
570++ tmp->flags |= AST_FLAG_DISABLE_DEVSTATE_CACHE;
571++ tmp2->flags |= AST_FLAG_DISABLE_DEVSTATE_CACHE;
572++
573+ p->owner = tmp;
574+ p->chan = tmp2;
575+ p->u_owner = ast_module_user_add(p->owner);
576+--- a/channels/chan_sip.c
577++++ b/channels/chan_sip.c
578+@@ -6312,7 +6312,7 @@ static int update_call_counter(struct si
579+ }
580+
581+ if (p) {
582+- ast_devstate_changed(AST_DEVICE_UNKNOWN, "SIP/%s", p->name);
583++ ast_devstate_changed(AST_DEVICE_UNKNOWN, AST_DEVSTATE_CACHABLE, "SIP/%s", p->name);
584+ unref_peer(p, "update_call_counter: unref_peer from call counter");
585+ }
586+ return 0;
587+@@ -7510,6 +7510,9 @@ static struct ast_channel *sip_new(struc
588+ if (i->rtp)
589+ ast_jb_configure(tmp, &global_jbconf);
590+
591++ if (!i->relatedpeer) {
592++ tmp->flags |= AST_FLAG_DISABLE_DEVSTATE_CACHE;
593++ }
594+ /* Set channel variables for this call from configuration */
595+ for (v = i->chanvars ; v ; v = v->next) {
596+ char valuebuf[1024];
597+@@ -14021,7 +14024,7 @@ static int expire_register(const void *d
598+
599+ manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "ChannelType: SIP\r\nPeer: SIP/%s\r\nPeerStatus: Unregistered\r\nCause: Expired\r\n", peer->name);
600+ register_peer_exten(peer, FALSE); /* Remove regexten */
601+- ast_devstate_changed(AST_DEVICE_UNKNOWN, "SIP/%s", peer->name);
602++ ast_devstate_changed(AST_DEVICE_UNKNOWN, AST_DEVSTATE_CACHABLE, "SIP/%s", peer->name);
603+
604+ /* Do we need to release this peer from memory?
605+ Only for realtime peers and autocreated peers
606+@@ -14803,8 +14806,9 @@ static void sip_peer_hold(struct sip_pvt
607+ ast_atomic_fetchadd_int(&p->relatedpeer->onHold, (hold ? +1 : -1));
608+
609+ /* Request device state update */
610+- ast_devstate_changed(AST_DEVICE_UNKNOWN, "SIP/%s", p->relatedpeer->name);
611+-
612++ ast_devstate_changed(AST_DEVICE_UNKNOWN, (p->owner->flags & AST_FLAG_DISABLE_DEVSTATE_CACHE ? AST_DEVSTATE_NOT_CACHABLE : AST_DEVSTATE_CACHABLE),
613++ "SIP/%s", p->relatedpeer->name);
614++
615+ return;
616+ }
617+
618+@@ -15208,7 +15212,7 @@ static enum check_auth_result register_v
619+ }
620+ }
621+ if (!res) {
622+- ast_devstate_changed(AST_DEVICE_UNKNOWN, "SIP/%s", peer->name);
623++ ast_devstate_changed(AST_DEVICE_UNKNOWN, AST_DEVSTATE_CACHABLE, "SIP/%s", peer->name);
624+ }
625+ if (res < 0) {
626+ switch (res) {
627+@@ -21122,7 +21126,7 @@ static void handle_response_peerpoke(str
628+
629+ ast_log(LOG_NOTICE, "Peer '%s' is now %s. (%dms / %dms)\n",
630+ peer->name, s, pingtime, peer->maxms);
631+- ast_devstate_changed(AST_DEVICE_UNKNOWN, "SIP/%s", peer->name);
632++ ast_devstate_changed(AST_DEVICE_UNKNOWN, AST_DEVSTATE_CACHABLE, "SIP/%s", peer->name);
633+ if (sip_cfg.peer_rtupdate) {
634+ ast_update_realtime(ast_check_realtime("sipregs") ? "sipregs" : "sippeers", "name", peer->name, "lastms", str_lastms, SENTINEL);
635+ }
636+@@ -26540,7 +26544,7 @@ static int sip_poke_noanswer(const void
637+ /* Don't send a devstate change if nothing changed. */
638+ if (peer->lastms > -1) {
639+ peer->lastms = -1;
640+- ast_devstate_changed(AST_DEVICE_UNKNOWN, "SIP/%s", peer->name);
641++ ast_devstate_changed(AST_DEVICE_UNKNOWN, AST_DEVSTATE_CACHABLE, "SIP/%s", peer->name);
642+ }
643+
644+ /* Try again quickly */
645+--- a/channels/chan_skinny.c
646++++ b/channels/chan_skinny.c
647+@@ -1925,7 +1925,7 @@ static int skinny_register(struct skinny
648+ register_exten(l);
649+ /* initialize MWI on line and device */
650+ mwi_event_cb(0, l);
651+- ast_devstate_changed(AST_DEVICE_NOT_INUSE, "Skinny/%s@%s", l->name, d->name);
652++ ast_devstate_changed(AST_DEVICE_NOT_INUSE, AST_DEVSTATE_CACHABLE, "Skinny/%s@%s", l->name, d->name);
653+ }
654+ --instance;
655+ }
656+@@ -1963,7 +1963,7 @@ static int skinny_unregister(struct skin
657+ l->instance = 0;
658+ manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "ChannelType: Skinny\r\nPeer: Skinny/%s@%s\r\nPeerStatus: Unregistered\r\n", l->name, d->name);
659+ unregister_exten(l);
660+- ast_devstate_changed(AST_DEVICE_UNAVAILABLE, "Skinny/%s@%s", l->name, d->name);
661++ ast_devstate_changed(AST_DEVICE_UNAVAILABLE, AST_DEVSTATE_CACHABLE, "Skinny/%s@%s", l->name, d->name);
662+ }
663+ }
664+ }
665+@@ -5321,7 +5321,7 @@ static int handle_stimulus_message(struc
666+ ast_verb(1, "RECEIVED UNKNOWN STIMULUS: %d(%d/%d)\n", event, instance, callreference);
667+ break;
668+ }
669+- ast_devstate_changed(AST_DEVICE_UNKNOWN, "Skinny/%s@%s", l->name, d->name);
670++ ast_devstate_changed(AST_DEVICE_UNKNOWN, AST_DEVSTATE_CACHABLE, "Skinny/%s@%s", l->name, d->name);
671+
672+ return 1;
673+ }
674+@@ -5372,7 +5372,7 @@ static int handle_offhook_message(struct
675+ transmit_ringer_mode(d, SKINNY_RING_OFF);
676+ l->hookstate = SKINNY_OFFHOOK;
677+
678+- ast_devstate_changed(AST_DEVICE_INUSE, "Skinny/%s@%s", l->name, d->name);
679++ ast_devstate_changed(AST_DEVICE_INUSE, AST_DEVSTATE_CACHABLE, "Skinny/%s@%s", l->name, d->name);
680+
681+ if (sub && sub->onhold) {
682+ return 1;
683+@@ -5448,7 +5448,7 @@ static int handle_onhook_message(struct
684+ return 0;
685+ }
686+
687+- ast_devstate_changed(AST_DEVICE_NOT_INUSE, "Skinny/%s@%s", l->name, d->name);
688++ ast_devstate_changed(AST_DEVICE_NOT_INUSE, AST_DEVSTATE_CACHABLE, "Skinny/%s@%s", l->name, d->name);
689+
690+ if (sub->onhold) {
691+ return 0;
692+@@ -5834,7 +5834,7 @@ static int handle_soft_key_event_message
693+ return 0;
694+ }
695+
696+- ast_devstate_changed(AST_DEVICE_INUSE, "Skinny/%s@%s", l->name, d->name);
697++ ast_devstate_changed(AST_DEVICE_INUSE, AST_DEVSTATE_CACHABLE, "Skinny/%s@%s", l->name, d->name);
698+
699+ switch(event) {
700+ case SOFTKEY_NONE:
701+@@ -6049,7 +6049,7 @@ static int handle_soft_key_event_message
702+ transmit_callstate(d, l->instance, sub->callid, l->hookstate);
703+ }
704+
705+- ast_devstate_changed(AST_DEVICE_NOT_INUSE, "Skinny/%s@%s", l->name, d->name);
706++ ast_devstate_changed(AST_DEVICE_NOT_INUSE, AST_DEVSTATE_CACHABLE, "Skinny/%s@%s", l->name, d->name);
707+ if (skinnydebug)
708+ ast_verb(1, "Skinny %s@%s went on hook\n", l->name, d->name);
709+ if (l->transfer && sub->xferor && sub->owner->_state >= AST_STATE_RING) {
710+@@ -6073,7 +6073,7 @@ static int handle_soft_key_event_message
711+ }
712+ }
713+ if ((l->hookstate == SKINNY_ONHOOK) && (AST_LIST_NEXT(sub, list) && !AST_LIST_NEXT(sub, list)->rtp)) {
714+- ast_devstate_changed(AST_DEVICE_NOT_INUSE, "Skinny/%s@%s", l->name, d->name);
715++ ast_devstate_changed(AST_DEVICE_NOT_INUSE, AST_DEVSTATE_CACHABLE, "Skinny/%s@%s", l->name, d->name);
716+ }
717+ }
718+ break;
719+--- a/funcs/func_devstate.c
720++++ b/funcs/func_devstate.c
721+@@ -132,7 +132,7 @@ static int devstate_write(struct ast_cha
722+
723+ ast_db_put(astdb_family, data, value);
724+
725+- ast_devstate_changed(state_val, "Custom:%s", data);
726++ ast_devstate_changed(state_val, AST_DEVSTATE_CACHABLE, "Custom:%s", data);
727+
728+ return 0;
729+ }
730+@@ -294,7 +294,7 @@ static char *handle_cli_devstate_change(
731+
732+ ast_db_put(astdb_family, dev, state);
733+
734+- ast_devstate_changed(state_val, "Custom:%s", dev);
735++ ast_devstate_changed(state_val, AST_DEVSTATE_CACHABLE, "Custom:%s", dev);
736+
737+ return CLI_SUCCESS;
738+ }
739+@@ -340,7 +340,7 @@ static int load_module(void)
740+ if (dev_name <= (const char *) 1)
741+ continue;
742+ ast_devstate_changed(ast_devstate_val(db_entry->data),
743+- "Custom:%s\n", dev_name);
744++ AST_DEVSTATE_CACHABLE, "Custom:%s\n", dev_name);
745+ }
746+ ast_db_freetree(db_tree);
747+ db_tree = NULL;
748+--- a/include/asterisk/channel.h
749++++ b/include/asterisk/channel.h
750+@@ -936,6 +936,12 @@ enum {
751+ * some non-traditional dialplans (like AGI) to continue to function.
752+ */
753+ AST_FLAG_DISABLE_WORKAROUNDS = (1 << 20),
754++ /*! Disable device state event caching. This allows allows channel
755++ * drivers to selectively prevent device state events from being cached
756++ * by certain channels such as anonymous calls which have no persistent
757++ * represenatation that can be tracked.
758++ */
759++ AST_FLAG_DISABLE_DEVSTATE_CACHE = (1 << 21),
760+ };
761+
762+ /*! \brief ast_bridge_config flags */
763+--- a/include/asterisk/devicestate.h
764++++ b/include/asterisk/devicestate.h
765+@@ -61,6 +61,14 @@ enum ast_device_state {
766+ AST_DEVICE_TOTAL, /*/ Total num of device states, used for testing */
767+ };
768+
769++/*! \brief Device State Cachability
770++ * \note This is used to define the cachability of a device state when set.
771++ */
772++enum ast_devstate_cache {
773++ AST_DEVSTATE_NOT_CACHABLE, /*!< This device state is not cachable */
774++ AST_DEVSTATE_CACHABLE, /*!< This device state is cachable */
775++};
776++
777+ /*! \brief Devicestate provider call back */
778+ typedef enum ast_device_state (*ast_devstate_prov_cb_type)(const char *data);
779+
780+@@ -129,6 +137,7 @@ enum ast_device_state ast_device_state(c
781+ * \brief Tells Asterisk the State for Device is changed
782+ *
783+ * \param state the new state of the device
784++ * \param cachable whether this device state is cachable
785+ * \param fmt device name like a dial string with format parameters
786+ *
787+ * The new state of the device will be sent off to any subscribers
788+@@ -138,13 +147,14 @@ enum ast_device_state ast_device_state(c
789+ * \retval 0 on success
790+ * \retval -1 on failure
791+ */
792+-int ast_devstate_changed(enum ast_device_state state, const char *fmt, ...)
793+- __attribute__((format(printf, 2, 3)));
794++int ast_devstate_changed(enum ast_device_state state, enum ast_devstate_cache cachable, const char *fmt, ...)
795++ __attribute__((format(printf, 3, 4)));
796+
797+ /*!
798+ * \brief Tells Asterisk the State for Device is changed
799+ *
800+ * \param state the new state of the device
801++ * \param cachable whether this device state is cachable
802+ * \param device device name like a dial string with format parameters
803+ *
804+ * The new state of the device will be sent off to any subscribers
805+@@ -154,7 +164,7 @@ int ast_devstate_changed(enum ast_device
806+ * \retval 0 on success
807+ * \retval -1 on failure
808+ */
809+-int ast_devstate_changed_literal(enum ast_device_state state, const char *device);
810++int ast_devstate_changed_literal(enum ast_device_state state, enum ast_devstate_cache cachable, const char *device);
811+
812+ /*!
813+ * \brief Tells Asterisk the State for Device is changed.
814+--- a/include/asterisk/event_defs.h
815++++ b/include/asterisk/event_defs.h
816+@@ -283,8 +283,14 @@ enum ast_event_ie_type {
817+ AST_EVENT_IE_CHALLENGE = 0x0032,
818+ AST_EVENT_IE_RESPONSE = 0x0033,
819+ AST_EVENT_IE_EXPECTED_RESPONSE = 0x0034,
820++ /*!
821++ * \brief Event non-cachability flag
822++ * Used by: All events
823++ * Payload type: UINT
824++ */
825++ AST_EVENT_IE_CACHABLE = 0x0035,
826+ /*! \brief Must be the last IE value +1 */
827+- AST_EVENT_IE_TOTAL = 0x0035,
828++ AST_EVENT_IE_TOTAL = 0x0036,
829+ };
830+
831+ /*!
832+--- a/main/channel.c
833++++ b/main/channel.c
834+@@ -285,6 +285,7 @@ static void channel_data_add_flags(struc
835+ ast_data_add_bool(tree, "BRIDGE_HANGUP_RUN", ast_test_flag(chan, AST_FLAG_BRIDGE_HANGUP_RUN));
836+ ast_data_add_bool(tree, "BRIDGE_HANGUP_DONT", ast_test_flag(chan, AST_FLAG_BRIDGE_HANGUP_DONT));
837+ ast_data_add_bool(tree, "DISABLE_WORKAROUNDS", ast_test_flag(chan, AST_FLAG_DISABLE_WORKAROUNDS));
838++ ast_data_add_bool(tree, "DISABLE_DEVSTATE_CACHE", ast_test_flag(chan, AST_FLAG_DISABLE_DEVSTATE_CACHE));
839+ }
840+
841+ #if defined(KEEP_TILL_CHANNEL_PARTY_NUMBER_INFO_NEEDED)
842+@@ -2477,7 +2478,7 @@ static void ast_channel_destructor(void
843+ * instance is dead, we don't know the state of all other possible
844+ * instances.
845+ */
846+- ast_devstate_changed_literal(AST_DEVICE_UNKNOWN, device_name);
847++ ast_devstate_changed_literal(AST_DEVICE_UNKNOWN, (chan->flags & AST_FLAG_DISABLE_DEVSTATE_CACHE ? AST_DEVSTATE_NOT_CACHABLE : AST_DEVSTATE_CACHABLE), device_name);
848+ }
849+ }
850+
851+@@ -6918,7 +6919,7 @@ int ast_setstate(struct ast_channel *cha
852+ /* We have to pass AST_DEVICE_UNKNOWN here because it is entirely possible that the channel driver
853+ * for this channel is using the callback method for device state. If we pass in an actual state here
854+ * we override what they are saying the state is and things go amuck. */
855+- ast_devstate_changed_literal(AST_DEVICE_UNKNOWN, name);
856++ ast_devstate_changed_literal(AST_DEVICE_UNKNOWN, (chan->flags & AST_FLAG_DISABLE_DEVSTATE_CACHE ? AST_DEVSTATE_NOT_CACHABLE : AST_DEVSTATE_CACHABLE), name);
857+
858+ /* setstate used to conditionally report Newchannel; this is no more */
859+ ast_manager_event(chan, EVENT_FLAG_CALL, "Newstate",
860+--- a/main/devicestate.c
861++++ b/main/devicestate.c
862+@@ -170,6 +170,7 @@ static AST_RWLIST_HEAD_STATIC(devstate_p
863+
864+ struct state_change {
865+ AST_LIST_ENTRY(state_change) list;
866++ enum ast_devstate_cache cachable;
867+ char device[1];
868+ };
869+
870+@@ -187,6 +188,7 @@ struct devstate_change {
871+ AST_LIST_ENTRY(devstate_change) entry;
872+ uint32_t state;
873+ struct ast_eid eid;
874++ enum ast_devstate_cache cachable;
875+ char device[1];
876+ };
877+
878+@@ -422,7 +424,7 @@ static int getproviderstate(const char *
879+ return res;
880+ }
881+
882+-static void devstate_event(const char *device, enum ast_device_state state)
883++static void devstate_event(const char *device, enum ast_device_state state, int cachable)
884+ {
885+ struct ast_event *event;
886+ enum ast_event_type event_type;
887+@@ -438,18 +440,23 @@ static void devstate_event(const char *d
888+ ast_debug(3, "device '%s' state '%d'\n", device, state);
889+
890+ if (!(event = ast_event_new(event_type,
891+- AST_EVENT_IE_DEVICE, AST_EVENT_IE_PLTYPE_STR, device,
892+- AST_EVENT_IE_STATE, AST_EVENT_IE_PLTYPE_UINT, state,
893+- AST_EVENT_IE_END))) {
894++ AST_EVENT_IE_DEVICE, AST_EVENT_IE_PLTYPE_STR, device,
895++ AST_EVENT_IE_STATE, AST_EVENT_IE_PLTYPE_UINT, state,
896++ AST_EVENT_IE_CACHABLE, AST_EVENT_IE_PLTYPE_UINT, cachable,
897++ AST_EVENT_IE_END))) {
898+ return;
899+ }
900+
901+- ast_event_queue_and_cache(event);
902++ if (cachable) {
903++ ast_event_queue_and_cache(event);
904++ } else {
905++ ast_event_queue(event);
906++ }
907+ }
908+
909+ /*! Called by the state change thread to find out what the state is, and then
910+ * to queue up the state change event */
911+-static void do_state_change(const char *device)
912++static void do_state_change(const char *device, int cachable)
913+ {
914+ enum ast_device_state state;
915+
916+@@ -457,10 +464,10 @@ static void do_state_change(const char *
917+
918+ ast_debug(3, "Changing state for %s - state %d (%s)\n", device, state, ast_devstate2str(state));
919+
920+- devstate_event(device, state);
921++ devstate_event(device, state, cachable);
922+ }
923+
924+-int ast_devstate_changed_literal(enum ast_device_state state, const char *device)
925++int ast_devstate_changed_literal(enum ast_device_state state, enum ast_devstate_cache cachable, const char *device)
926+ {
927+ struct state_change *change;
928+
929+@@ -481,14 +488,15 @@ int ast_devstate_changed_literal(enum as
930+ */
931+
932+ if (state != AST_DEVICE_UNKNOWN) {
933+- devstate_event(device, state);
934++ devstate_event(device, state, cachable);
935+ } else if (change_thread == AST_PTHREADT_NULL || !(change = ast_calloc(1, sizeof(*change) + strlen(device)))) {
936+ /* we could not allocate a change struct, or */
937+ /* there is no background thread, so process the change now */
938+- do_state_change(device);
939++ do_state_change(device, cachable);
940+ } else {
941+ /* queue the change */
942+ strcpy(change->device, device);
943++ change->cachable = cachable;
944+ AST_LIST_LOCK(&state_changes);
945+ AST_LIST_INSERT_TAIL(&state_changes, change, list);
946+ ast_cond_signal(&change_pending);
947+@@ -500,10 +508,10 @@ int ast_devstate_changed_literal(enum as
948+
949+ int ast_device_state_changed_literal(const char *dev)
950+ {
951+- return ast_devstate_changed_literal(AST_DEVICE_UNKNOWN, dev);
952++ return ast_devstate_changed_literal(AST_DEVICE_UNKNOWN, AST_DEVSTATE_CACHABLE, dev);
953+ }
954+
955+-int ast_devstate_changed(enum ast_device_state state, const char *fmt, ...)
956++int ast_devstate_changed(enum ast_device_state state, enum ast_devstate_cache cachable, const char *fmt, ...)
957+ {
958+ char buf[AST_MAX_EXTENSION];
959+ va_list ap;
960+@@ -512,7 +520,7 @@ int ast_devstate_changed(enum ast_device
961+ vsnprintf(buf, sizeof(buf), fmt, ap);
962+ va_end(ap);
963+
964+- return ast_devstate_changed_literal(state, buf);
965++ return ast_devstate_changed_literal(state, cachable, buf);
966+ }
967+
968+ int ast_device_state_changed(const char *fmt, ...)
969+@@ -524,7 +532,7 @@ int ast_device_state_changed(const char
970+ vsnprintf(buf, sizeof(buf), fmt, ap);
971+ va_end(ap);
972+
973+- return ast_devstate_changed_literal(AST_DEVICE_UNKNOWN, buf);
974++ return ast_devstate_changed_literal(AST_DEVICE_UNKNOWN, AST_DEVSTATE_CACHABLE, buf);
975+ }
976+
977+ /*! \brief Go through the dev state change queue and update changes in the dev state thread */
978+@@ -544,7 +552,7 @@ static void *do_devstate_changes(void *d
979+ /* Process each state change */
980+ while ((current = next)) {
981+ next = AST_LIST_NEXT(current, list);
982+- do_state_change(current->device);
983++ do_state_change(current->device, current->cachable);
984+ ast_free(current);
985+ }
986+ }
987+@@ -588,7 +596,7 @@ static void devstate_cache_cb(const stru
988+ collection->num_states++;
989+ }
990+
991+-static void process_collection(const char *device, struct change_collection *collection)
992++static void process_collection(const char *device, enum ast_devstate_cache cachable, struct change_collection *collection)
993+ {
994+ int i;
995+ struct ast_devstate_aggregate agg;
996+@@ -639,7 +647,11 @@ static void process_collection(const cha
997+ return;
998+ }
999+
1000+- ast_event_queue_and_cache(event);
1001++ if (cachable) {
1002++ ast_event_queue_and_cache(event);
1003++ } else {
1004++ ast_event_queue(event);
1005++ }
1006+ }
1007+
1008+ static void handle_devstate_change(struct devstate_change *sc)
1009+@@ -665,7 +677,7 @@ static void handle_devstate_change(struc
1010+ /* Populate the collection of device states from the cache */
1011+ ast_event_dump_cache(tmp_sub);
1012+
1013+- process_collection(sc->device, &collection);
1014++ process_collection(sc->device, sc->cachable, &collection);
1015+
1016+ ast_event_sub_destroy(tmp_sub);
1017+ }
1018+@@ -694,10 +706,12 @@ static void devstate_change_collector_cb
1019+ const char *device;
1020+ const struct ast_eid *eid;
1021+ uint32_t state;
1022++ enum ast_devstate_cache cachable = AST_DEVSTATE_CACHABLE;
1023+
1024+ device = ast_event_get_ie_str(event, AST_EVENT_IE_DEVICE);
1025+ eid = ast_event_get_ie_raw(event, AST_EVENT_IE_EID);
1026+ state = ast_event_get_ie_uint(event, AST_EVENT_IE_STATE);
1027++ cachable = ast_event_get_ie_uint(event, AST_EVENT_IE_CACHABLE);
1028+
1029+ if (ast_strlen_zero(device) || !eid) {
1030+ ast_log(LOG_ERROR, "Invalid device state change event received\n");
1031+@@ -710,6 +724,7 @@ static void devstate_change_collector_cb
1032+ strcpy(sc->device, device);
1033+ sc->eid = *eid;
1034+ sc->state = state;
1035++ sc->cachable = cachable;
1036+
1037+ ast_mutex_lock(&devstate_collector.lock);
1038+ AST_LIST_INSERT_TAIL(&devstate_collector.devstate_change_q, sc, entry);
1039+--- a/main/event.c
1040++++ b/main/event.c
1041+@@ -264,6 +264,7 @@ static const struct ie_map {
1042+ [AST_EVENT_IE_CHALLENGE] = { AST_EVENT_IE_PLTYPE_STR, "Challenge" },
1043+ [AST_EVENT_IE_RESPONSE] = { AST_EVENT_IE_PLTYPE_STR, "Response" },
1044+ [AST_EVENT_IE_EXPECTED_RESPONSE] = { AST_EVENT_IE_PLTYPE_STR, "ExpectedResponse" },
1045++ [AST_EVENT_IE_CACHABLE] = { AST_EVENT_IE_PLTYPE_UINT, "Cachable" },
1046+ };
1047+
1048+ const char *ast_event_get_type_name(const struct ast_event *event)
1049+--- a/main/features.c
1050++++ b/main/features.c
1051+@@ -1061,7 +1061,7 @@ static void notify_metermaids(const char
1052+ ast_debug(4, "Notification of state change to metermaids %s@%s\n to state '%s'",
1053+ exten, context, ast_devstate2str(state));
1054+
1055+- ast_devstate_changed(state, "park:%s@%s", exten, context);
1056++ ast_devstate_changed(state, AST_DEVSTATE_CACHABLE, "park:%s@%s", exten, context);
1057+ }
1058+
1059+ /*! \brief metermaids callback from devicestate.c */
1060+--- a/res/res_calendar.c
1061++++ b/res/res_calendar.c
1062+@@ -571,9 +571,9 @@ static struct ast_calendar_event *destro
1063+ * but haven't hit the end event yet, go ahead and set the devicestate to the current busy status */
1064+ if (event->bs_start_sched < 0 && event->bs_end_sched >= 0) {
1065+ if (!calendar_is_busy(event->owner)) {
1066+- ast_devstate_changed(AST_DEVICE_NOT_INUSE, "Calendar:%s", event->owner->name);
1067++ ast_devstate_changed(AST_DEVICE_NOT_INUSE, AST_DEVSTATE_CACHABLE, "Calendar:%s", event->owner->name);
1068+ } else {
1069+- ast_devstate_changed(AST_DEVICE_BUSY, "Calendar:%s", event->owner->name);
1070++ ast_devstate_changed(AST_DEVICE_BUSY, AST_DEVSTATE_CACHABLE, "Calendar:%s", event->owner->name);
1071+ }
1072+ }
1073+
1074+@@ -814,9 +814,9 @@ static int calendar_devstate_change(cons
1075+ /* We can have overlapping events, so ignore the event->busy_state and check busy state
1076+ * based on all events in the calendar */
1077+ if (!calendar_is_busy(event->owner)) {
1078+- ast_devstate_changed(AST_DEVICE_NOT_INUSE, "Calendar:%s", event->owner->name);
1079++ ast_devstate_changed(AST_DEVICE_NOT_INUSE, AST_DEVSTATE_CACHABLE, "Calendar:%s", event->owner->name);
1080+ } else {
1081+- ast_devstate_changed(AST_DEVICE_BUSY, "Calendar:%s", event->owner->name);
1082++ ast_devstate_changed(AST_DEVICE_BUSY, AST_DEVSTATE_CACHABLE, "Calendar:%s", event->owner->name);
1083+ }
1084+
1085+ event = ast_calendar_unref_event(event);
1086+--- a/res/res_jabber.c
1087++++ b/res/res_jabber.c
1088+@@ -350,7 +350,7 @@ static char *aji_cli_create_leafnode(str
1089+ static void aji_create_affiliations(struct aji_client *client, const char *node);
1090+ static iks* aji_pubsub_iq_create(struct aji_client *client, const char *type);
1091+ static void aji_publish_device_state(struct aji_client *client, const char * device,
1092+- const char *device_state);
1093++ const char *device_state, unsigned int cachable);
1094+ static int aji_handle_pubsub_error(void *data, ikspak *pak);
1095+ static int aji_handle_pubsub_event(void *data, ikspak *pak);
1096+ static void aji_pubsub_subscribe(struct aji_client *client, const char *node);
1097+@@ -364,7 +364,7 @@ static void aji_publish_mwi(struct aji_c
1098+ static void aji_devstate_cb(const struct ast_event *ast_event, void *data);
1099+ static void aji_mwi_cb(const struct ast_event *ast_event, void *data);
1100+ static iks* aji_build_publish_skeleton(struct aji_client *client, const char *node,
1101+- const char *event_type);
1102++ const char *event_type, unsigned int cachable);
1103+ /* No transports in this version */
1104+ /*
1105+ static int aji_create_transport(char *label, struct aji_client *client);
1106+@@ -3198,6 +3198,7 @@ static void aji_devstate_cb(const struct
1107+ {
1108+ const char *device;
1109+ const char *device_state;
1110++ unsigned int cachable;
1111+ struct aji_client *client;
1112+ if (ast_eid_cmp(&ast_eid_default, ast_event_get_ie_raw(ast_event, AST_EVENT_IE_EID)))
1113+ {
1114+@@ -3209,7 +3210,8 @@ static void aji_devstate_cb(const struct
1115+ client = ASTOBJ_REF((struct aji_client *) data);
1116+ device = ast_event_get_ie_str(ast_event, AST_EVENT_IE_DEVICE);
1117+ device_state = ast_devstate_str(ast_event_get_ie_uint(ast_event, AST_EVENT_IE_STATE));
1118+- aji_publish_device_state(client, device, device_state);
1119++ cachable = ast_event_get_ie_uint(ast_event, AST_EVENT_IE_CACHABLE);
1120++ aji_publish_device_state(client, device, device_state, cachable);
1121+ ASTOBJ_UNREF(client, ast_aji_client_destroy);
1122+ }
1123+
1124+@@ -3249,11 +3251,13 @@ static void aji_init_event_distribution(
1125+ */
1126+ static int aji_handle_pubsub_event(void *data, ikspak *pak)
1127+ {
1128+- char *item_id, *device_state, *context;
1129++ char *item_id, *device_state, *context, *cachable_str;
1130+ int oldmsgs, newmsgs;
1131+ iks *item, *item_content;
1132+ struct ast_eid pubsub_eid;
1133+ struct ast_event *event;
1134++ unsigned int cachable = AST_DEVSTATE_CACHABLE;
1135++
1136+ item = iks_find(iks_find(iks_find(pak->x, "event"), "items"), "item");
1137+ if (!item) {
1138+ ast_log(LOG_ERROR, "Could not parse incoming PubSub event\n");
1139+@@ -3268,11 +3272,14 @@ static int aji_handle_pubsub_event(void
1140+ }
1141+ if (!strcasecmp(iks_name(item_content), "state")) {
1142+ device_state = iks_find_cdata(item, "state");
1143++ if ((cachable_str = iks_find_cdata(item, "cachable"))) {
1144++ sscanf(cachable_str, "%30d", &cachable);
1145++ }
1146+ if (!(event = ast_event_new(AST_EVENT_DEVICE_STATE_CHANGE,
1147+- AST_EVENT_IE_DEVICE, AST_EVENT_IE_PLTYPE_STR, item_id, AST_EVENT_IE_STATE,
1148+- AST_EVENT_IE_PLTYPE_UINT, ast_devstate_val(device_state), AST_EVENT_IE_EID,
1149+- AST_EVENT_IE_PLTYPE_RAW, &pubsub_eid, sizeof(pubsub_eid),
1150+- AST_EVENT_IE_END))) {
1151++ AST_EVENT_IE_DEVICE, AST_EVENT_IE_PLTYPE_STR, item_id, AST_EVENT_IE_STATE,
1152++ AST_EVENT_IE_PLTYPE_UINT, ast_devstate_val(device_state), AST_EVENT_IE_EID,
1153++ AST_EVENT_IE_PLTYPE_RAW, &pubsub_eid, sizeof(pubsub_eid),
1154++ AST_EVENT_IE_END))) {
1155+ return IKS_FILTER_EAT;
1156+ }
1157+ } else if (!strcasecmp(iks_name(item_content), "mailbox")) {
1158+@@ -3292,7 +3299,13 @@ static int aji_handle_pubsub_event(void
1159+ iks_name(item_content));
1160+ return IKS_FILTER_EAT;
1161+ }
1162+- ast_event_queue_and_cache(event);
1163++
1164++ if (cachable == AST_DEVSTATE_CACHABLE) {
1165++ ast_event_queue_and_cache(event);
1166++ } else {
1167++ ast_event_queue(event);
1168++ }
1169++
1170+ return IKS_FILTER_EAT;
1171+ }
1172+
1173+@@ -3367,7 +3380,7 @@ static void aji_pubsub_subscribe(struct
1174+ * \return iks *
1175+ */
1176+ static iks* aji_build_publish_skeleton(struct aji_client *client, const char *node,
1177+- const char *event_type)
1178++ const char *event_type, unsigned int cachable)
1179+ {
1180+ iks *request = aji_pubsub_iq_create(client, "set");
1181+ iks *pubsub, *publish, *item;
1182+@@ -3381,8 +3394,24 @@ static iks* aji_build_publish_skeleton(s
1183+ }
1184+ item = iks_insert(publish, "item");
1185+ iks_insert_attrib(item, "id", node);
1186+- return item;
1187+
1188++ if (cachable == AST_DEVSTATE_NOT_CACHABLE) {
1189++ iks *options, *x, *field_form_type, *field_persist;
1190++
1191++ options = iks_insert(pubsub, "publish-options");
1192++ x = iks_insert(options, "x");
1193++ iks_insert_attrib(x, "xmlns", "jabber:x:data");
1194++ iks_insert_attrib(x, "type", "submit");
1195++ field_form_type = iks_insert(x, "field");
1196++ iks_insert_attrib(field_form_type, "var", "FORM_TYPE");
1197++ iks_insert_attrib(field_form_type, "type", "hidden");
1198++ iks_insert_cdata(iks_insert(field_form_type, "value"), "http://jabber.org/protocol/pubsub#publish-options", 0);
1199++ field_persist = iks_insert(x, "field");
1200++ iks_insert_attrib(field_persist, "var", "pubsub#persist_items");
1201++ iks_insert_cdata(iks_insert(field_persist, "value"), "0", 1);
1202++ }
1203++
1204++ return item;
1205+ }
1206+
1207+ /*!
1208+@@ -3393,11 +3422,11 @@ static iks* aji_build_publish_skeleton(s
1209+ * \return void
1210+ */
1211+ static void aji_publish_device_state(struct aji_client *client, const char *device,
1212+- const char *device_state)
1213++ const char *device_state, unsigned int cachable)
1214+ {
1215+- iks *request = aji_build_publish_skeleton(client, device, "device_state");
1216++ iks *request = aji_build_publish_skeleton(client, device, "device_state", cachable);
1217+ iks *state;
1218+- char eid_str[20];
1219++ char eid_str[20], cachable_str[2];
1220+ if (ast_test_flag(&pubsubflags, AJI_PUBSUB_AUTOCREATE)) {
1221+ if (ast_test_flag(&pubsubflags, AJI_XEP0248)) {
1222+ aji_create_pubsub_node(client, "leaf", device, "device_state");
1223+@@ -3409,6 +3438,8 @@ static void aji_publish_device_state(str
1224+ state = iks_insert(request, "state");
1225+ iks_insert_attrib(state, "xmlns", "http://asterisk.org");
1226+ iks_insert_attrib(state, "eid", eid_str);
1227++ snprintf(cachable_str, sizeof(cachable_str), "%u", cachable);
1228++ iks_insert_attrib(state, "cachable", cachable_str);
1229+ iks_insert_cdata(state, device_state, strlen(device_state));
1230+ ast_aji_send(client, iks_root(request));
1231+ iks_delete(request);
1232+@@ -3428,7 +3459,7 @@ static void aji_publish_mwi(struct aji_c
1233+ char eid_str[20];
1234+ iks *mailbox_node, *request;
1235+ snprintf(full_mailbox, sizeof(full_mailbox), "%s@%s", mailbox, context);
1236+- request = aji_build_publish_skeleton(client, full_mailbox, "message_waiting");
1237++ request = aji_build_publish_skeleton(client, full_mailbox, "message_waiting", 1);
1238+ ast_eid_to_str(eid_str, sizeof(eid_str), &ast_eid_default);
1239+ mailbox_node = iks_insert(request, "mailbox");
1240+ iks_insert_attrib(mailbox_node, "xmlns", "http://asterisk.org");
1241
1242=== added file 'debian/patches/AST-2013-002'
1243--- debian/patches/AST-2013-002 1970-01-01 00:00:00 +0000
1244+++ debian/patches/AST-2013-002 2013-07-28 21:58:23 +0000
1245@@ -0,0 +1,55 @@
1246+From: Matthew Jordan <mjordan@digium.com>
1247+Date: Wed, 27 Mar 2013 14:35:11 +0000
1248+Subject: AST-2013-002: Prevent denial of service in HTTP server
1249+Origin: http://svnview.digium.com/svn/asterisk?view=rev&rev=383976
1250+Bug: https://issues.asterisk.org/jira/browse/ASTERISK-20967
1251+CVE: CVE-2013-2686
1252+
1253+AST-2012-014, fixed in January of this year, contained a fix for Asterisk's
1254+HTTP server for a remotely-triggered crash. While the fix put in place fixed
1255+the possibility for the crash to be triggered, a denial of service vector still
1256+exists with that solution if an attacker sends one or more HTTP POST requests
1257+with very large Content-Length values. This patch resolves this by capping
1258+the Content-Length at 1024 bytes. Any attempt to send an HTTP POST with
1259+Content-Length greater than this cap will not result in any memory allocation.
1260+The POST will be responded to with an HTTP 413 "Request Entity Too Large"
1261+response.
1262+
1263+This issue was reported by Christoph Hebeisen of TELUS Security Labs
1264+
1265+See Also: http://downloads.asterisk.org/pub/security/AST-2013-002.html
1266+
1267+---
1268+ main/http.c | 9 +++++++++
1269+ 1 file changed, 9 insertions(+)
1270+
1271+diff --git a/main/http.c b/main/http.c
1272+index 1b5f2b6..4b73acb 100644
1273+--- a/main/http.c
1274++++ b/main/http.c
1275+@@ -612,6 +612,8 @@ static void http_decode(char *s)
1276+ ast_uri_decode(s);
1277+ }
1278+
1279++#define MAX_POST_CONTENT 1025
1280++
1281+ /*
1282+ * get post variables from client Request Entity-Body, if content type is
1283+ * application/x-www-form-urlencoded
1284+@@ -644,6 +646,13 @@ struct ast_variable *ast_http_get_post_vars(
1285+ return NULL;
1286+ }
1287+
1288++ if (content_length > MAX_POST_CONTENT - 1) {
1289++ ast_log(LOG_WARNING, "Excessively long HTTP content. %d is greater than our max of %d\n",
1290++ content_length, MAX_POST_CONTENT);
1291++ ast_http_send(ser, AST_HTTP_POST, 413, "Request Entity Too Large", NULL, NULL, 0, 0);
1292++ return NULL;
1293++ }
1294++
1295+ buf = ast_malloc(content_length + 1);
1296+ if (!buf) {
1297+ return NULL;
1298+--
1299+1.7.10.4
1300+
1301
1302=== added file 'debian/patches/AST-2013-003'
1303--- debian/patches/AST-2013-003 1970-01-01 00:00:00 +0000
1304+++ debian/patches/AST-2013-003 2013-07-28 21:58:23 +0000
1305@@ -0,0 +1,370 @@
1306+From: Matthew Jordan <mjordan@digium.com>
1307+Date: Wed, 27 Mar 2013 14:53:13 +0000
1308+Subject: AST-2013-003: Prevent username disclosure in SIP channel driver
1309+Bug: https://issues.asterisk.org/jira/browse/ASTERISK-21013
1310+Origin: http://svnview.digium.com/svn/asterisk?view=rev&rev=383981
1311+CVE: CVE-2013-2264
1312+
1313+When authenticating a SIP request with alwaysauthreject enabled, allowguest
1314+disabled, and autocreatepeer disabled, Asterisk discloses whether a user
1315+exists for INVITE, SUBSCRIBE, and REGISTER transactions in multiple ways. The
1316+information is disclosed when:
1317+ * A "407 Proxy Authentication Required" response is sent instead of a
1318+ "401 Unauthorized" response
1319+ * The presence or absence of additional tags occurs at the end of "403
1320+ Forbidden" (such as "(Bad Auth)")
1321+ * A "401 Unauthorized" response is sent instead of "403 Forbidden" response
1322+ after a retransmission
1323+ * Retransmission are sent when a matching peer did not exist, but not when a
1324+ matching peer did exist.
1325+
1326+This patch resolves these various vectors by ensuring that the responses sent
1327+in all scenarios is the same, regardless of the presence of a matching peer.
1328+
1329+This issue was reported by Walter Doekes, OSSO B.V. A substantial portion of
1330+the testing and the solution to this problem was done by Walter as well - a
1331+huge thanks to his tireless efforts in finding all the ways in which this
1332+setting didn't work, providing automated tests, and working with Kinsey on
1333+getting this fixed.
1334+
1335+Patch slightly adapted due to irrelevant changes in r367362.
1336+
1337+See Also: http://downloads.asterisk.org/pub/security/AST-2013-003.html
1338+
1339+---
1340+ channels/chan_sip.c | 128 ++++++++++++++++++++++++++++----------------
1341+ channels/sip/include/sip.h | 1 -
1342+ 2 files changed, 83 insertions(+), 46 deletions(-)
1343+
1344+--- a/channels/chan_sip.c
1345++++ b/channels/chan_sip.c
1346+@@ -1110,6 +1110,11 @@ static struct ao2_container *threadt;
1347+ static struct ao2_container *peers;
1348+ static struct ao2_container *peers_by_ip;
1349+
1350++/*! \brief A bogus peer, to be used when authentication should fail */
1351++static struct sip_peer *bogus_peer;
1352++/*! \brief We can recognise the bogus peer by this invalid MD5 hash */
1353++#define BOGUS_PEER_MD5SECRET "intentionally_invalid_md5_string"
1354++
1355+ /*! \brief The register list: Other SIP proxies we register with and receive calls from */
1356+ static struct ast_register_list {
1357+ ASTOBJ_CONTAINER_COMPONENTS(struct sip_registry);
1358+@@ -1250,7 +1255,7 @@ static int transmit_response_with_unsupp
1359+ static int transmit_response_with_auth(struct sip_pvt *p, const char *msg, const struct sip_request *req, const char *rand, enum xmittype reliable, const char *header, int stale);
1360+ static int transmit_provisional_response(struct sip_pvt *p, const char *msg, const struct sip_request *req, int with_sdp);
1361+ static int transmit_response_with_allow(struct sip_pvt *p, const char *msg, const struct sip_request *req, enum xmittype reliable);
1362+-static void transmit_fake_auth_response(struct sip_pvt *p, int sipmethod, struct sip_request *req, enum xmittype reliable);
1363++static void transmit_fake_auth_response(struct sip_pvt *p, struct sip_request *req, enum xmittype reliable);
1364+ static int transmit_request(struct sip_pvt *p, int sipmethod, uint32_t seqno, enum xmittype reliable, int newbranch);
1365+ static int transmit_request_with_auth(struct sip_pvt *p, int sipmethod, uint32_t seqno, enum xmittype reliable, int newbranch);
1366+ static int transmit_publish(struct sip_epa_entry *epa_entry, enum sip_publish_type publish_type, const char * const explicit_uri);
1367+@@ -14621,6 +14626,7 @@ static enum check_auth_result check_auth
1368+ char a1_hash[256];
1369+ char resp_hash[256]="";
1370+ char *c;
1371++ int is_bogus_peer = 0;
1372+ int wrongnonce = FALSE;
1373+ int good_response;
1374+ const char *usednonce = p->randdata;
1375+@@ -14715,8 +14721,14 @@ static enum check_auth_result check_auth
1376+ }
1377+ }
1378+
1379++ /* We cannot rely on the bogus_peer having a bad md5 value. Someone could
1380++ * use it to construct valid auth. */
1381++ if (md5secret && strcmp(md5secret, BOGUS_PEER_MD5SECRET) == 0) {
1382++ is_bogus_peer = 1;
1383++ }
1384++
1385+ /* Verify that digest username matches the username we auth as */
1386+- if (strcmp(username, keys[K_USER].s)) {
1387++ if (strcmp(username, keys[K_USER].s) && !is_bogus_peer) {
1388+ ast_log(LOG_WARNING, "username mismatch, have <%s>, digest has <%s>\n",
1389+ username, keys[K_USER].s);
1390+ /* Oops, we're trying something here */
1391+@@ -14755,7 +14767,8 @@ static enum check_auth_result check_auth
1392+ }
1393+
1394+ good_response = keys[K_RESP].s &&
1395+- !strncasecmp(keys[K_RESP].s, resp_hash, strlen(resp_hash));
1396++ !strncasecmp(keys[K_RESP].s, resp_hash, strlen(resp_hash)) &&
1397++ !is_bogus_peer; /* lastly, check that the peer isn't the fake peer */
1398+ if (wrongnonce) {
1399+ if (good_response) {
1400+ if (sipdebug)
1401+@@ -14899,7 +14912,7 @@ static int cb_extensionstate(char *conte
1402+ /*! \brief Send a fake 401 Unauthorized response when the administrator
1403+ wants to hide the names of local devices from fishers
1404+ */
1405+-static void transmit_fake_auth_response(struct sip_pvt *p, int sipmethod, struct sip_request *req, enum xmittype reliable)
1406++static void transmit_fake_auth_response(struct sip_pvt *p, struct sip_request *req, enum xmittype reliable)
1407+ {
1408+ /* We have to emulate EXACTLY what we'd get with a good peer
1409+ * and a bad password, or else we leak information. */
1410+@@ -14938,13 +14951,13 @@ static void transmit_fake_auth_response(
1411+ }
1412+
1413+ if (!(buf = ast_str_thread_get(&check_auth_buf, CHECK_AUTH_BUF_INITLEN))) {
1414+- transmit_response(p, "403 Forbidden (Bad auth)", &p->initreq);
1415++ __transmit_response(p, "403 Forbidden", &p->initreq, reliable);
1416+ return;
1417+ }
1418+
1419+ /* Make a copy of the response and parse it */
1420+ if (ast_str_set(&buf, 0, "%s", authtoken) == AST_DYNSTR_BUILD_FAILED) {
1421+- transmit_response(p, "403 Forbidden (Bad auth)", &p->initreq);
1422++ __transmit_response(p, "403 Forbidden", &p->initreq, reliable);
1423+ return;
1424+ }
1425+
1426+@@ -14982,7 +14995,7 @@ static void transmit_fake_auth_response(
1427+ /* Schedule auto destroy in 32 seconds */
1428+ sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
1429+ } else {
1430+- transmit_response(p, "403 Forbidden (Bad auth)", &p->initreq);
1431++ __transmit_response(p, "403 Forbidden", &p->initreq, reliable);
1432+ }
1433+ }
1434+
1435+@@ -15077,7 +15090,7 @@ static enum check_auth_result register_v
1436+ if (!AST_LIST_EMPTY(&domain_list)) {
1437+ if (!check_sip_domain(domain, NULL, 0)) {
1438+ if (sip_cfg.alwaysauthreject) {
1439+- transmit_fake_auth_response(p, SIP_REGISTER, &p->initreq, XMIT_UNRELIABLE);
1440++ transmit_fake_auth_response(p, &p->initreq, XMIT_UNRELIABLE);
1441+ } else {
1442+ transmit_response(p, "404 Not found (unknown domain)", &p->initreq);
1443+ }
1444+@@ -15104,6 +15117,13 @@ static enum check_auth_result register_v
1445+ }
1446+ peer = find_peer(name, NULL, TRUE, FINDPEERS, FALSE, 0);
1447+
1448++ /* If we don't want username disclosure, use the bogus_peer when a user
1449++ * is not found. */
1450++ if (!peer && sip_cfg.alwaysauthreject && !sip_cfg.autocreatepeer) {
1451++ peer = bogus_peer;
1452++ ref_peer(peer, "register_verify: ref the bogus_peer");
1453++ }
1454++
1455+ if (!(peer && ast_apply_ha(peer->ha, addr))) {
1456+ /* Peer fails ACL check */
1457+ if (peer) {
1458+@@ -15183,7 +15203,7 @@ static enum check_auth_result register_v
1459+ switch (parse_register_contact(p, peer, req)) {
1460+ case PARSE_REGISTER_DENIED:
1461+ ast_log(LOG_WARNING, "Registration denied because of contact ACL\n");
1462+- transmit_response_with_date(p, "403 Forbidden (ACL)", req);
1463++ transmit_response_with_date(p, "403 Forbidden", req);
1464+ peer->lastmsgssent = -1;
1465+ res = 0;
1466+ break;
1467+@@ -15218,7 +15238,7 @@ static enum check_auth_result register_v
1468+ switch (res) {
1469+ case AUTH_SECRET_FAILED:
1470+ /* Wrong password in authentication. Go away, don't try again until you fixed it */
1471+- transmit_response(p, "403 Forbidden (Bad auth)", &p->initreq);
1472++ transmit_response(p, "403 Forbidden", &p->initreq);
1473+ if (global_authfailureevents) {
1474+ const char *peer_addr = ast_strdupa(ast_sockaddr_stringify_addr(addr));
1475+ const char *peer_port = ast_strdupa(ast_sockaddr_stringify_port(addr));
1476+@@ -15241,7 +15261,7 @@ static enum check_auth_result register_v
1477+ case AUTH_PEER_NOT_DYNAMIC:
1478+ case AUTH_ACL_FAILED:
1479+ if (sip_cfg.alwaysauthreject) {
1480+- transmit_fake_auth_response(p, SIP_REGISTER, &p->initreq, XMIT_UNRELIABLE);
1481++ transmit_fake_auth_response(p, &p->initreq, XMIT_UNRELIABLE);
1482+ if (global_authfailureevents) {
1483+ const char *peer_addr = ast_strdupa(ast_sockaddr_stringify_addr(addr));
1484+ const char *peer_port = ast_strdupa(ast_sockaddr_stringify_port(addr));
1485+@@ -16242,7 +16262,19 @@ static enum check_auth_result check_peer
1486+ ast_verbose("No matching peer for '%s' from '%s'\n",
1487+ of, ast_sockaddr_stringify(&p->recv));
1488+ }
1489+- return AUTH_DONT_KNOW;
1490++
1491++ /* If you don't mind, we can return 404s for devices that do
1492++ * not exist: username disclosure. If we allow guests, there
1493++ * is no way around that. */
1494++ if (sip_cfg.allowguest || !sip_cfg.alwaysauthreject) {
1495++ return AUTH_DONT_KNOW;
1496++ }
1497++
1498++ /* If you do mind, we use a peer that will never authenticate.
1499++ * This ensures that we follow the same code path as regular
1500++ * auth: less chance for username disclosure. */
1501++ peer = bogus_peer;
1502++ ref_peer(peer, "ref_peer: check_peer_ok: must ref bogus_peer so unreffing it does not fail");
1503+ }
1504+
1505+ if (!ast_apply_ha(peer->ha, addr)) {
1506+@@ -16250,9 +16282,10 @@ static enum check_auth_result check_peer
1507+ unref_peer(peer, "unref_peer: check_peer_ok: from find_peer call, early return of AUTH_ACL_FAILED");
1508+ return AUTH_ACL_FAILED;
1509+ }
1510+- if (debug)
1511++ if (debug && peer != bogus_peer) {
1512+ ast_verbose("Found peer '%s' for '%s' from %s\n",
1513+ peer->name, of, ast_sockaddr_stringify(&p->recv));
1514++ }
1515+
1516+ /* XXX what about p->prefs = peer->prefs; ? */
1517+ /* Set Frame packetization */
1518+@@ -16517,8 +16550,6 @@ static enum check_auth_result check_user
1519+ } else {
1520+ res = AUTH_RTP_FAILED;
1521+ }
1522+- } else if (sip_cfg.alwaysauthreject) {
1523+- res = AUTH_FAKE_AUTH; /* reject with fake authorization request */
1524+ } else {
1525+ res = AUTH_SECRET_FAILED; /* we don't want any guests, authentication will fail */
1526+ }
1527+@@ -22225,13 +22256,8 @@ static int handle_request_options(struct
1528+ return 0;
1529+ }
1530+ if (res < 0) { /* Something failed in authentication */
1531+- if (res == AUTH_FAKE_AUTH) {
1532+- ast_log(LOG_NOTICE, "Sending fake auth rejection for device %s\n", get_header(req, "From"));
1533+- transmit_fake_auth_response(p, SIP_OPTIONS, req, XMIT_UNRELIABLE);
1534+- } else {
1535+- ast_log(LOG_NOTICE, "Failed to authenticate device %s\n", get_header(req, "From"));
1536+- transmit_response(p, "403 Forbidden", req);
1537+- }
1538++ ast_log(LOG_NOTICE, "Failed to authenticate device %s\n", get_header(req, "From"));
1539++ transmit_response(p, "403 Forbidden", req);
1540+ sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
1541+ return 0;
1542+ }
1543+@@ -22896,13 +22922,8 @@ static int handle_request_invite(struct
1544+ goto request_invite_cleanup;
1545+ }
1546+ if (res < 0) { /* Something failed in authentication */
1547+- if (res == AUTH_FAKE_AUTH) {
1548+- ast_log(LOG_NOTICE, "Sending fake auth rejection for device %s\n", get_header(req, "From"));
1549+- transmit_fake_auth_response(p, SIP_INVITE, req, XMIT_RELIABLE);
1550+- } else {
1551+- ast_log(LOG_NOTICE, "Failed to authenticate device %s\n", get_header(req, "From"));
1552+- transmit_response_reliable(p, "403 Forbidden", req);
1553+- }
1554++ ast_log(LOG_NOTICE, "Failed to authenticate device %s\n", get_header(req, "From"));
1555++ transmit_response_reliable(p, "403 Forbidden", req);
1556+ p->invitestate = INV_COMPLETED;
1557+ sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
1558+ res = 0;
1559+@@ -24712,18 +24733,13 @@ static int handle_request_publish(struct
1560+ return -1;
1561+ }
1562+
1563+- auth_result = check_user(p, req, SIP_PUBLISH, uri, XMIT_RELIABLE, addr);
1564++ auth_result = check_user(p, req, SIP_PUBLISH, uri, XMIT_UNRELIABLE, addr);
1565+ if (auth_result == AUTH_CHALLENGE_SENT) {
1566+ p->lastinvite = seqno;
1567+ return 0;
1568+ } else if (auth_result < 0) {
1569+- if (auth_result == AUTH_FAKE_AUTH) {
1570+- ast_log(LOG_NOTICE, "Sending fake auth rejection for device %s\n", get_header(req, "From"));
1571+- transmit_fake_auth_response(p, SIP_INVITE, req, XMIT_RELIABLE);
1572+- } else {
1573+- ast_log(LOG_NOTICE, "Failed to authenticate device %s\n", get_header(req, "From"));
1574+- transmit_response_reliable(p, "403 Forbidden", req);
1575+- }
1576++ ast_log(LOG_NOTICE, "Failed to authenticate device %s\n", get_header(req, "From"));
1577++ transmit_response(p, "403 Forbidden", req);
1578+ sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
1579+ ast_string_field_set(p, theirtag, NULL);
1580+ return 0;
1581+@@ -24938,19 +24954,14 @@ static int handle_request_subscribe(stru
1582+ * use if !req->ignore, because then we'll end up sending
1583+ * a 200 OK if someone retransmits without sending auth */
1584+ if (p->subscribed == NONE || resubscribe) {
1585+- res = check_user_full(p, req, SIP_SUBSCRIBE, e, 0, addr, &authpeer);
1586++ res = check_user_full(p, req, SIP_SUBSCRIBE, e, XMIT_UNRELIABLE, addr, &authpeer);
1587+
1588+ /* if an authentication response was sent, we are done here */
1589+ if (res == AUTH_CHALLENGE_SENT) /* authpeer = NULL here */
1590+ return 0;
1591+ if (res != AUTH_SUCCESSFUL) {
1592+- if (res == AUTH_FAKE_AUTH) {
1593+- ast_log(LOG_NOTICE, "Sending fake auth rejection for device %s\n", get_header(req, "From"));
1594+- transmit_fake_auth_response(p, SIP_SUBSCRIBE, req, XMIT_UNRELIABLE);
1595+- } else {
1596+- ast_log(LOG_NOTICE, "Failed to authenticate device %s for SUBSCRIBE\n", get_header(req, "From"));
1597+- transmit_response_reliable(p, "403 Forbidden", req);
1598+- }
1599++ ast_log(LOG_NOTICE, "Failed to authenticate device %s\n", get_header(req, "From"));
1600++ transmit_response(p, "403 Forbidden", req);
1601+
1602+ pvt_set_needdestroy(p, "authentication failed");
1603+ return 0;
1604+@@ -29988,6 +29999,7 @@ static int sip_do_reload(enum channelrel
1605+ /*! \brief Force reload of module from cli */
1606+ static char *sip_reload(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
1607+ {
1608++ static struct sip_peer *tmp_peer, *new_peer;
1609+
1610+ switch (cmd) {
1611+ case CLI_INIT:
1612+@@ -30010,6 +30022,18 @@ static char *sip_reload(struct ast_cli_e
1613+ ast_mutex_unlock(&sip_reload_lock);
1614+ restart_monitor();
1615+
1616++ tmp_peer = bogus_peer;
1617++ /* Create new bogus peer possibly with new global settings. */
1618++ if ((new_peer = temp_peer("(bogus_peer)"))) {
1619++ ast_string_field_set(new_peer, md5secret, BOGUS_PEER_MD5SECRET);
1620++ ast_clear_flag(&new_peer->flags[0], SIP_INSECURE);
1621++ bogus_peer = new_peer;
1622++ ao2_t_ref(tmp_peer, -1, "unref the old bogus_peer during reload");
1623++ } else {
1624++ ast_log(LOG_ERROR, "Could not update the fake authentication peer.\n");
1625++ /* You probably have bigger (memory?) issues to worry about though.. */
1626++ }
1627++
1628+ return CLI_SUCCESS;
1629+ }
1630+
1631+@@ -31130,6 +31154,17 @@ static int load_module(void)
1632+ return AST_MODULE_LOAD_DECLINE;
1633+ }
1634+
1635++ /* Initialize bogus peer. Can be done first after reload_config() */
1636++ if (!(bogus_peer = temp_peer("(bogus_peer)"))) {
1637++ ast_log(LOG_ERROR, "Unable to create bogus_peer for authentication\n");
1638++ io_context_destroy(io);
1639++ sched_context_destroy(sched);
1640++ return AST_MODULE_LOAD_FAILURE;
1641++ }
1642++ /* Make sure the auth will always fail. */
1643++ ast_string_field_set(bogus_peer, md5secret, BOGUS_PEER_MD5SECRET);
1644++ ast_clear_flag(&bogus_peer->flags[0], SIP_INSECURE);
1645++
1646+ /* Prepare the version that does not require DTMF BEGIN frames.
1647+ * We need to use tricks such as memcpy and casts because the variable
1648+ * has const fields.
1649+@@ -31140,6 +31175,7 @@ static int load_module(void)
1650+ /* Make sure we can register our sip channel type */
1651+ if (ast_channel_register(&sip_tech)) {
1652+ ast_log(LOG_ERROR, "Unable to register channel type 'SIP'\n");
1653++ ao2_t_ref(bogus_peer, -1, "unref the bogus_peer");
1654+ io_context_destroy(io);
1655+ sched_context_destroy(sched);
1656+ return AST_MODULE_LOAD_FAILURE;
1657+@@ -31378,6 +31414,8 @@ static int unload_module(void)
1658+ ast_debug(2, "TCP/TLS thread container did not become empty :(\n");
1659+ }
1660+
1661++ ao2_t_ref(bogus_peer, -1, "unref the bogus_peer");
1662++
1663+ ao2_t_ref(peers, -1, "unref the peers table");
1664+ ao2_t_ref(peers_by_ip, -1, "unref the peers_by_ip table");
1665+ ao2_t_ref(dialogs, -1, "unref the dialogs table");
1666+--- a/channels/sip/include/sip.h
1667++++ b/channels/sip/include/sip.h
1668+@@ -470,7 +470,6 @@ enum check_auth_result {
1669+ AUTH_SECRET_FAILED = -1,
1670+ AUTH_USERNAME_MISMATCH = -2,
1671+ AUTH_NOT_FOUND = -3, /*!< returned by register_verify */
1672+- AUTH_FAKE_AUTH = -4,
1673+ AUTH_UNKNOWN_DOMAIN = -5,
1674+ AUTH_PEER_NOT_DYNAMIC = -6,
1675+ AUTH_ACL_FAILED = -7,
1676
1677=== modified file 'debian/patches/armhf-fixes'
1678--- debian/patches/armhf-fixes 2012-04-24 22:15:54 +0000
1679+++ debian/patches/armhf-fixes 2013-07-28 21:58:23 +0000
1680@@ -1,6 +1,5 @@
1681 Author: Adam Conrad <adconrad@ubuntu.com>
1682-
1683-Fix a few places where armhf is misdetected.
1684+Description: Fix a few places where armhf is misdetected. Flatten linux-gnueabihf in configure to linux-gnu, in the same way that's already done for linux-gnueabi.
1685
1686 --- x/configure.ac 2012-01-12 08:24:38.000000000 -0700
1687 +++ x/configure.ac 2012-01-12 08:59:45.647736713 -0700
1688
1689=== added file 'debian/patches/bluetooth_bind'
1690--- debian/patches/bluetooth_bind 1970-01-01 00:00:00 +0000
1691+++ debian/patches/bluetooth_bind 2013-07-28 21:58:23 +0000
1692@@ -0,0 +1,30 @@
1693+From: Matthew Jordan <mjordan@digium.com>
1694+Date: Thu, 17 Jan 2013 02:28:31 +0000
1695+Subject: Fix issue where chan_mobile fails to bind to first available port
1696+Bug: https://issues.asterisk.org/jira/browse/ASTERISK-16357
1697+Origin: http://svnview.digium.com/svn/asterisk?view=rev&rev=379342
1698+
1699+Per the bluez API, in order to bind to the first available port, the rc_channel
1700+field of the socket addressing structure used to bind the socket should be set
1701+to 0. Previously, Asterisk had set the rc_channel field set to 1, causing it
1702+to connect to whatever happens to be on port 1.
1703+
1704+We could probably not explicitly set rc_channel to 0 since we memset the struct
1705+earlier, but explicitly setting it will hopefully prevent someone from coming
1706+in and setting it to some explicit port in the future.
1707+
1708+---
1709+ addons/chan_mobile.c | 2 +-
1710+ 1 file changed, 1 insertion(+), 1 deletion(-)
1711+
1712+--- a/addons/chan_mobile.c
1713++++ b/addons/chan_mobile.c
1714+@@ -1370,7 +1370,7 @@ static int rfcomm_connect(bdaddr_t src,
1715+ memset(&addr, 0, sizeof(addr));
1716+ addr.rc_family = AF_BLUETOOTH;
1717+ bacpy(&addr.rc_bdaddr, &src);
1718+- addr.rc_channel = (uint8_t) 1;
1719++ addr.rc_channel = (uint8_t) 0;
1720+ if (bind(s, (struct sockaddr *)&addr, sizeof(addr)) < 0) {
1721+ ast_debug(1, "bind() failed (%d).\n", errno);
1722+ close(s);
1723
1724=== modified file 'debian/patches/series'
1725--- debian/patches/series 2012-09-08 12:38:06 +0000
1726+++ debian/patches/series 2013-07-28 21:58:23 +0000
1727@@ -29,3 +29,8 @@
1728
1729 AST-2012-012
1730 AST-2012-013
1731+AST-2012-014
1732+AST-2012-015
1733+AST-2013-002
1734+AST-2013-003
1735+bluetooth_bind

Subscribers

People subscribed via source and target branches

to all changes: