Compare commits

...

12 Commits

Author SHA1 Message Date
George Joseph
f0eea53cdc Update for 13.18.1 2017-11-08 11:26:46 -05:00
George Joseph
343efb0085 Merge "AST-2017-009: pjproject: Add validation of numeric header values" into 13.18 2017-11-08 09:52:13 -06:00
Jenkins2
32f9f3a080 Merge "AST-2017-011 - res_pjsip_session: session leak when a call is rejected" into 13.18 2017-11-08 09:20:39 -06:00
George Joseph
ed0acc1fff AST-2017-009: pjproject: Add validation of numeric header values
Parsing the numeric header fields like cseq, ttl, port, etc. all
had the potential to overflow, either causing unintended values to
be captured or, if the values were subsequently converted back to
strings, a buffer overrun.  To address this, new "strto" functions
have been created that do range checking and those functions are
used wherever possible in the parser.

 * Created pjlib/include/limits.h and pjlib/include/compat/limits.h
   to either include the system limits.h or define common numeric
   limits if there is no system limits.h.

 * Created strto*_validate functions in sip_parser that take bounds
   and on failure call the on_str_parse_error function which prints
   an error message and calls PJ_THROW.

 * Updated sip_parser to validate the numeric fields.

 * Fixed an issue in sip_transport that prevented error messages
   from being properly displayed.

 * Added "volatile" to some variables referenced in PJ_CATCH blocks
   as the optimizer was sometimes optimizing them away.

 * Fixed length calculation in sip_transaction/create_tsx_key_2543
   to account for signed ints being 11 characters, not 9.

ASTERISK-27319
Reported by: Youngsung Kim at LINE Corporation

Change-Id: I48de2e4ccf196990906304e8d7061f4ffdd772ff
2017-11-08 07:12:59 -07:00
Kevin Harwell
cd7c10c646 AST-2017-011 - res_pjsip_session: session leak when a call is rejected
A previous commit made it so when an invite session transitioned into a
disconnected state destruction of the Asterisk pjsip session object was
postponed until either a transport error occurred or the event timer
expired. However, if a call was rejected (for instance a 488) before the
session was fully established the event timer may not have been initiated,
or it was canceled without triggering either of the session finalizing states
mentioned above.

Really the only time destruction of the session should be delayed is when a
BYE is being transacted. This is because it's possible in some cases for the
session to be disconnected, but the BYE is still transacting.

This patch makes it so the session object always gets released (no more
memory leak) when the pjsip session is in a disconnected state. Except when
the method is a BYE. Then it waits until a transport error occurs or an event
timeout.

ASTERISK-27345 #close

Reported by: Corey Farrell

Change-Id: I1e724737b758c20ac76d19d3611e3d2876ae10ed
2017-11-08 05:46:58 -07:00
Richard Mudgett
8f7073be6d AST-2017-010: Fix cdr_object_update_party_b_userfield_cb() buf overrun
cdr_object_update_party_b_userfield_cb() could overrun the fixed buffer if
the supplied string is too long.  The long string could be supplied by
external means using the CDR(userfield) function.

This may seem reminiscent to AST-2017-001 (ASTERISK_26897) and it is.  The
earlier patch fixed the buffer overrun for Party A's userfield while this
patch fixes the same thing for Party B's userfield.

ASTERISK-27337

Change-Id: I0fa767f65ecec7e676ca465306ff9e0edbf3b652
2017-11-08 05:38:23 -07:00
Kevin Harwell
719ac573a6 Update for 13.18.0 2017-10-30 10:33:07 -05:00
Kevin Harwell
82cedfbcb3 Update for 13.18.0-rc2 2017-10-25 15:01:55 -05:00
George Joseph
576daa8a99 Merge "http.c: Fix http header send content." into 13.18 2017-10-25 13:05:30 -05:00
Joshua Colp
db233704f4 res_xmpp: Ensure the connection filter is available.
Users of the API that res_xmpp provides expect that a
filter be available on the client at all times. When
OAuth authentication support was added this requirement
was not maintained.

This change merely moves the OAuth authentication to
after the filter is created, ensuring users of res_xmpp
can add things to the filter as needed.

ASTERISK-27346

Change-Id: I4ac474afe220e833288ff574e32e2b9a23394886
(cherry picked from commit 07e17fd04f)
2017-10-25 11:22:47 -05:00
Ben Ford
72bf65f44f http.c: Fix http header send content.
Currently ast_http_send barricades a portion of the content that
needs to be sent in order to establish a connection for things
like the ARI client. The conditional and contents have been changed
to ensure that everything that needs to be sent, will be sent.

ASTERISK-27372

Change-Id: I8816d2d8f80f4fefc6dcae4b5fdfc97f1e46496d
2017-10-25 10:39:24 -05:00
Kevin Harwell
d5d1e98fa4 Update for 13.18.0-rc1 2017-10-13 12:46:56 -05:00
22 changed files with 61514 additions and 72 deletions

1
.lastclean Normal file
View File

@@ -0,0 +1 @@
40

1
.version Normal file
View File

@@ -0,0 +1 @@
13.18.1

54203
ChangeLog Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,24 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><title>Release Summary - asterisk-13.18.1</title><h1 align="center"><a name="top">Release Summary</a></h1><h3 align="center">asterisk-13.18.1</h3><h3 align="center">Date: 2017-11-08</h3><h3 align="center">&lt;asteriskteam@digium.com&gt;</h3><hr><h2 align="center">Table of Contents</h2><ol>
<li><a href="#summary">Summary</a></li>
<li><a href="#contributors">Contributors</a></li>
<li><a href="#closed_issues">Closed Issues</a></li>
<li><a href="#diffstat">Diffstat</a></li>
</ol><hr><a name="summary"><h2 align="center">Summary</h2></a><center><a href="#top">[Back to Top]</a></center><p>This release has been made to address one or more security vulnerabilities that have been identified. A security advisory document has been published for each vulnerability that includes additional information. Users of versions of Asterisk that are affected are strongly encouraged to review the advisories and determine what action they should take to protect their systems from these issues.</p><p>Security Advisories:</p><ul>
<li><a href="http://downloads.asterisk.org/pub/security/AST-2017-009,AST-2017-010,AST-2017-011.html">AST-2017-009,AST-2017-010,AST-2017-011</a></li>
</ul><p>The data in this summary reflects changes that have been made since the previous release, asterisk-13.18.0.</p><hr><a name="contributors"><h2 align="center">Contributors</h2></a><center><a href="#top">[Back to Top]</a></center><p>This table lists the people who have submitted code, those that have tested patches, as well as those that reported issues on the issue tracker that were resolved in this release. For coders, the number is how many of their patches (of any size) were committed into this release. For testers, the number is the number of times their name was listed as assisting with testing a patch. Finally, for reporters, the number is the number of issues that they reported that were affected by commits that went into this release.</p><table width="100%" border="0">
<tr><th width="33%">Coders</th><th width="33%">Testers</th><th width="33%">Reporters</th></tr>
<tr valign="top"><td width="33%">1 Richard Mudgett <rmudgett@digium.com><br/>1 Kevin Harwell <kharwell@digium.com><br/>1 George Joseph <gjoseph@digium.com><br/></td><td width="33%"><td width="33%">1 Youngsung Kim at LINE Corporation<br/>1 Richard Mudgett <rmudgett@digium.com><br/>1 Kim youngsung <youngsung.kim@linecorp.com><br/>1 Corey Farrell <git@cfware.com><br/></td></tr>
</table><hr><a name="closed_issues"><h2 align="center">Closed Issues</h2></a><center><a href="#top">[Back to Top]</a></center><p>This is a list of all issues from the issue tracker that were closed by changes that went into this release.</p><h3>Bug</h3><h4>Category: General</h4><a href="https://issues.asterisk.org/jira/browse/ASTERISK-27319">ASTERISK-27319</a>: (Security) Function in PJSIP 2.7 miscalculates the length of an unsigned long variable in 64bit machines<br/>Reported by: Kim youngsung<ul>
<li><a href="https://code.asterisk.org/code/changelog/asterisk?cs=ed0acc1fff3547ee4d7870b45d9b910b328b4e8a">[ed0acc1fff]</a> George Joseph -- AST-2017-009: pjproject: Add validation of numeric header values</li>
</ul><a href="https://issues.asterisk.org/jira/browse/ASTERISK-27337">ASTERISK-27337</a>: chan_sip: Security vulnerability with client code header (revisited)<br/>Reported by: Richard Mudgett<ul>
<li><a href="https://code.asterisk.org/code/changelog/asterisk?cs=8f7073be6d08029d222de8a17c5982fa28534e58">[8f7073be6d]</a> Richard Mudgett -- AST-2017-010: Fix cdr_object_update_party_b_userfield_cb() buf overrun</li>
</ul><br><h4>Category: Resources/res_pjsip</h4><a href="https://issues.asterisk.org/jira/browse/ASTERISK-27345">ASTERISK-27345</a>: res_pjsip_session: RTP instances leak on 488 responses.<br/>Reported by: Corey Farrell<ul>
<li><a href="https://code.asterisk.org/code/changelog/asterisk?cs=cd7c10c6468c1931b4860d5eaf1b1b1df82fe72d">[cd7c10c646]</a> Kevin Harwell -- AST-2017-011 - res_pjsip_session: session leak when a call is rejected</li>
</ul><br><h4>Category: Resources/res_pjsip_sdp_rtp</h4><a href="https://issues.asterisk.org/jira/browse/ASTERISK-27345">ASTERISK-27345</a>: res_pjsip_session: RTP instances leak on 488 responses.<br/>Reported by: Corey Farrell<ul>
<li><a href="https://code.asterisk.org/code/changelog/asterisk?cs=cd7c10c6468c1931b4860d5eaf1b1b1df82fe72d">[cd7c10c646]</a> Kevin Harwell -- AST-2017-011 - res_pjsip_session: session leak when a call is rejected</li>
</ul><br><h4>Category: Resources/res_pjsip_session</h4><a href="https://issues.asterisk.org/jira/browse/ASTERISK-27345">ASTERISK-27345</a>: res_pjsip_session: RTP instances leak on 488 responses.<br/>Reported by: Corey Farrell<ul>
<li><a href="https://code.asterisk.org/code/changelog/asterisk?cs=cd7c10c6468c1931b4860d5eaf1b1b1df82fe72d">[cd7c10c646]</a> Kevin Harwell -- AST-2017-011 - res_pjsip_session: session leak when a call is rejected</li>
</ul><br><hr><a name="diffstat"><h2 align="center">Diffstat Results</h2></a><center><a href="#top">[Back to Top]</a></center><p>This is a summary of the changes to the source code that went into this release that was generated using the diffstat utility.</p><pre>main/cdr.c | 6
res/res_pjsip_session.c | 80
third-party/pjproject/patches/0090-sip_parser-Add-validity-checking-for-numeric-header-.patch | 828 ++++++++++
3 files changed, 874 insertions(+), 40 deletions(-)</pre><br></html>

View File

@@ -0,0 +1,116 @@
Release Summary
asterisk-13.18.1
Date: 2017-11-08
<asteriskteam@digium.com>
----------------------------------------------------------------------
Table of Contents
1. Summary
2. Contributors
3. Closed Issues
4. Diffstat
----------------------------------------------------------------------
Summary
[Back to Top]
This release has been made to address one or more security vulnerabilities
that have been identified. A security advisory document has been published
for each vulnerability that includes additional information. Users of
versions of Asterisk that are affected are strongly encouraged to review
the advisories and determine what action they should take to protect their
systems from these issues.
Security Advisories:
* AST-2017-009,AST-2017-010,AST-2017-011
The data in this summary reflects changes that have been made since the
previous release, asterisk-13.18.0.
----------------------------------------------------------------------
Contributors
[Back to Top]
This table lists the people who have submitted code, those that have
tested patches, as well as those that reported issues on the issue tracker
that were resolved in this release. For coders, the number is how many of
their patches (of any size) were committed into this release. For testers,
the number is the number of times their name was listed as assisting with
testing a patch. Finally, for reporters, the number is the number of
issues that they reported that were affected by commits that went into
this release.
Coders Testers Reporters
1 Richard Mudgett 1 Youngsung Kim at LINE Corporation
1 Kevin Harwell 1 Richard Mudgett
1 George Joseph 1 Kim youngsung
1 Corey Farrell
----------------------------------------------------------------------
Closed Issues
[Back to Top]
This is a list of all issues from the issue tracker that were closed by
changes that went into this release.
Bug
Category: General
ASTERISK-27319: (Security) Function in PJSIP 2.7 miscalculates the length
of an unsigned long variable in 64bit machines
Reported by: Kim youngsung
* [ed0acc1fff] George Joseph -- AST-2017-009: pjproject: Add validation
of numeric header values
ASTERISK-27337: chan_sip: Security vulnerability with client code header
(revisited)
Reported by: Richard Mudgett
* [8f7073be6d] Richard Mudgett -- AST-2017-010: Fix
cdr_object_update_party_b_userfield_cb() buf overrun
Category: Resources/res_pjsip
ASTERISK-27345: res_pjsip_session: RTP instances leak on 488 responses.
Reported by: Corey Farrell
* [cd7c10c646] Kevin Harwell -- AST-2017-011 - res_pjsip_session:
session leak when a call is rejected
Category: Resources/res_pjsip_sdp_rtp
ASTERISK-27345: res_pjsip_session: RTP instances leak on 488 responses.
Reported by: Corey Farrell
* [cd7c10c646] Kevin Harwell -- AST-2017-011 - res_pjsip_session:
session leak when a call is rejected
Category: Resources/res_pjsip_session
ASTERISK-27345: res_pjsip_session: RTP instances leak on 488 responses.
Reported by: Corey Farrell
* [cd7c10c646] Kevin Harwell -- AST-2017-011 - res_pjsip_session:
session leak when a call is rejected
----------------------------------------------------------------------
Diffstat Results
[Back to Top]
This is a summary of the changes to the source code that went into this
release that was generated using the diffstat utility.
main/cdr.c | 6
res/res_pjsip_session.c | 80
third-party/pjproject/patches/0090-sip_parser-Add-validity-checking-for-numeric-header-.patch | 828 ++++++++++
3 files changed, 874 insertions(+), 40 deletions(-)

View File

@@ -0,0 +1,44 @@
BEGIN TRANSACTION;
CREATE TABLE alembic_version (
version_num VARCHAR(32) NOT NULL
);
GO
-- Running upgrade -> 210693f3123d
CREATE TABLE cdr (
accountcode VARCHAR(20) NULL,
src VARCHAR(80) NULL,
dst VARCHAR(80) NULL,
dcontext VARCHAR(80) NULL,
clid VARCHAR(80) NULL,
channel VARCHAR(80) NULL,
dstchannel VARCHAR(80) NULL,
lastapp VARCHAR(80) NULL,
lastdata VARCHAR(80) NULL,
start DATETIME NULL,
answer DATETIME NULL,
[end] DATETIME NULL,
duration INTEGER NULL,
billsec INTEGER NULL,
disposition VARCHAR(45) NULL,
amaflags VARCHAR(45) NULL,
userfield VARCHAR(256) NULL,
uniqueid VARCHAR(150) NULL,
linkedid VARCHAR(150) NULL,
peeraccount VARCHAR(20) NULL,
sequence INTEGER NULL
);
GO
INSERT INTO alembic_version (version_num) VALUES ('210693f3123d');
GO
COMMIT;
GO

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,54 @@
BEGIN TRANSACTION;
CREATE TABLE alembic_version (
version_num VARCHAR(32) NOT NULL
);
GO
-- Running upgrade -> a2e9769475e
CREATE TABLE voicemail_messages (
dir VARCHAR(255) NOT NULL,
msgnum INTEGER NOT NULL,
context VARCHAR(80) NULL,
macrocontext VARCHAR(80) NULL,
callerid VARCHAR(80) NULL,
origtime INTEGER NULL,
duration INTEGER NULL,
recording IMAGE NULL,
flag VARCHAR(30) NULL,
category VARCHAR(30) NULL,
mailboxuser VARCHAR(30) NULL,
mailboxcontext VARCHAR(30) NULL,
msg_id VARCHAR(40) NULL
);
GO
ALTER TABLE voicemail_messages ADD CONSTRAINT voicemail_messages_dir_msgnum PRIMARY KEY (dir, msgnum);
GO
CREATE INDEX voicemail_messages_dir ON voicemail_messages (dir);
GO
INSERT INTO alembic_version (version_num) VALUES ('a2e9769475e');
GO
-- Running upgrade a2e9769475e -> 39428242f7f5
ALTER TABLE voicemail_messages ALTER COLUMN recording IMAGE;
GO
UPDATE alembic_version SET version_num='39428242f7f5' WHERE alembic_version.version_num = 'a2e9769475e';
GO
COMMIT;
GO

View File

@@ -0,0 +1,32 @@
CREATE TABLE alembic_version (
version_num VARCHAR(32) NOT NULL
);
-- Running upgrade -> 210693f3123d
CREATE TABLE cdr (
accountcode VARCHAR(20),
src VARCHAR(80),
dst VARCHAR(80),
dcontext VARCHAR(80),
clid VARCHAR(80),
channel VARCHAR(80),
dstchannel VARCHAR(80),
lastapp VARCHAR(80),
lastdata VARCHAR(80),
start DATETIME,
answer DATETIME,
end DATETIME,
duration INTEGER,
billsec INTEGER,
disposition VARCHAR(45),
amaflags VARCHAR(45),
userfield VARCHAR(256),
uniqueid VARCHAR(150),
linkedid VARCHAR(150),
peeraccount VARCHAR(20),
sequence INTEGER
);
INSERT INTO alembic_version (version_num) VALUES ('210693f3123d');

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,34 @@
CREATE TABLE alembic_version (
version_num VARCHAR(32) NOT NULL
);
-- Running upgrade -> a2e9769475e
CREATE TABLE voicemail_messages (
dir VARCHAR(255) NOT NULL,
msgnum INTEGER NOT NULL,
context VARCHAR(80),
macrocontext VARCHAR(80),
callerid VARCHAR(80),
origtime INTEGER,
duration INTEGER,
recording BLOB,
flag VARCHAR(30),
category VARCHAR(30),
mailboxuser VARCHAR(30),
mailboxcontext VARCHAR(30),
msg_id VARCHAR(40)
);
ALTER TABLE voicemail_messages ADD CONSTRAINT voicemail_messages_dir_msgnum PRIMARY KEY (dir, msgnum);
CREATE INDEX voicemail_messages_dir ON voicemail_messages (dir);
INSERT INTO alembic_version (version_num) VALUES ('a2e9769475e');
-- Running upgrade a2e9769475e -> 39428242f7f5
ALTER TABLE voicemail_messages MODIFY recording BLOB(4294967295) NULL;
UPDATE alembic_version SET version_num='39428242f7f5' WHERE alembic_version.version_num = 'a2e9769475e';

View File

@@ -0,0 +1,38 @@
CREATE TABLE alembic_version (
version_num VARCHAR2(32 CHAR) NOT NULL
)
/
-- Running upgrade -> 210693f3123d
CREATE TABLE cdr (
accountcode VARCHAR2(20 CHAR),
src VARCHAR2(80 CHAR),
dst VARCHAR2(80 CHAR),
dcontext VARCHAR2(80 CHAR),
clid VARCHAR2(80 CHAR),
channel VARCHAR2(80 CHAR),
dstchannel VARCHAR2(80 CHAR),
lastapp VARCHAR2(80 CHAR),
lastdata VARCHAR2(80 CHAR),
"start" DATE,
answer DATE,
end DATE,
duration INTEGER,
billsec INTEGER,
disposition VARCHAR2(45 CHAR),
amaflags VARCHAR2(45 CHAR),
userfield VARCHAR2(256 CHAR),
uniqueid VARCHAR2(150 CHAR),
linkedid VARCHAR2(150 CHAR),
peeraccount VARCHAR2(20 CHAR),
sequence INTEGER
)
/
INSERT INTO alembic_version (version_num) VALUES ('210693f3123d')
/

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,48 @@
CREATE TABLE alembic_version (
version_num VARCHAR2(32 CHAR) NOT NULL
)
/
-- Running upgrade -> a2e9769475e
CREATE TABLE voicemail_messages (
dir VARCHAR2(255 CHAR) NOT NULL,
msgnum INTEGER NOT NULL,
context VARCHAR2(80 CHAR),
macrocontext VARCHAR2(80 CHAR),
callerid VARCHAR2(80 CHAR),
origtime INTEGER,
duration INTEGER,
recording BLOB,
flag VARCHAR2(30 CHAR),
category VARCHAR2(30 CHAR),
mailboxuser VARCHAR2(30 CHAR),
mailboxcontext VARCHAR2(30 CHAR),
msg_id VARCHAR2(40 CHAR)
)
/
ALTER TABLE voicemail_messages ADD CONSTRAINT voicemail_messages_dir_msgnum PRIMARY KEY (dir, msgnum)
/
CREATE INDEX voicemail_messages_dir ON voicemail_messages (dir)
/
INSERT INTO alembic_version (version_num) VALUES ('a2e9769475e')
/
-- Running upgrade a2e9769475e -> 39428242f7f5
ALTER TABLE voicemail_messages MODIFY recording BLOB
/
UPDATE alembic_version SET version_num='39428242f7f5' WHERE alembic_version.version_num = 'a2e9769475e'
/

View File

@@ -0,0 +1,36 @@
BEGIN;
CREATE TABLE alembic_version (
version_num VARCHAR(32) NOT NULL
);
-- Running upgrade -> 210693f3123d
CREATE TABLE cdr (
accountcode VARCHAR(20),
src VARCHAR(80),
dst VARCHAR(80),
dcontext VARCHAR(80),
clid VARCHAR(80),
channel VARCHAR(80),
dstchannel VARCHAR(80),
lastapp VARCHAR(80),
lastdata VARCHAR(80),
start TIMESTAMP WITHOUT TIME ZONE,
answer TIMESTAMP WITHOUT TIME ZONE,
"end" TIMESTAMP WITHOUT TIME ZONE,
duration INTEGER,
billsec INTEGER,
disposition VARCHAR(45),
amaflags VARCHAR(45),
userfield VARCHAR(256),
uniqueid VARCHAR(150),
linkedid VARCHAR(150),
peeraccount VARCHAR(20),
sequence INTEGER
);
INSERT INTO alembic_version (version_num) VALUES ('210693f3123d');
COMMIT;

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,38 @@
BEGIN;
CREATE TABLE alembic_version (
version_num VARCHAR(32) NOT NULL
);
-- Running upgrade -> a2e9769475e
CREATE TABLE voicemail_messages (
dir VARCHAR(255) NOT NULL,
msgnum INTEGER NOT NULL,
context VARCHAR(80),
macrocontext VARCHAR(80),
callerid VARCHAR(80),
origtime INTEGER,
duration INTEGER,
recording BYTEA,
flag VARCHAR(30),
category VARCHAR(30),
mailboxuser VARCHAR(30),
mailboxcontext VARCHAR(30),
msg_id VARCHAR(40)
);
ALTER TABLE voicemail_messages ADD CONSTRAINT voicemail_messages_dir_msgnum PRIMARY KEY (dir, msgnum);
CREATE INDEX voicemail_messages_dir ON voicemail_messages (dir);
INSERT INTO alembic_version (version_num) VALUES ('a2e9769475e');
-- Running upgrade a2e9769475e -> 39428242f7f5
ALTER TABLE voicemail_messages ALTER COLUMN recording TYPE BYTEA;
UPDATE alembic_version SET version_num='39428242f7f5' WHERE alembic_version.version_num = 'a2e9769475e';
COMMIT;

View File

@@ -3229,7 +3229,8 @@ static int cdr_object_update_party_b_userfield_cb(void *obj, void *arg, int flag
}
if (it_cdr->party_b.snapshot
&& !strcasecmp(it_cdr->party_b.snapshot->name, info->channel_name)) {
strcpy(it_cdr->party_b.userfield, info->userfield);
ast_copy_string(it_cdr->party_b.userfield, info->userfield,
sizeof(it_cdr->party_b.userfield));
}
}
return 0;
@@ -3252,7 +3253,8 @@ void ast_cdr_setuserfield(const char *channel_name, const char *userfield)
if (it_cdr->fn_table == &finalized_state_fn_table && it_cdr->next != NULL) {
continue;
}
ast_copy_string(it_cdr->party_a.userfield, userfield, AST_MAX_USER_FIELD);
ast_copy_string(it_cdr->party_a.userfield, userfield,
sizeof(it_cdr->party_a.userfield));
}
ao2_unlock(cdr);
}

View File

@@ -451,9 +451,12 @@ void ast_http_send(struct ast_tcptls_session_instance *ser,
struct timeval now = ast_tvnow();
struct ast_tm tm;
char timebuf[80];
char buf[256];
int len;
int content_length = 0;
int close_connection;
struct ast_str *server_header_field = ast_str_create(MAX_SERVER_NAME_LENGTH);
int send_content;
if (!ser || !ser->f || !server_header_field) {
/* The connection is not open. */
@@ -504,6 +507,8 @@ void ast_http_send(struct ast_tcptls_session_instance *ser,
lseek(fd, 0, SEEK_SET);
}
send_content = method != AST_HTTP_HEAD || status_code >= 400;
/* send http header */
if (fprintf(ser->f,
"HTTP/1.1 %d %s\r\n"
@@ -513,46 +518,30 @@ void ast_http_send(struct ast_tcptls_session_instance *ser,
"%s"
"%s"
"Content-Length: %d\r\n"
"\r\n",
"\r\n"
"%s",
status_code, status_title ? status_title : "OK",
ast_str_buffer(server_header_field),
timebuf,
close_connection ? "Connection: close\r\n" : "",
static_content ? "" : "Cache-Control: no-cache, no-store\r\n",
http_header ? ast_str_buffer(http_header) : "",
content_length
content_length,
send_content && out && ast_str_strlen(out) ? ast_str_buffer(out) : ""
) <= 0) {
ast_debug(1, "fprintf() failed: %s\n", strerror(errno));
close_connection = 1;
}
/* send content */
if (!close_connection && (method != AST_HTTP_HEAD || status_code >= 400)) {
if (out && ast_str_strlen(out)) {
} else if (send_content && fd) {
/* send file content */
while ((len = read(fd, buf, sizeof(buf))) > 0) {
/*
* NOTE: Because ser->f is a non-standard FILE *, fwrite() will probably not
* behave exactly as documented.
*/
if (fwrite(ast_str_buffer(out), ast_str_strlen(out), 1, ser->f) != 1) {
if (fwrite(buf, len, 1, ser->f) != 1) {
ast_debug(1, "fwrite() failed: %s\n", strerror(errno));
close_connection = 1;
}
}
if (fd) {
char buf[256];
int len;
while ((len = read(fd, buf, sizeof(buf))) > 0) {
/*
* NOTE: Because ser->f is a non-standard FILE *, fwrite() will probably not
* behave exactly as documented.
*/
if (fwrite(buf, len, 1, ser->f) != 1) {
ast_debug(1, "fwrite() failed: %s\n", strerror(errno));
close_connection = 1;
break;
}
break;
}
}
}

View File

@@ -2654,6 +2654,36 @@ static void session_inv_on_new_session(pjsip_inv_session *inv, pjsip_event *e)
/* XXX STUB */
}
static int session_end_if_disconnected(int id, pjsip_inv_session *inv)
{
struct ast_sip_session *session;
if (inv->state != PJSIP_INV_STATE_DISCONNECTED) {
return 0;
}
/*
* We are locking because ast_sip_dialog_get_session() needs
* the dialog locked to get the session by other threads.
*/
pjsip_dlg_inc_lock(inv->dlg);
session = inv->mod_data[id];
inv->mod_data[id] = NULL;
pjsip_dlg_dec_lock(inv->dlg);
/*
* Pass the session ref held by session->inv_session to
* session_end_completion().
*/
if (session
&& ast_sip_push_task(session->serializer, session_end_completion, session)) {
/* Do it anyway even though this is not the right thread. */
session_end_completion(session);
}
return 1;
}
static void session_inv_on_tsx_state_changed(pjsip_inv_session *inv, pjsip_transaction *tsx, pjsip_event *e)
{
ast_sip_session_response_cb cb;
@@ -2678,6 +2708,17 @@ static void session_inv_on_tsx_state_changed(pjsip_inv_session *inv, pjsip_trans
/* The session has ended. Ignore the transaction change. */
return;
}
/*
* If the session is disconnected really nothing else to do unless currently transacting
* a BYE. If a BYE then hold off destruction until the transaction timeout occurs. This
* has to be done for BYEs because sometimes the dialog can be in a disconnected
* state but the BYE request transaction has not yet completed.
*/
if (tsx->method.id != PJSIP_BYE_METHOD && session_end_if_disconnected(id, inv)) {
return;
}
switch (e->body.tsx_state.type) {
case PJSIP_EVENT_TX_MSG:
/* When we create an outgoing request, we do not have access to the transaction that
@@ -2800,49 +2841,12 @@ static void session_inv_on_tsx_state_changed(pjsip_inv_session *inv, pjsip_trans
}
break;
case PJSIP_EVENT_TRANSPORT_ERROR:
if (inv->state == PJSIP_INV_STATE_DISCONNECTED) {
/*
* Clear the module data now to block session_inv_on_state_changed()
* from calling session_end() if it hasn't already done so.
*/
inv->mod_data[id] = NULL;
/*
* Pass the session ref held by session->inv_session to
* session_end_completion().
*/
if (session
&& ast_sip_push_task(session->serializer, session_end_completion, session)) {
/* Do it anyway even though this is not the right thread. */
session_end_completion(session);
}
return;
}
break;
case PJSIP_EVENT_TIMER:
/*
* The timer event is run by the pjsip monitor thread and not
* by the session serializer.
*/
if (inv->state == PJSIP_INV_STATE_DISCONNECTED) {
/*
* We are locking because ast_sip_dialog_get_session() needs
* the dialog locked to get the session by other threads.
*/
pjsip_dlg_inc_lock(inv->dlg);
session = inv->mod_data[id];
inv->mod_data[id] = NULL;
pjsip_dlg_dec_lock(inv->dlg);
/*
* Pass the session ref held by session->inv_session to
* session_end_completion().
*/
if (session
&& ast_sip_push_task(session->serializer, session_end_completion, session)) {
/* Do it anyway even though this is not the right thread. */
session_end_completion(session);
}
if (session_end_if_disconnected(id, inv)) {
return;
}
break;

View File

@@ -3654,13 +3654,6 @@ static int xmpp_client_reconnect(struct ast_xmpp_client *client)
return -1;
}
if (!ast_strlen_zero(clientcfg->refresh_token)) {
ast_debug(2, "Obtaining OAuth access token for client '%s'\n", client->name);
if (fetch_access_token(clientcfg)) {
return -1;
}
}
ast_xmpp_client_disconnect(client);
client->timeout = 50;
@@ -3671,6 +3664,13 @@ static int xmpp_client_reconnect(struct ast_xmpp_client *client)
return -1;
}
if (!ast_strlen_zero(clientcfg->refresh_token)) {
ast_debug(2, "Obtaining OAuth access token for client '%s'\n", client->name);
if (fetch_access_token(clientcfg)) {
return -1;
}
}
/* If it's a component connect to user otherwise connect to server */
res = iks_connect_via(client->parser, S_OR(clientcfg->server, client->jid->server), clientcfg->port,
ast_test_flag(&clientcfg->flags, XMPP_COMPONENT) ? clientcfg->user : client->jid->server);

View File

@@ -0,0 +1,910 @@
diff -uprN pjproject-2.6-a/pjlib/build/pjlib.vcproj pjproject-2.6-b/pjlib/build/pjlib.vcproj
--- pjproject-2.6-a/pjlib/build/pjlib.vcproj 2013-06-19 00:47:43.000000000 -0600
+++ pjproject-2.6-b/pjlib/build/pjlib.vcproj 2017-11-08 06:54:01.531232949 -0700
@@ -14967,7 +14967,11 @@
</File>
<File
RelativePath="..\include\pj\ip_helper.h"
- >
+ >
+ </File>
+ <File
+ RelativePath="..\include\pj\limits.h"
+ >
</File>
<File
RelativePath="..\include\pj\list.h"
@@ -15070,8 +15074,12 @@
</File>
<File
RelativePath="..\include\pj\compat\high_precision.h"
- >
- </File>
+ >
+ </File>
+ <File
+ RelativePath="..\include\pj\compat\limits.h"
+ >
+ </File>
<File
RelativePath="..\include\pj\compat\m_alpha.h"
>
diff -uprN pjproject-2.6-a/pjlib/build/pjlib.vcxproj pjproject-2.6-b/pjlib/build/pjlib.vcxproj
--- pjproject-2.6-a/pjlib/build/pjlib.vcxproj 2017-01-22 21:32:34.000000000 -0700
+++ pjproject-2.6-b/pjlib/build/pjlib.vcxproj 2017-11-08 06:54:01.531232949 -0700
@@ -494,7 +494,7 @@
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|ARM'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
</ClCompile>
- <ClCompile Include="..\src\pj\file_io_win32.c" />
+ <ClCompile Include="..\src\pj\file_io_win32.c" />
<ClCompile Include="..\src\pj\guid.c" />
<ClCompile Include="..\src\pj\guid_simple.c">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug-Dynamic|Win32'">true</ExcludedFromBuild>
@@ -890,6 +890,7 @@
<ClInclude Include="..\include\pj\compat\ctype.h" />
<ClInclude Include="..\include\pj\compat\errno.h" />
<ClInclude Include="..\include\pj\compat\high_precision.h" />
+ <ClInclude Include="..\include\pj\compat\limits.h" />
<ClInclude Include="..\include\pj\compat\malloc.h" />
<ClInclude Include="..\include\pj\compat\m_alpha.h" />
<ClInclude Include="..\include\pj\compat\m_i386.h" />
@@ -925,6 +926,7 @@
<ClInclude Include="..\include\pj\hash.h" />
<ClInclude Include="..\include\pj\ioqueue.h" />
<ClInclude Include="..\include\pj\ip_helper.h" />
+ <ClInclude Include="..\include\pj\limits.h" />
<ClInclude Include="..\include\pj\list.h" />
<ClInclude Include="..\include\pj\list_i.h" />
<ClInclude Include="..\include\pj\lock.h" />
diff -uprN pjproject-2.6-a/pjlib/build/pjlib.vcxproj.filters pjproject-2.6-b/pjlib/build/pjlib.vcxproj.filters
--- pjproject-2.6-a/pjlib/build/pjlib.vcxproj.filters 2017-01-22 21:32:34.000000000 -0700
+++ pjproject-2.6-b/pjlib/build/pjlib.vcxproj.filters 2017-11-08 06:54:01.532232969 -0700
@@ -439,5 +439,11 @@
<ClInclude Include="..\include\pj\compat\os_winuwp.h">
<Filter>Header Files\compat</Filter>
</ClInclude>
+ <ClInclude Include="..\include\pj\limits.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="..\include\pj\compat\limits.h">
+ <Filter>Header Files\compat</Filter>
+ </ClInclude>
</ItemGroup>
</Project>
\ No newline at end of file
diff -uprN pjproject-2.6-a/pjlib/include/pj/compat/limits.h pjproject-2.6-b/pjlib/include/pj/compat/limits.h
--- pjproject-2.6-a/pjlib/include/pj/compat/limits.h 1969-12-31 17:00:00.000000000 -0700
+++ pjproject-2.6-b/pjlib/include/pj/compat/limits.h 2017-11-08 06:54:01.532232969 -0700
@@ -0,0 +1,65 @@
+/* $Id$ */
+/*
+ * Copyright (C) 2017 Teluu Inc. (http://www.teluu.com)
+ * Copyright (C) 2017 George Joseph <gjoseph@digium.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+#ifndef __PJ_COMPAT_LIMITS_H__
+#define __PJ_COMPAT_LIMITS_H__
+
+/**
+ * @file limits.h
+ * @brief Provides integer limits normally found in limits.h.
+ */
+
+#if defined(PJ_HAS_LIMITS_H) && PJ_HAS_LIMITS_H != 0
+# include <limits.h>
+#else
+
+# ifdef _MSC_VER
+# pragma message("limits.h is not found or not supported. LONG_MIN and "\
+ "LONG_MAX will be defined by the library in "\
+ "pj/compats/limits.h and overridable in config_site.h")
+# else
+# warning "limits.h is not found or not supported. LONG_MIN and LONG_MAX " \
+ "will be defined by the library in pj/compats/limits.h and "\
+ "overridable in config_site.h"
+# endif
+
+/* Minimum and maximum values a `signed long int' can hold. */
+# ifndef LONG_MAX
+# if __WORDSIZE == 64
+# define LONG_MAX 9223372036854775807L
+# else
+# define LONG_MAX 2147483647L
+# endif
+# endif
+
+# ifndef LONG_MIN
+# define LONG_MIN (-LONG_MAX - 1L)
+# endif
+
+/* Maximum value an `unsigned long int' can hold. (Minimum is 0.) */
+# ifndef ULONG_MAX
+# if __WORDSIZE == 64
+# define ULONG_MAX 18446744073709551615UL
+# else
+# define ULONG_MAX 4294967295UL
+# endif
+# endif
+#endif
+
+#endif /* __PJ_COMPAT_LIMITS_H__ */
diff -uprN pjproject-2.6-a/pjlib/include/pj/compat/os_win32.h pjproject-2.6-b/pjlib/include/pj/compat/os_win32.h
--- pjproject-2.6-a/pjlib/include/pj/compat/os_win32.h 2011-05-05 00:14:19.000000000 -0600
+++ pjproject-2.6-b/pjlib/include/pj/compat/os_win32.h 2017-11-08 06:54:01.532232969 -0700
@@ -57,6 +57,7 @@
#define PJ_HAS_SYS_TYPES_H 1
#define PJ_HAS_TIME_H 1
#define PJ_HAS_UNISTD_H 0
+#define PJ_HAS_LIMITS_H 1
#define PJ_HAS_MSWSOCK_H 1
#define PJ_HAS_WINSOCK_H 0
diff -uprN pjproject-2.6-a/pjlib/include/pj/limits.h pjproject-2.6-b/pjlib/include/pj/limits.h
--- pjproject-2.6-a/pjlib/include/pj/limits.h 1969-12-31 17:00:00.000000000 -0700
+++ pjproject-2.6-b/pjlib/include/pj/limits.h 2017-11-08 06:54:01.532232969 -0700
@@ -0,0 +1,51 @@
+/* $Id$ */
+/*
+ * Copyright (C) 2017 Teluu Inc. (http://www.teluu.com)
+ * Copyright (C) 2017 George Joseph <gjoseph@digium.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+#ifndef __PJ_LIMITS_H__
+#define __PJ_LIMITS_H__
+
+/**
+ * @file limits.h
+ * @brief Common min and max values
+ */
+
+#include <pj/compat/limits.h>
+
+/** Maximum value for signed 32-bit integer. */
+#define PJ_MAXINT32 0x7fffffff
+
+/** Minimum value for signed 32-bit integer. */
+#define PJ_MININT32 0x80000000
+
+/** Maximum value for unsigned 16-bit integer. */
+#define PJ_MAXUINT16 0xffff
+
+/** Maximum value for unsigned char. */
+#define PJ_MAXUINT8 0xff
+
+/** Maximum value for long. */
+#define PJ_MAXLONG LONG_MAX
+
+/** Minimum value for long. */
+#define PJ_MINLONG LONG_MIN
+
+/** Minimum value for unsigned long. */
+#define PJ_MAXULONG ULONG_MAX
+
+#endif /* __PJ_LIMITS_H__ */
diff -uprN pjproject-2.6-a/pjlib/include/pj/string.h pjproject-2.6-b/pjlib/include/pj/string.h
--- pjproject-2.6-a/pjlib/include/pj/string.h 2017-01-10 21:38:29.000000000 -0700
+++ pjproject-2.6-b/pjlib/include/pj/string.h 2017-11-08 06:54:01.532232969 -0700
@@ -28,7 +28,6 @@
#include <pj/types.h>
#include <pj/compat/string.h>
-
PJ_BEGIN_DECL
/**
@@ -636,6 +635,29 @@ PJ_DECL(char*) pj_create_random_string(c
PJ_DECL(long) pj_strtol(const pj_str_t *str);
/**
+ * Convert string to signed long integer. The conversion will stop as
+ * soon as non-digit character is found or all the characters have
+ * been processed.
+ *
+ * @param str the string.
+ * @param value Pointer to a long to receive the value.
+ *
+ * @return PJ_SUCCESS if successful. Otherwise:
+ * PJ_ETOOSMALL if the value was an impossibly long negative number.
+ * In this case *value will be set to LONG_MIN.
+ * \n
+ * PJ_ETOOBIG if the value was an impossibly long positive number.
+ * In this case, *value will be set to LONG_MAX.
+ * \n
+ * PJ_EINVAL if the input string was NULL, the value pointer was NULL
+ * or the input string could not be parsed at all such as starting with
+ * a character other than a '+', '-' or not in the '0' - '9' range.
+ * In this case, *value will be left untouched.
+ */
+PJ_DECL(pj_status_t) pj_strtol2(const pj_str_t *str, long *value);
+
+
+/**
* Convert string to unsigned integer. The conversion will stop as
* soon as non-digit character is found or all the characters have
* been processed.
@@ -664,6 +686,27 @@ PJ_DECL(unsigned long) pj_strtoul2(const
unsigned base);
/**
+ * Convert string to unsigned long integer. The conversion will stop as
+ * soon as non-digit character is found or all the characters have
+ * been processed.
+ *
+ * @param str The input string.
+ * @param value Pointer to an unsigned long to receive the value.
+ * @param base Number base to use.
+ *
+ * @return PJ_SUCCESS if successful. Otherwise:
+ * PJ_ETOOBIG if the value was an impossibly long positive number.
+ * In this case, *value will be set to ULONG_MAX.
+ * \n
+ * PJ_EINVAL if the input string was NULL, the value pointer was NULL
+ * or the input string could not be parsed at all such as starting
+ * with a character outside the base character range. In this case,
+ * *value will be left untouched.
+ */
+PJ_DECL(pj_status_t) pj_strtoul3(const pj_str_t *str, unsigned long *value,
+ unsigned base);
+
+/**
* Convert string to float.
*
* @param str the string.
@@ -786,7 +829,6 @@ PJ_INLINE(void*) pj_memchr(const void *b
return (void*)memchr((void*)buf, c, size);
}
-
/**
* @}
*/
diff -uprN pjproject-2.6-a/pjlib/include/pj/types.h pjproject-2.6-b/pjlib/include/pj/types.h
--- pjproject-2.6-a/pjlib/include/pj/types.h 2014-01-15 22:30:46.000000000 -0700
+++ pjproject-2.6-b/pjlib/include/pj/types.h 2017-11-08 06:54:01.532232969 -0700
@@ -280,9 +280,6 @@ typedef int pj_exception_id_t;
/** Utility macro to compute the number of elements in static array. */
#define PJ_ARRAY_SIZE(a) (sizeof(a)/sizeof(a[0]))
-/** Maximum value for signed 32-bit integer. */
-#define PJ_MAXINT32 0x7FFFFFFFL
-
/**
* Length of object names.
*/
diff -uprN pjproject-2.6-a/pjlib/src/pj/string.c pjproject-2.6-b/pjlib/src/pj/string.c
--- pjproject-2.6-a/pjlib/src/pj/string.c 2017-01-10 21:38:29.000000000 -0700
+++ pjproject-2.6-b/pjlib/src/pj/string.c 2017-11-08 06:54:01.532232969 -0700
@@ -23,11 +23,14 @@
#include <pj/ctype.h>
#include <pj/rand.h>
#include <pj/os.h>
+#include <pj/errno.h>
+#include <pj/limits.h>
#if PJ_FUNCTIONS_ARE_INLINED==0
# include <pj/string_i.h>
#endif
+
PJ_DEF(pj_ssize_t) pj_strspn(const pj_str_t *str, const pj_str_t *set_char)
{
pj_ssize_t i, j, count = 0;
@@ -230,6 +233,55 @@ PJ_DEF(long) pj_strtol(const pj_str_t *s
return pj_strtoul(str);
}
+
+PJ_DEF(pj_status_t) pj_strtol2(const pj_str_t *str, long *value)
+{
+ pj_str_t s;
+ unsigned long retval = 0;
+ pj_bool_t is_negative = PJ_FALSE;
+ int rc = 0;
+
+ PJ_CHECK_STACK();
+
+ if (!str || !value) {
+ return PJ_EINVAL;
+ }
+
+ s = *str;
+ pj_strltrim(&s);
+
+ if (s.slen == 0)
+ return PJ_EINVAL;
+
+ if (s.ptr[0] == '+' || s.ptr[0] == '-') {
+ is_negative = (s.ptr[0] == '-');
+ s.ptr += 1;
+ s.slen -= 1;
+ }
+
+ rc = pj_strtoul3(&s, &retval, 10);
+ if (rc == PJ_EINVAL) {
+ return rc;
+ } else if (rc != PJ_SUCCESS) {
+ *value = is_negative ? PJ_MINLONG : PJ_MAXLONG;
+ return is_negative ? PJ_ETOOSMALL : PJ_ETOOBIG;
+ }
+
+ if (retval > PJ_MAXLONG && !is_negative) {
+ *value = PJ_MAXLONG;
+ return PJ_ETOOBIG;
+ }
+
+ if (retval > (PJ_MAXLONG + 1UL) && is_negative) {
+ *value = PJ_MINLONG;
+ return PJ_ETOOSMALL;
+ }
+
+ *value = is_negative ? -(long)retval : retval;
+
+ return PJ_SUCCESS;
+}
+
PJ_DEF(unsigned long) pj_strtoul(const pj_str_t *str)
{
unsigned long value;
@@ -282,6 +334,71 @@ PJ_DEF(unsigned long) pj_strtoul2(const
return value;
}
+PJ_DEF(pj_status_t) pj_strtoul3(const pj_str_t *str, unsigned long *value,
+ unsigned base)
+{
+ pj_str_t s;
+ unsigned i;
+
+ PJ_CHECK_STACK();
+
+ if (!str || !value) {
+ return PJ_EINVAL;
+ }
+
+ s = *str;
+ pj_strltrim(&s);
+
+ if (s.slen == 0 || s.ptr[0] < '0' ||
+ (base <= 10 && (unsigned)s.ptr[0] > ('0' - 1) + base) ||
+ (base == 16 && !pj_isxdigit(s.ptr[0])))
+ {
+ return PJ_EINVAL;
+ }
+
+ *value = 0;
+ if (base <= 10) {
+ for (i=0; i<(unsigned)s.slen; ++i) {
+ unsigned c = s.ptr[i] - '0';
+ if (s.ptr[i] < '0' || (unsigned)s.ptr[i] > ('0' - 1) + base) {
+ break;
+ }
+ if (*value > PJ_MAXULONG / base) {
+ *value = PJ_MAXULONG;
+ return PJ_ETOOBIG;
+ }
+
+ *value *= base;
+ if ((PJ_MAXULONG - *value) < c) {
+ *value = PJ_MAXULONG;
+ return PJ_ETOOBIG;
+ }
+ *value += c;
+ }
+ } else if (base == 16) {
+ for (i=0; i<(unsigned)s.slen; ++i) {
+ unsigned c = pj_hex_digit_to_val(s.ptr[i]);
+ if (!pj_isxdigit(s.ptr[i]))
+ break;
+
+ if (*value > PJ_MAXULONG / base) {
+ *value = PJ_MAXULONG;
+ return PJ_ETOOBIG;
+ }
+ *value *= base;
+ if ((PJ_MAXULONG - *value) < c) {
+ *value = PJ_MAXULONG;
+ return PJ_ETOOBIG;
+ }
+ *value += c;
+ }
+ } else {
+ pj_assert(!"Unsupported base");
+ return PJ_EINVAL;
+ }
+ return PJ_SUCCESS;
+}
+
PJ_DEF(float) pj_strtof(const pj_str_t *str)
{
pj_str_t part;
@@ -356,5 +473,3 @@ PJ_DEF(int) pj_utoa_pad( unsigned long v
return len;
}
-
-
diff -uprN pjproject-2.6-a/pjlib/src/pj/timer.c pjproject-2.6-b/pjlib/src/pj/timer.c
--- pjproject-2.6-a/pjlib/src/pj/timer.c 2014-06-04 03:23:10.000000000 -0600
+++ pjproject-2.6-b/pjlib/src/pj/timer.c 2017-11-08 06:54:01.533232988 -0700
@@ -36,6 +36,7 @@
#include <pj/lock.h>
#include <pj/log.h>
#include <pj/rand.h>
+#include <pj/limits.h>
#define THIS_FILE "timer.c"
diff -uprN pjproject-2.6-a/pjsip/include/pjsip/sip_parser.h pjproject-2.6-b/pjsip/include/pjsip/sip_parser.h
--- pjproject-2.6-a/pjsip/include/pjsip/sip_parser.h 2013-03-20 05:29:08.000000000 -0600
+++ pjproject-2.6-b/pjsip/include/pjsip/sip_parser.h 2017-11-08 06:54:01.533232988 -0700
@@ -39,6 +39,26 @@ PJ_BEGIN_DECL
*/
/**
+ * Contants for limit checks
+ */
+#define PJSIP_MIN_CONTENT_LENGTH 0
+#define PJSIP_MAX_CONTENT_LENGTH PJ_MAXINT32
+#define PJSIP_MIN_PORT 0
+#define PJSIP_MAX_PORT PJ_MAXUINT16
+#define PJSIP_MIN_TTL 0
+#define PJSIP_MAX_TTL PJ_MAXUINT8
+#define PJSIP_MIN_STATUS_CODE 100
+#define PJSIP_MAX_STATUS_CODE 999
+#define PJSIP_MIN_Q1000 0
+#define PJSIP_MAX_Q1000 PJ_MAXINT32 / 1000
+#define PJSIP_MIN_EXPIRES 0
+#define PJSIP_MAX_EXPIRES PJ_MAXINT32
+#define PJSIP_MIN_CSEQ 0
+#define PJSIP_MAX_CSEQ PJ_MAXINT32
+#define PJSIP_MIN_RETRY_AFTER 0
+#define PJSIP_MAX_RETRY_AFTER PJ_MAXINT32
+
+/**
* URI Parsing options.
*/
enum
@@ -64,6 +84,11 @@ enum
extern int PJSIP_SYN_ERR_EXCEPTION;
/**
+ * Invalid value error exception value.
+ */
+extern int PJSIP_EINVAL_ERR_EXCEPTION;
+
+/**
* This structure is used to get error reporting from parser.
*/
typedef struct pjsip_parser_err_report
diff -uprN pjproject-2.6-a/pjsip/src/pjsip/sip_parser.c pjproject-2.6-b/pjsip/src/pjsip/sip_parser.c
--- pjproject-2.6-a/pjsip/src/pjsip/sip_parser.c 2016-04-19 19:58:15.000000000 -0600
+++ pjproject-2.6-b/pjsip/src/pjsip/sip_parser.c 2017-11-08 06:54:01.533232988 -0700
@@ -34,6 +34,7 @@
#include <pj/string.h>
#include <pj/ctype.h>
#include <pj/assert.h>
+#include <pj/limits.h>
#define THIS_FILE "sip_parser.c"
@@ -93,6 +94,7 @@ static unsigned uri_handler_count;
* Global vars (also extern).
*/
int PJSIP_SYN_ERR_EXCEPTION = -1;
+int PJSIP_EINVAL_ERR_EXCEPTION = -2;
/* Parser constants */
static pjsip_parser_const_t pconst =
@@ -205,7 +207,6 @@ static unsigned long pj_strtoul_mindigit
/* Case insensitive comparison */
#define parser_stricmp(s1, s2) (s1.slen!=s2.slen || pj_stricmp_alnum(&s1, &s2))
-
/* Get a token and unescape */
PJ_INLINE(void) parser_get_and_unescape(pj_scanner *scanner, pj_pool_t *pool,
const pj_cis_t *spec,
@@ -223,8 +224,6 @@ PJ_INLINE(void) parser_get_and_unescape(
#endif
}
-
-
/* Syntax error handler for parser. */
static void on_syntax_error(pj_scanner *scanner)
{
@@ -232,6 +231,60 @@ static void on_syntax_error(pj_scanner *
PJ_THROW(PJSIP_SYN_ERR_EXCEPTION);
}
+/* Syntax error handler for parser. */
+static void on_str_parse_error(const pj_str_t *str, int rc)
+{
+ char *s;
+
+ switch(rc) {
+ case PJ_EINVAL:
+ s = "NULL input string, invalid input string, or NULL return "\
+ "value pointer";
+ break;
+ case PJ_ETOOSMALL:
+ s = "String value was less than the minimum allowed value.";
+ break;
+ case PJ_ETOOBIG:
+ s = "String value was greater than the maximum allowed value.";
+ break;
+ default:
+ s = "Unknown error";
+ }
+
+ if (str) {
+ PJ_LOG(1, (THIS_FILE, "Error parsing '%.*s': %s",
+ (int)str->slen, str->ptr, s));
+ } else {
+ PJ_LOG(1, (THIS_FILE, "Can't parse input string: %s", s));
+ }
+ PJ_THROW(PJSIP_EINVAL_ERR_EXCEPTION);
+}
+
+static void strtoi_validate(const pj_str_t *str, int min_val,
+ int max_val, int *value)
+{
+ long retval;
+ pj_status_t status;
+
+ if (!str || !value) {
+ on_str_parse_error(str, PJ_EINVAL);
+ }
+ status = pj_strtol2(str, &retval);
+ if (status != PJ_EINVAL) {
+ if (min_val > retval) {
+ *value = min_val;
+ status = PJ_ETOOSMALL;
+ } else if (retval > max_val) {
+ *value = max_val;
+ status = PJ_ETOOBIG;
+ } else
+ *value = (int)retval;
+ }
+
+ if (status != PJ_SUCCESS)
+ on_str_parse_error(str, status);
+}
+
/* Get parser constants. */
PJ_DEF(const pjsip_parser_const_t*) pjsip_parser_const(void)
{
@@ -285,6 +338,14 @@ static pj_status_t init_parser()
PJ_ASSERT_RETURN(status == PJ_SUCCESS, status);
/*
+ * Invalid value exception.
+ */
+ pj_assert (PJSIP_EINVAL_ERR_EXCEPTION == -2);
+ status = pj_exception_id_alloc("PJSIP invalid value error",
+ &PJSIP_EINVAL_ERR_EXCEPTION);
+ PJ_ASSERT_RETURN(status == PJ_SUCCESS, status);
+
+ /*
* Init character input spec (cis)
*/
@@ -502,6 +563,9 @@ void deinit_sip_parser(void)
/* Deregister exception ID */
pj_exception_id_free(PJSIP_SYN_ERR_EXCEPTION);
PJSIP_SYN_ERR_EXCEPTION = -1;
+
+ pj_exception_id_free(PJSIP_EINVAL_ERR_EXCEPTION);
+ PJSIP_EINVAL_ERR_EXCEPTION = -2;
}
pj_leave_critical_section();
}
@@ -766,7 +830,7 @@ PJ_DEF(pjsip_msg *) pjsip_parse_rdata( c
}
/* Determine if a message has been received. */
-PJ_DEF(pj_bool_t) pjsip_find_msg( const char *buf, pj_size_t size,
+PJ_DEF(pj_status_t) pjsip_find_msg( const char *buf, pj_size_t size,
pj_bool_t is_datagram, pj_size_t *msg_size)
{
#if PJ_HAS_TCP
@@ -776,6 +840,7 @@ PJ_DEF(pj_bool_t) pjsip_find_msg( const
const char *line;
int content_length = -1;
pj_str_t cur_msg;
+ pj_status_t status = PJ_SUCCESS;
const pj_str_t end_hdr = { "\n\r\n", 3};
*msg_size = size;
@@ -836,9 +901,16 @@ PJ_DEF(pj_bool_t) pjsip_find_msg( const
pj_scan_get_newline(&scanner);
/* Found a valid Content-Length header. */
- content_length = pj_strtoul(&str_clen);
+ strtoi_validate(&str_clen, PJSIP_MIN_CONTENT_LENGTH,
+ PJSIP_MAX_CONTENT_LENGTH, &content_length);
}
PJ_CATCH_ANY {
+ int eid = PJ_GET_EXCEPTION();
+ if (eid == PJSIP_SYN_ERR_EXCEPTION) {
+ status = PJSIP_EMISSINGHDR;
+ } else if (eid == PJSIP_EINVAL_ERR_EXCEPTION) {
+ status = PJSIP_EINVALIDHDR;
+ }
content_length = -1;
}
PJ_END
@@ -858,7 +930,7 @@ PJ_DEF(pj_bool_t) pjsip_find_msg( const
/* Found Content-Length? */
if (content_length == -1) {
- return PJSIP_EMISSINGHDR;
+ return status;
}
/* Enough packet received? */
@@ -938,10 +1010,14 @@ static pj_bool_t is_next_sip_version(pj_
static pjsip_msg *int_parse_msg( pjsip_parse_ctx *ctx,
pjsip_parser_err_report *err_list)
{
- pj_bool_t parsing_headers;
- pjsip_msg *msg = NULL;
+ /* These variables require "volatile" so their values get
+ * preserved when re-entering the PJ_TRY block after an error.
+ */
+ volatile pj_bool_t parsing_headers;
+ pjsip_msg *volatile msg = NULL;
+ pjsip_ctype_hdr *volatile ctype_hdr = NULL;
+
pj_str_t hname;
- pjsip_ctype_hdr *ctype_hdr = NULL;
pj_scanner *scanner = ctx->scanner;
pj_pool_t *pool = ctx->pool;
PJ_USE_EXCEPTION;
@@ -1023,7 +1099,6 @@ parse_headers:
hdr->name = hdr->sname = hname;
}
-
/* Single parse of header line can produce multiple headers.
* For example, if one Contact: header contains Contact list
* separated by comma, then these Contacts will be split into
@@ -1267,7 +1342,7 @@ static void int_parse_uri_host_port( pj_
pj_str_t port;
pj_scan_get_char(scanner);
pj_scan_get(scanner, &pconst.pjsip_DIGIT_SPEC, &port);
- *p_port = pj_strtoul(&port);
+ strtoi_validate(&port, PJSIP_MIN_PORT, PJSIP_MAX_PORT, p_port);
} else {
*p_port = 0;
}
@@ -1458,8 +1533,8 @@ static void* int_parse_sip_url( pj_scann
url->transport_param = pvalue;
} else if (!parser_stricmp(pname, pconst.pjsip_TTL_STR) && pvalue.slen) {
- url->ttl_param = pj_strtoul(&pvalue);
-
+ strtoi_validate(&pvalue, PJSIP_MIN_TTL, PJSIP_MAX_TTL,
+ &url->ttl_param);
} else if (!parser_stricmp(pname, pconst.pjsip_MADDR_STR) && pvalue.slen) {
url->maddr_param = pvalue;
@@ -1595,7 +1670,8 @@ static void int_parse_status_line( pj_sc
parse_sip_version(scanner);
pj_scan_get( scanner, &pconst.pjsip_DIGIT_SPEC, &token);
- status_line->code = pj_strtoul(&token);
+ strtoi_validate(&token, PJSIP_MIN_STATUS_CODE, PJSIP_MAX_STATUS_CODE,
+ &status_line->code);
if (*scanner->curptr != '\r' && *scanner->curptr != '\n')
pj_scan_get( scanner, &pconst.pjsip_NOT_NEWLINE, &status_line->reason);
else
@@ -1780,20 +1856,34 @@ static void int_parse_contact_param( pjs
if (!parser_stricmp(pname, pconst.pjsip_Q_STR) && pvalue.slen) {
char *dot_pos = (char*) pj_memchr(pvalue.ptr, '.', pvalue.slen);
if (!dot_pos) {
- hdr->q1000 = pj_strtoul(&pvalue) * 1000;
+ strtoi_validate(&pvalue, PJSIP_MIN_Q1000, PJSIP_MAX_Q1000,
+ &hdr->q1000);
+ hdr->q1000 *= 1000;
} else {
pj_str_t tmp = pvalue;
+ unsigned long qval_frac;
tmp.slen = dot_pos - pvalue.ptr;
- hdr->q1000 = pj_strtoul(&tmp) * 1000;
+ strtoi_validate(&tmp, PJSIP_MIN_Q1000, PJSIP_MAX_Q1000,
+ &hdr->q1000);
+ hdr->q1000 *= 1000;
pvalue.slen = (pvalue.ptr+pvalue.slen) - (dot_pos+1);
pvalue.ptr = dot_pos + 1;
- hdr->q1000 += pj_strtoul_mindigit(&pvalue, 3);
+ if (pvalue.slen > 3) {
+ pvalue.slen = 3;
+ }
+ qval_frac = pj_strtoul_mindigit(&pvalue, 3);
+ if ((unsigned)hdr->q1000 > (PJ_MAXINT32 - qval_frac)) {
+ PJ_THROW(PJSIP_SYN_ERR_EXCEPTION);
+ }
+ hdr->q1000 += qval_frac;
}
- } else if (!parser_stricmp(pname, pconst.pjsip_EXPIRES_STR) && pvalue.slen) {
- hdr->expires = pj_strtoul(&pvalue);
-
+ } else if (!parser_stricmp(pname, pconst.pjsip_EXPIRES_STR) &&
+ pvalue.slen)
+ {
+ strtoi_validate(&pvalue, PJSIP_MIN_EXPIRES, PJSIP_MAX_EXPIRES,
+ &hdr->expires);
} else {
pjsip_param *p = PJ_POOL_ALLOC_T(pool, pjsip_param);
p->name = pname;
@@ -1890,19 +1980,22 @@ static pjsip_hdr* parse_hdr_content_type
static pjsip_hdr* parse_hdr_cseq( pjsip_parse_ctx *ctx )
{
pj_str_t cseq, method;
- pjsip_cseq_hdr *hdr;
+ pjsip_cseq_hdr *hdr = NULL;
+ int cseq_val = 0;
- hdr = pjsip_cseq_hdr_create(ctx->pool);
pj_scan_get( ctx->scanner, &pconst.pjsip_DIGIT_SPEC, &cseq);
- hdr->cseq = pj_strtoul(&cseq);
+ strtoi_validate(&cseq, PJSIP_MIN_CSEQ, PJSIP_MAX_CSEQ, &cseq_val);
- pj_scan_get( ctx->scanner, &pconst.pjsip_TOKEN_SPEC, &method);
- pjsip_method_init_np(&hdr->method, &method);
+ hdr = pjsip_cseq_hdr_create(ctx->pool);
+ hdr->cseq = cseq_val;
+ pj_scan_get( ctx->scanner, &pconst.pjsip_TOKEN_SPEC, &method);
parse_hdr_end( ctx->scanner );
- if (ctx->rdata)
+ pjsip_method_init_np(&hdr->method, &method);
+ if (ctx->rdata) {
ctx->rdata->msg_info.cseq = hdr;
+ }
return (pjsip_hdr*)hdr;
}
@@ -1984,7 +2077,8 @@ static pjsip_hdr* parse_hdr_retry_after(
hdr = pjsip_retry_after_hdr_create(ctx->pool, 0);
pj_scan_get(scanner, &pconst.pjsip_DIGIT_SPEC, &tmp);
- hdr->ivalue = pj_strtoul(&tmp);
+ strtoi_validate(&tmp, PJSIP_MIN_RETRY_AFTER, PJSIP_MAX_RETRY_AFTER,
+ &hdr->ivalue);
while (!pj_scan_is_eof(scanner) && *scanner->curptr!='\r' &&
*scanner->curptr!='\n')
@@ -2073,7 +2167,8 @@ static void int_parse_via_param( pjsip_v
hdr->branch_param = pvalue;
} else if (!parser_stricmp(pname, pconst.pjsip_TTL_STR) && pvalue.slen) {
- hdr->ttl_param = pj_strtoul(&pvalue);
+ strtoi_validate(&pvalue, PJSIP_MIN_TTL, PJSIP_MAX_TTL,
+ &hdr->ttl_param);
} else if (!parser_stricmp(pname, pconst.pjsip_MADDR_STR) && pvalue.slen) {
hdr->maddr_param = pvalue;
@@ -2082,9 +2177,10 @@ static void int_parse_via_param( pjsip_v
hdr->recvd_param = pvalue;
} else if (!parser_stricmp(pname, pconst.pjsip_RPORT_STR)) {
- if (pvalue.slen)
- hdr->rport_param = pj_strtoul(&pvalue);
- else
+ if (pvalue.slen) {
+ strtoi_validate(&pvalue, PJSIP_MIN_PORT, PJSIP_MAX_PORT,
+ &hdr->rport_param);
+ } else
hdr->rport_param = 0;
} else {
pjsip_param *p = PJ_POOL_ALLOC_T(pool, pjsip_param);
@@ -2213,7 +2309,8 @@ static pjsip_hdr* parse_hdr_via( pjsip_p
pj_str_t digit;
pj_scan_get_char(scanner);
pj_scan_get(scanner, &pconst.pjsip_DIGIT_SPEC, &digit);
- hdr->sent_by.port = pj_strtoul(&digit);
+ strtoi_validate(&digit, PJSIP_MIN_PORT, PJSIP_MAX_PORT,
+ &hdr->sent_by.port);
}
int_parse_via_param(hdr, scanner, ctx->pool);
@@ -2298,9 +2395,10 @@ PJ_DEF(pj_status_t) pjsip_parse_headers(
unsigned options)
{
enum { STOP_ON_ERROR = 1 };
+ pj_str_t hname;
pj_scanner scanner;
pjsip_parse_ctx ctx;
- pj_str_t hname;
+
PJ_USE_EXCEPTION;
pj_scan_init(&scanner, input, size, PJ_SCAN_AUTOSKIP_WS_HEADER,
@@ -2323,7 +2421,7 @@ retry_parse:
*/
hname.slen = 0;
- /* Get hname. */
+ /* Get hname. */
pj_scan_get( &scanner, &pconst.pjsip_TOKEN_SPEC, &hname);
if (pj_scan_get_char( &scanner ) != ':') {
PJ_THROW(PJSIP_SYN_ERR_EXCEPTION);
diff -uprN pjproject-2.6-a/pjsip/src/pjsip/sip_transaction.c pjproject-2.6-b/pjsip/src/pjsip/sip_transaction.c
--- pjproject-2.6-a/pjsip/src/pjsip/sip_transaction.c 2017-11-08 06:49:48.436246594 -0700
+++ pjproject-2.6-b/pjsip/src/pjsip/sip_transaction.c 2017-11-08 06:54:11.101421471 -0700
@@ -288,12 +288,12 @@ static pj_status_t create_tsx_key_2543(
host = &rdata->msg_info.via->sent_by.host;
/* Calculate length required. */
- len_required = method->name.slen + /* Method */
- 9 + /* CSeq number */
+ len_required = method->name.slen + /* Method */
+ 11 + /* CSeq number */
rdata->msg_info.from->tag.slen + /* From tag. */
rdata->msg_info.cid->id.slen + /* Call-ID */
host->slen + /* Via host. */
- 9 + /* Via port. */
+ 11 + /* Via port. */
16; /* Separator+Allowance. */
key = p = (char*) pj_pool_alloc(pool, len_required);
@@ -3396,4 +3396,3 @@ static pj_status_t tsx_on_state_destroye
return PJ_EIGNORED;
}
-
diff -uprN pjproject-2.6-a/pjsip/src/pjsip/sip_transport.c pjproject-2.6-b/pjsip/src/pjsip/sip_transport.c
--- pjproject-2.6-a/pjsip/src/pjsip/sip_transport.c 2017-11-08 06:49:48.425246377 -0700
+++ pjproject-2.6-b/pjsip/src/pjsip/sip_transport.c 2017-11-08 06:54:01.534233008 -0700
@@ -1836,7 +1836,7 @@ PJ_DEF(pj_ssize_t) pjsip_tpmgr_receive_p
/* Check for parsing syntax error */
if (msg==NULL || !pj_list_empty(&rdata->msg_info.parse_err)) {
pjsip_parser_err_report *err;
- char buf[128];
+ char buf[256];
pj_str_t tmp;
/* Gather syntax error information */
@@ -1850,7 +1850,10 @@ PJ_DEF(pj_ssize_t) pjsip_tpmgr_receive_p
pj_exception_id_name(err->except_code),
(int)err->hname.slen, err->hname.ptr,
err->line, err->col);
- if (len > 0 && len < (int) (sizeof(buf)-tmp.slen)) {
+ if (len >= (int)sizeof(buf)-tmp.slen) {
+ len = (int)sizeof(buf)-tmp.slen;
+ }
+ if (len > 0) {
tmp.slen += len;
}
err = err->next;