Skip to content

Commit 2d6994a

Browse files
author
Maria Farooq
committed
Merge branch 'master' into restcomm-1995
* master: Added extra log statements around the check of client Authorization header Updated External project version DigestAuthentication unit test Fixes for 8.4.0 release notes. This close RESTCOMM-2054 Patch for race condition when SBC is enabled, where the Cancel from one of the forking branches will cause the initial call state to be marked as Canceled and thus the Bye wont be send at the end of the call. This refer to RESTCOMM-1932 added release notes log,and link to main page
2 parents 0d63244 + 03bd67a commit 2d6994a

6 files changed

Lines changed: 163 additions & 1 deletion

File tree

restcomm/restcomm.commons/src/main/java/org/restcomm/connect/commons/util/DigestAuthentication.java

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -144,4 +144,12 @@ public static String HA1(String username, String realm, String password){
144144
ha1 = DigestAuthentication.H(username+":"+realm+":"+password, algorithm);
145145
return ha1;
146146
}
147+
148+
149+
//USed for unit testing
150+
public static String HA1(String username, String realm, String password, String algorithm){
151+
String ha1 = "";
152+
ha1 = DigestAuthentication.H(username+":"+realm+":"+password, algorithm);
153+
return ha1;
154+
}
147155
}
Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
/*
2+
* TeleStax, Open Source Cloud Communications
3+
* Copyright 2011-2018, Telestax Inc and individual contributors
4+
* by the @authors tag.
5+
*
6+
* This program is free software: you can redistribute it and/or modify
7+
* under the terms of the GNU Affero General Public License as
8+
* published by the Free Software Foundation; either version 3 of
9+
* the License, or (at your option) any later version.
10+
*
11+
* This program is distributed in the hope that it will be useful,
12+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
13+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14+
* GNU Affero General Public License for more details.
15+
*
16+
* You should have received a copy of the GNU Affero General Public License
17+
* along with this program. If not, see <http://www.gnu.org/licenses/>
18+
*/
19+
20+
package org.restcomm.connect.commons;
21+
22+
import org.junit.Test;
23+
import org.restcomm.connect.commons.dao.Sid;
24+
import org.restcomm.connect.commons.util.DigestAuthentication;
25+
26+
import java.util.HashMap;
27+
import java.util.Map;
28+
29+
import static org.junit.Assert.assertTrue;
30+
31+
public class DigestAuthenticationTest {
32+
33+
private String client = "alice0000000";
34+
private String domain = "org0000000.restcomm.com";
35+
private String password = "1234";
36+
private String proxyAuthHeader = "Digest username=\"alice0000000\"," +
37+
"realm=\"org0000000.restcomm.com\"," +
38+
"cnonce=\"6b8b4567\"," +
39+
"nc=00000001," +
40+
"qop=auth,uri=\"sip:172.31.44.214:5080\"," +
41+
"nonce=\"39656532346436332d633335612d346\"," +
42+
"response=\"00e135e06e2474d1d0318fb66a2bc473\"," +
43+
"algorithm=MD5\n";
44+
45+
@Test
46+
public void testAuth(){
47+
String hashedPass = DigestAuthentication.HA1(client, domain, password, "MD5");
48+
49+
assertTrue(permitted(proxyAuthHeader, "INVITE", hashedPass));
50+
51+
}
52+
53+
static boolean permitted(final String authorization, final String method, String clientPassword) {
54+
final Map<String, String> map = authHeaderToMap(authorization);
55+
String user = map.get("username");
56+
final String algorithm = map.get("algorithm");
57+
final String realm = map.get("realm");
58+
final String uri = map.get("uri");
59+
final String nonce = map.get("nonce");
60+
final String nc = map.get("nc");
61+
final String cnonce = map.get("cnonce");
62+
final String qop = map.get("qop");
63+
final String response = map.get("response");
64+
final String password2 = clientPassword;
65+
final String result = DigestAuthentication.response(algorithm, user, realm, "", password2, nonce, nc, cnonce,
66+
method, uri, null, qop);
67+
return result.equals(response);
68+
}
69+
70+
private static Map<String, String> authHeaderToMap(final String header) {
71+
final Map<String, String> map = new HashMap<String, String>();
72+
final int endOfScheme = header.indexOf(" ");
73+
map.put("scheme", header.substring(0, endOfScheme).trim());
74+
final String[] tokens = header.substring(endOfScheme + 1).split(",");
75+
for (final String token : tokens) {
76+
final String[] values = token.trim().split("=",2); //Issue #935, split only for first occurrence of "="
77+
map.put(values[0].toLowerCase(), values[1].replace("\"", ""));
78+
}
79+
80+
return map;
81+
}
82+
83+
}

restcomm/restcomm.docs/sources-asciidoc/src/main/asciidoc/index.adoc

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,3 +21,6 @@ There is multiple ways to interact with Restcomm Connect to build applications
2121
* The <<tutorials/index.adoc#tutorials,Restcomm Tutorials>> will help you in creating sample applications that cover common use cases in a variety of languages using the Restcomm API, RCML or Visual Designer. Download, test, and tweak for yourself.
2222
2323
* The <<configuration/index.adoc#Configuration,Configuration>> will help you in setting up Restcomm Connect on your own server or development environment to build powerful apps locally.
24+
25+
26+
Find <<release-notes.adoc#Release Notes,Release Notes>> here
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
= Restcomm-Connect Release Notes
2+
3+
These notes group both Community and Telscale changes in a single document.
4+
5+
=== Tags
6+
7+
The folowing tags are used to categorize and state the scope of a change
8+
9+
* **security improvement** tags changes related to security
10+
* **commercial** tags changes that are available only in the commercial RestcommOne product
11+
12+
13+
//add release-notes with newer on top
14+
== 8.4.0 version
15+
=== New Features
16+
// New features (whether major or minor) go here
17+
* Clients passwords are now hashed in DB - **security improvement**
18+
* Profiles allow arbitrary properties to be saved/retrieved.
19+
* Added configurable SBC mode which if enabled will disable all NAT handling operations
20+
21+
=== Breaking Changes
22+
// draws attention to functionality that is getting removed
23+
* Accessing Olympus WebRTC from Console now requires to login again. This because of the new feature to hash passwords
24+
* Removed default clients `alice` and `bob`
25+
26+
=== Bug Fixes
27+
// any difference in functionality
28+
* Dial Timeout does not cancel task when Callee is busy
29+
* Configurable inbound/outbound SMPP encoding
30+
* Race condition on sending BYE to incoming call for a dial fork scenario
31+
* Fixed SDR event for SMS - **commercial**
32+
33+
34+
=== Migration Notes
35+
// Things to consider during migration from previous release
36+
* Clients password are considered to be MD5 hashed in DB. Database migration
37+
scripts are available in **commercial** version. Database migration script will ensure existing clients passwords are properly migrated.
38+
39+
=== External Dependencies Updates
40+
// any dependencies
41+
* Console updated to version **__8.4.0__**
42+
** Integrated Feature Access Control (FAC) limitations
43+
** Updated Console Look & Feel to match new Restcomm branding
44+
** Implemented new Sign In page in Console
45+
** Use Designer location in Console from configuration file
46+
* Designer updated to version **__1.2.0-131__**
47+
** Integrated Feature Access Control (FAC) limitations
48+
** Improved Designer performance with better xstream usage
49+
** Designer Look & Feel to match new Restcomm branding
50+
* Olympus WebRTC Demo updated to version **__1.1.0-167__**
51+
** Fixed an issue in WebRTC Demo jain-sip library, parsing some headers
52+
** Improve WebRTC Demo UX by showing incoming call screen on top even if caller is not the selected contact
53+
** Add additional configuration to WebRTC Demo for specifying client-specific parameters
54+
** Improve WebRTC Xirsys integration by checking for actual success response and using domain property as namespace (now required)

restcomm/restcomm.interpreter/src/main/java/org/restcomm/connect/interpreter/VoiceInterpreter.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1244,7 +1244,7 @@ private void onCallStateChanged(Object message, ActorRef sender) throws Transiti
12441244
case RINGING:
12451245
break;
12461246
case CANCELED:
1247-
if (is(initializingBridge) || is(acquiringOutboundCallInfo) || is(bridging) || is(bridged)) {
1247+
if (is(creatingBridge) || is(initializingBridge) || is(acquiringOutboundCallInfo) || is(bridging) || is(bridged)) {
12481248
//This is a canceled branch from a previous forking call. We need to destroy the branch
12491249
// removeDialBranch(message, sender);
12501250
callManager.tell(new DestroyCall(sender), self());

restcomm/restcomm.telephony.api/src/main/java/org/restcomm/connect/telephony/api/util/CallControlHelper.java

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131
import javax.servlet.sip.SipServletResponse;
3232
import javax.servlet.sip.SipURI;
3333

34+
import org.apache.log4j.Logger;
3435
import org.restcomm.connect.dao.ClientsDao;
3536
import org.restcomm.connect.dao.DaoManager;
3637
import org.restcomm.connect.dao.entities.Client;
@@ -47,6 +48,7 @@
4748
*
4849
*/
4950
public class CallControlHelper {
51+
private static Logger logger = Logger.getLogger(CallControlHelper.class);
5052

5153
static boolean permitted(final String authorization, final String method, DaoManager daoManager, final Sid organizationSid) {
5254
final Map<String, String> map = authHeaderToMap(authorization);
@@ -66,8 +68,16 @@ static boolean permitted(final String authorization, final String method, DaoMan
6668
final String password2 = client.getPassword();
6769
final String result = DigestAuthentication.response(algorithm, user, realm, "", password2, nonce, nc, cnonce,
6870
method, uri, null, qop);
71+
if (logger.isDebugEnabled()) {
72+
String msg = String.format("Provided response [%s], generated response [%s]", response, result);
73+
logger.debug(msg);
74+
}
6975
return result.equals(response);
7076
} else {
77+
if (logger.isDebugEnabled()) {
78+
String msg = String.format("Authorization check failed, [if(client==null) evaluates %s] or [if(client.getStatus()==Client.ENABLED) evaluates %s]", client!=null, Client.ENABLED == client.getStatus());
79+
logger.debug(msg);
80+
}
7181
return false;
7282
}
7383
}
@@ -85,6 +95,10 @@ public static boolean checkAuthentication(SipServletRequest request, DaoManager
8595
final String authorization = request.getHeader("Proxy-Authorization");
8696
final String method = request.getMethod();
8797
if (authorization == null || !CallControlHelper.permitted(authorization, method, storage, organizationSid)) {
98+
if (logger.isDebugEnabled()) {
99+
String msg = String.format("Either authorization header is null [if(authorization==null) evaluates %s], or CallControlHelper.permitted() method failed, will send \"407 Proxy Authentication required\"", authorization==null);
100+
logger.debug(msg);
101+
}
88102
authenticate(request, storage.getOrganizationsDao().getOrganization(organizationSid).getDomainName());
89103
return false;
90104
} else {

0 commit comments

Comments
 (0)