Skip to content

Commit 2febd3f

Browse files
author
Maria Farooq
committed
Merge branch 'master' into restcomm1657
* master: (28 commits) Update on DigestAuthentication unit test update rn wording updated RN wording updated RNs updated release notes updated migration notes reverted unused change Added extra log statements around the check of client Authorization header Updated External project version DigestAuthentication unit test tha patch corected data corrected test data dial DID with proper org test data 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 added ReferOrganizationTest refactored for readability ...
2 parents 5c65cb1 + 335a572 commit 2febd3f

File tree

15 files changed

+1644
-6
lines changed

15 files changed

+1644
-6
lines changed

docker-compose.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -137,4 +137,4 @@ services:
137137
# Uncomment below to enable logs rotation. (Rotate using 3 files 20m each file)
138138
# options:
139139
# max-size: "20m"
140-
# max-file: "3"
140+
# max-file: "3"

restcomm/configuration/config-scripts/as7-config-scripts/restcomm/autoconfig.d/config-restcomm.sh

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -883,7 +883,14 @@ else
883883
fi
884884

885885
if [ -z "$MS_ADDRESS" ]; then
886-
MS_ADDRESS=$BIND_ADDRESS
886+
MS_ADDRESS=$BIND_ADDRESS
887+
fi
888+
889+
if [ "a" == "a$MGCP_LOCAL_ADDRESS" ]; then
890+
# $MGCP_LOCAL_ADDRESS is empty, so just use bind address
891+
MGCP_ADDRESS=$BIND_ADDRESS
892+
else
893+
MGCP_ADDRESS=$MGCP_LOCAL_ADDRESS
887894
fi
888895

889896
configDidProvisionManager "$DID_LOGIN" "$DID_PASSWORD" "$DID_ENDPOINT" "$DID_SITEID" "$HOSTFORDID" "$DID_ACCOUNTID" "$SMPP_SYSTEM_TYPE" "$DID_URIPORT"
@@ -892,7 +899,7 @@ configSmsAggregator "$SMS_OUTBOUND_PROXY" "$SMS_PREFIX"
892899
configSpeechRecognizer "$ISPEECH_KEY"
893900
configSpeechSynthesizers
894901
configTelestaxProxy "$ACTIVE_PROXY" "$TP_LOGIN" "$TP_PASSWORD" "$INSTANCE_ID" "$PROXY_IP" "$SITE_ID"
895-
configMediaServerManager "$BIND_ADDRESS" "$MS_ADDRESS" "$MEDIASERVER_EXTERNAL_ADDRESS"
902+
configMediaServerManager "$MGCP_ADDRESS" "$MS_ADDRESS" "$MEDIASERVER_EXTERNAL_ADDRESS"
896903
configSMPPAccount "$SMPP_ACTIVATE" "$SMPP_SYSTEM_ID" "$SMPP_PASSWORD" "$SMPP_SYSTEM_TYPE" "$SMPP_PEER_IP" "$SMPP_PEER_PORT" "$SMPP_SOURCE_MAP" "$SMPP_DEST_MAP" "$SMPP_INBOUND_ENCODING" "$SMPP_OUTBOUND_ENCODING"
897904
configRestCommURIs
898905
updateRecordingsPath

restcomm/configuration/config-scripts/as7-config-scripts/restcomm/restcomm.conf

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,8 @@ MS_EXTERNAL=false
2424
MS_ADDRESS=''
2525
#Values rms: RestComm Media Server, xms: Dialogic Media Server
2626
MS_COMPATIBILITY_MODE=rms
27+
# The IP address that the MGCP `media-server-manager` is using to contact the Media Server.
28+
MGCP_LOCAL_ADDRESS=''
2729
LOCALMGCP=2727
2830
REMOTEMGCP=2427
2931
MGCP_RESPONSE_TIMEOUT=500
@@ -148,4 +150,4 @@ CONFERENCE_TIMEOUT="14400"
148150
#SDR Service configuration
149151
SDR_SERVICE_CLASS=''
150152
SDR_SERVICE_HTTP_URI=''
151-
SDR_SERVICE_AMQP_URI=''
153+
SDR_SERVICE_AMQP_URI=''

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: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
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.assertEquals;
30+
import static org.junit.Assert.assertTrue;
31+
32+
public class DigestAuthenticationTest {
33+
34+
private String client = "alice0000000";
35+
private String domain = "org0000000.restcomm.com";
36+
private String password = "1234";
37+
private String proxyAuthHeader = "Digest username=\"alice0000000\",realm=\"org0000000.restcomm.com\",cnonce=\"6b8b4567\",nc=00000001,qop=auth,uri=\"sip:172.31.45.30:5080\",nonce=\"61343361383534392d633237372d343\",response=\"bc322276e42a123c53c2ed6f53d5e7c7\",algorithm=MD5";
38+
39+
@Test
40+
public void testAuth(){
41+
String hashedPass = DigestAuthentication.HA1(client, domain, password, "MD5");
42+
43+
assertEquals("9b11a2924d0881aca84f9db97f834d99", hashedPass);
44+
45+
assertTrue(permitted(proxyAuthHeader, "INVITE", hashedPass));
46+
47+
}
48+
49+
static boolean permitted(final String authorization, final String method, String clientPassword) {
50+
final Map<String, String> map = authHeaderToMap(authorization);
51+
String user = map.get("username");
52+
final String algorithm = map.get("algorithm");
53+
final String realm = map.get("realm");
54+
final String uri = map.get("uri");
55+
final String nonce = map.get("nonce");
56+
final String nc = map.get("nc");
57+
final String cnonce = map.get("cnonce");
58+
final String qop = map.get("qop");
59+
final String response = map.get("response");
60+
final String password2 = clientPassword;
61+
final String result = DigestAuthentication.response(algorithm, user, realm, "", password2, nonce, nc, cnonce,
62+
method, uri, null, qop);
63+
return result.equals(response);
64+
}
65+
66+
private static Map<String, String> authHeaderToMap(final String header) {
67+
final Map<String, String> map = new HashMap<String, String>();
68+
final int endOfScheme = header.indexOf(" ");
69+
map.put("scheme", header.substring(0, endOfScheme).trim());
70+
final String[] tokens = header.substring(endOfScheme + 1).split(",");
71+
for (final String token : tokens) {
72+
final String[] values = token.trim().split("=",2); //Issue #935, split only for first occurrence of "="
73+
map.put(values[0].toLowerCase(), values[1].replace("\"", ""));
74+
}
75+
76+
return map;
77+
}
78+
79+
}

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: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
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+
* Fixed REFER (Call Transfer) support to work with organizations
33+
34+
35+
=== Migration Notes
36+
// Things to consider during migration from previous release
37+
* Clients password are considered to be MD5 hashed in DB. Database migration
38+
scripts are available in **commercial** version. Database migration script will ensure existing clients passwords are properly migrated.
39+
** Database migration script will automatically take a backup of complete database before making any changes
40+
** Please take a backup of restcomm clients table (to be used in case we need to rollback as explained below)
41+
** In case of rollback to older version, kindly restore restcomm clients table only.
42+
43+
=== External Dependencies Updates
44+
// any dependencies
45+
* Console updated to version **__8.4.0__**
46+
** Integrated Feature Access Control (FAC) limitations
47+
** Updated Console Look & Feel to match new Restcomm branding
48+
** Implemented new Sign In page in Console
49+
** Use Designer location in Console from configuration file
50+
* Designer updated to version **__1.2.0-131__**
51+
** Integrated Feature Access Control (FAC) limitations
52+
** Improved Designer performance with better xstream usage
53+
** Designer Look & Feel to match new Restcomm branding
54+
* Olympus WebRTC Demo updated to version **__1.1.0-167__**
55+
** Fixed an issue in WebRTC Demo jain-sip library, parsing some headers
56+
** Improve WebRTC Demo UX by showing incoming call screen on top even if caller is not the selected contact
57+
** Add additional configuration to WebRTC Demo for specifying client-specific parameters
58+
** 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/SIPOrganizationUtil.java

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@
1919
*/
2020
package org.restcomm.connect.interpreter;
2121

22+
import javax.servlet.sip.Address;
23+
import javax.servlet.sip.ServletParseException;
2224
import javax.servlet.sip.SipServletRequest;
2325
import javax.servlet.sip.SipURI;
2426
import org.apache.log4j.Logger;
@@ -50,6 +52,18 @@ public static Sid searchOrganizationBySIPRequest(OrganizationsDao orgDao, SipSer
5052
// try to get destinationOrganizationSid from toUri
5153
destinationOrganizationSid = getOrganizationSidBySipURIHost(orgDao, (SipURI) request.getTo().getURI());
5254
}
55+
if (destinationOrganizationSid == null) {
56+
// try to get destinationOrganizationSid from Refer-To
57+
Address referAddress;
58+
try {
59+
referAddress = request.getAddressHeader("Refer-To");
60+
if(referAddress != null){
61+
destinationOrganizationSid = getOrganizationSidBySipURIHost(orgDao, (SipURI) referAddress.getURI());
62+
}
63+
} catch (ServletParseException e) {
64+
logger.error(e);
65+
}
66+
}
5367
return destinationOrganizationSid;
5468
}
5569
}

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)