Skip to content

Commit 690c6fe

Browse files
author
maria-farooq
authored
Merge pull request #2404 from RestComm/RESTCOMM-1032_1a_D1
RESTCOMM-1032 : Client Password Proposal 1a
2 parents b4163bc + 54d1704 commit 690c6fe

82 files changed

Lines changed: 406 additions & 268 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

restcomm/pom.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1157,4 +1157,4 @@
11571157
</pluginRepository>
11581158
</pluginRepositories>
11591159

1160-
</project>
1160+
</project>

restcomm/restcomm.application/src/main/webapp/WEB-INF/conf/restcomm.xml

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,9 @@
1111
MA 02110-1301 USA, or see the FSF site: http://www.fsf.org. -->
1212
<restcomm>
1313
<runtime-settings>
14-
<!-- The API version that will be used. -->
14+
<client-algorithm>MD5</client-algorithm>
15+
<client-qop>auth</client-qop>
16+
<!-- The API version that will be used. -->
1517
<api-version>2012-04-24</api-version>
1618

1719
<!-- Try to run RVD workspace projects migration to apply new naming

restcomm/restcomm.application/src/main/webapp/WEB-INF/data/hsql/restcomm.script

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -51,5 +51,3 @@ INSERT INTO "restcomm_incoming_phone_numbers" VALUES('PN9154cd100e894cccb9846542
5151
INSERT INTO "restcomm_incoming_phone_numbers" VALUES('PN268b3f55d3a84a70aae8b78bde3443b5','2017-04-13 22:03:27.925000000','2017-04-13 22:03:27.925000000','This app joins a video conf bridge with wait music playing and requires XMS media server','ACae6e420f425248d6a26948c17a9e2acf','+1244','2012-04-24',FALSE,'/restcomm/demos/video-conference.xml','POST',NULL,'POST',NULL,'POST',NULL,NULL,'POST',NULL,'POST',NULL,'/2012-04-24/Accounts/ACae6e420f425248d6a26948c17a9e2acf/IncomingPhoneNumbers/PN268b3f55d3a84a70aae8b78bde3443b5',NULL,NULL,NULL,NULL, TRUE,'0.0',NULL,NULL,NULL,NULL,NULL, NULL, NULL, NULL, 'ORafbe225ad37541eba518a74248f0ac4c')
5252
INSERT INTO "restcomm_incoming_phone_numbers" VALUES('PNa956a87b060b4b93bf432fce19fe79bf','2017-04-13 22:04:04.258000000','2017-04-13 22:04:04.258000000','This app adds you to a video conf bridge as a moderator and requires XMS media server','ACae6e420f425248d6a26948c17a9e2acf','+1245','2012-04-24',FALSE,'/restcomm/demos/video-conference-moderator.xml','POST',NULL,'POST',NULL,'POST',NULL,NULL,'POST',NULL,'POST',NULL,'/2012-04-24/Accounts/ACae6e420f425248d6a26948c17a9e2acf/IncomingPhoneNumbers/PNa956a87b060b4b93bf432fce19fe79bf',NULL,NULL,NULL,NULL, TRUE,'0.0',NULL,NULL,NULL,NULL,NULL, NULL, NULL, NULL, 'ORafbe225ad37541eba518a74248f0ac4c')
5353
INSERT INTO "restcomm_incoming_phone_numbers" VALUES('PN5eadc8c3b26a495a842bbff6aecc9f6c','2017-09-29 19:34:10.679000000','2017-09-29 19:34:10.679000000','This app calls registered restcomm client Alice using XMS for video','ACae6e420f425248d6a26948c17a9e2acf','+1246','2012-04-24',FALSE,'/restcomm/demos/video-dial-client.xml','POST',NULL,'POST',NULL,'POST',NULL,NULL,'POST',NULL,'POST',NULL,'/2012-04-24/Accounts/ACae6e420f425248d6a26948c17a9e2acf/IncomingPhoneNumbers/PN5eadc8c3b26a495a842bbff6aecc9f6c',NULL,NULL,NULL,NULL, TRUE,'0.0',NULL,NULL,NULL,NULL,NULL, NULL, NULL, NULL, 'ORafbe225ad37541eba518a74248f0ac4c')
54-
INSERT INTO "restcomm_clients" VALUES('CLa2b99142e111427fbb489c3de357f60a','2013-11-04 12:52:44.144000000','2013-11-04 12:52:44.144000000','ACae6e420f425248d6a26948c17a9e2acf','2012-04-24','alice','alice','1234',1,NULL,'POST',NULL,'POST',NULL,'/2012-04-24/Accounts/ACae6e420f425248d6a26948c17a9e2acf/Clients/CLa2b99142e111427fbb489c3de357f60a',NULL)
55-
INSERT INTO "restcomm_clients" VALUES('CL3003328d0de04ba68f38de85b732ed56','2013-11-04 16:33:39.248000000','2013-11-04 16:33:39.248000000','ACae6e420f425248d6a26948c17a9e2acf','2012-04-24','bob','bob','1234',1,NULL,'POST',NULL,'POST',NULL,'/2012-04-24/Accounts/ACae6e420f425248d6a26948c17a9e2acf/Clients/CL3003328d0de04ba68f38de85b732ed56',NULL)

restcomm/restcomm.application/src/main/webapp/WEB-INF/scripts/mariadb/init.sql

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -458,10 +458,6 @@ INSERT INTO restcomm_incoming_phone_numbers VALUES('PN268b3f55d3a84a70aae8b78bde
458458
INSERT INTO restcomm_incoming_phone_numbers VALUES('PNa956a87b060b4b93bf432fce19fe79bf','2017-04-13 22:04:04.258000000','2017-04-13 22:04:04.258000000','This app adds you to a video conf bridge as a moderator and requires XMS media server','ACae6e420f425248d6a26948c17a9e2acf','+1245','2012-04-24',FALSE,'/restcomm/demos/video-conference-moderator.xml','POST',NULL,'POST',NULL,'POST',NULL,NULL,'POST',NULL,'POST',NULL,'/2012-04-24/Accounts/ACae6e420f425248d6a26948c17a9e2acf/IncomingPhoneNumbers/PNa956a87b060b4b93bf432fce19fe79bf', true, false, false, false, true, 0.0, null, null, null, null, null, null, null, null, 'ORafbe225ad37541eba518a74248f0ac4c');
459459
INSERT INTO restcomm_incoming_phone_numbers VALUES('PN5eadc8c3b26a495a842bbff6aecc9f6c','2017-09-29 19:34:10.679000000','2017-09-29 19:34:10.679000000','This app calls registered restcomm client Alice using XMS for video','ACae6e420f425248d6a26948c17a9e2acf','+1246','2012-04-24',FALSE,'/restcomm/demos/video-dial-client.xml','POST',NULL,'POST',NULL,'POST',NULL,NULL,'POST',NULL,'POST',NULL,'/2012-04-24/Accounts/ACae6e420f425248d6a26948c17a9e2acf/IncomingPhoneNumbers/PN5eadc8c3b26a495a842bbff6aecc9f6c', true, false, false, false, true, 0.0, null, null, null, null, null, null, null, null, 'ORafbe225ad37541eba518a74248f0ac4c');
460460

461-
/* Create demo clients */
462-
INSERT INTO restcomm_clients VALUES('CLa2b99142e111427fbb489c3de357f60a','2013-11-04 12:52:44.144000000','2013-11-04 12:52:44.144000000','ACae6e420f425248d6a26948c17a9e2acf','2012-04-24','alice','alice','1234',1,NULL,'POST',NULL,'POST',NULL,'/2012-04-24/Accounts/ACae6e420f425248d6a26948c17a9e2acf/Clients/CLa2b99142e111427fbb489c3de357f60a', NULL);
463-
INSERT INTO restcomm_clients VALUES('CL3003328d0de04ba68f38de85b732ed56','2013-11-04 16:33:39.248000000','2013-11-04 16:33:39.248000000','ACae6e420f425248d6a26948c17a9e2acf','2012-04-24','bob','bob','1234',1,NULL,'POST',NULL,'POST',NULL,'/2012-04-24/Accounts/ACae6e420f425248d6a26948c17a9e2acf/Clients/CL3003328d0de04ba68f38de85b732ed56', NULL);
464-
465461
/* Create index on restcomm_call_detail_records on conference_sid column */
466462
CREATE INDEX idx_cdr_conference_sid ON restcomm_call_detail_records (conference_sid);
467463

restcomm/restcomm.commons/src/main/java/org/restcomm/connect/commons/configuration/sets/MainConfigurationSet.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,4 +59,8 @@ public interface MainConfigurationSet {
5959
long getConferenceTimeout();
6060

6161
void setConferenceTimeout(long conferenceTimeout);
62+
63+
String getClientAlgorithm();
64+
65+
String getClientQOP();
6266
}

restcomm/restcomm.commons/src/main/java/org/restcomm/connect/commons/configuration/sets/impl/MainConfigurationSetImpl.java

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,8 @@ public class MainConfigurationSetImpl extends ConfigurationSet implements MainCo
5252
private static final String HTTP_ROUTES_PORT = "http-client.routes-port";
5353
private static final String HTTP_ROUTES_CONN = "http-client.routes-conn";
5454
private static final String CONFERENCE_TIMEOUT_KEY = "runtime-settings.conference-timeout";
55+
private static final String DEFAULT_CLIENT_PASSWORD = "MD5";
56+
private static final String DEFAULT_CLIENT_QOP = "auth";
5557
private static final long CONFERENCE_TIMEOUT_DEFAULT = 14400; //4 hours in seconds
5658
private static final SslMode SSL_MODE_DEFAULT = SslMode.strict;
5759
private SslMode sslMode;
@@ -73,6 +75,8 @@ public class MainConfigurationSetImpl extends ConfigurationSet implements MainCo
7375

7476
public static final String BYPASS_LB_FOR_CLIENTS = "bypass-lb-for-clients";
7577
private boolean bypassLbForClients = false;
78+
private String clientAlgorithm = DEFAULT_CLIENT_PASSWORD;
79+
private String clientQOP = DEFAULT_CLIENT_QOP;
7680

7781
public MainConfigurationSetImpl(ConfigurationSource source) {
7882
super(source);
@@ -161,6 +165,9 @@ public MainConfigurationSetImpl(ConfigurationSource source) {
161165
}catch(NumberFormatException nfe){
162166
this.conferenceTimeout = CONFERENCE_TIMEOUT_DEFAULT;
163167
}
168+
169+
clientAlgorithm = source.getProperty("runtime-settings.client-algorithm", DEFAULT_CLIENT_PASSWORD);
170+
clientQOP = source.getProperty("runtime-settings.client-qop", DEFAULT_CLIENT_QOP);
164171
}
165172

166173
public MainConfigurationSetImpl(SslMode sslMode, int responseTimeout, boolean useHostnameToResolveRelativeUrls, String hostname, String instanceId, boolean bypassLbForClients) {
@@ -271,4 +278,14 @@ public long getConferenceTimeout() {
271278
public void setConferenceTimeout(long conferenceTimeout) {
272279
this.conferenceTimeout = conferenceTimeout;
273280
}
281+
282+
@Override
283+
public String getClientAlgorithm() {
284+
return clientAlgorithm;
285+
}
286+
287+
@Override
288+
public String getClientQOP() {
289+
return clientQOP;
290+
}
274291
}

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

Lines changed: 60 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
import java.security.NoSuchAlgorithmException;
2424

2525
import org.restcomm.connect.commons.annotations.concurrency.ThreadSafe;
26+
import org.restcomm.connect.commons.configuration.RestcommConfiguration;
2627

2728
/**
2829
* @author quintana.thomas@gmail.com (Thomas Quintana)
@@ -41,36 +42,65 @@ private static String A1(final String algorithm, final String user, final String
4142
if (cnonce == null || cnonce.length() == 0) {
4243
throw new NullPointerException("The cnonce parameter may not be null.");
4344
}
44-
return H(user + ":" + realm + ":" + password) + ":" + nonce + ":" + cnonce;
45+
return H(user + ":" + realm + ":" + password, algorithm) + ":" + nonce + ":" + cnonce;
4546
}
4647
}
4748

48-
private static String A2(final String method, final String uri, String body, final String qop) {
49+
private static String A2(String algorithm, final String method, final String uri, String body, final String qop) {
4950
if (qop == null || qop.trim().length() == 0 || qop.trim().equalsIgnoreCase("auth")) {
5051
return method + ":" + uri;
5152
} else {
5253
if (body == null)
5354
body = "";
54-
return method + ":" + uri + ":" + H(body);
55+
return method + ":" + uri + ":" + H(body, algorithm);
5556
}
5657
}
5758

5859
public static String response(final String algorithm, final String user, final String realm, final String password,
59-
final String nonce, final String nc, final String cnonce, final String method, final String uri, String body,
60-
final String qop) {
61-
validate(user, realm, password, nonce, method, uri);
62-
final String a1 = A1(algorithm, user, realm, password, nonce, cnonce);
63-
final String a2 = A2(method, uri, body, qop);
60+
final String nonce, final String nc, final String cnonce, final String method, final String uri, String body,
61+
final String qop) {
62+
return response(algorithm, user, realm, password, "", nonce, nc, cnonce, method, uri, body, qop);
63+
}
64+
65+
/**
66+
* @param algorithm
67+
* @param user
68+
* @param realm
69+
* @param password
70+
* @param password2
71+
* @param nonce
72+
* @param nc
73+
* @param cnonce
74+
* @param method
75+
* @param uri
76+
* @param body
77+
* @param qop
78+
* @return
79+
*/
80+
public static String response(final String algorithm, final String user, final String realm, final String password,
81+
String password2, final String nonce, final String nc, final String cnonce, final String method, final String uri,
82+
String body, final String qop) {
83+
validate(user, realm, password, nonce, method, uri, algorithm);
84+
String ha1;
85+
86+
if(!password2.isEmpty()){
87+
ha1 = password2;
88+
}else{
89+
final String a1 = A1(algorithm, user, realm, password, nonce, cnonce);
90+
ha1 = H(a1, algorithm);
91+
}
92+
93+
final String a2 = A2(algorithm, method, uri, body, qop);
6494
if (cnonce != null && qop != null && nc != null && (qop.equalsIgnoreCase("auth") || qop.equalsIgnoreCase("auth-int"))) {
65-
return KD(H(a1), nonce + ":" + nc + ":" + cnonce + ":" + qop + ":" + H(a2));
95+
return KD(ha1, nonce + ":" + nc + ":" + cnonce + ":" + qop + ":" + H(a2, algorithm), algorithm);
6696
} else {
67-
return KD(H(a1), nonce + ":" + H(a2));
97+
return KD(ha1, nonce + ":" + H(a2, algorithm), algorithm);
6898
}
6999
}
70100

71-
private static String H(final String data) {
101+
private static String H(final String data, String algorithm) {
72102
try {
73-
final MessageDigest digest = MessageDigest.getInstance("MD5");
103+
final MessageDigest digest = MessageDigest.getInstance(algorithm);
74104
final byte[] result = digest.digest(data.getBytes());
75105
final char[] characters = HexadecimalUtils.toHex(result);
76106
return new String(characters);
@@ -79,12 +109,12 @@ private static String H(final String data) {
79109
}
80110
}
81111

82-
private static String KD(final String secret, final String data) {
83-
return H(secret + ":" + data);
112+
private static String KD(final String secret, final String data, String algorithm) {
113+
return H(secret + ":" + data, algorithm);
84114
}
85115

86116
private static void validate(final String user, final String realm, final String password, final String nonce,
87-
final String method, final String uri) {
117+
final String method, final String uri, String algorithm) {
88118
if (user == null) {
89119
throw new NullPointerException("The user parameter may not be null.");
90120
} else if (realm == null) {
@@ -97,6 +127,21 @@ private static void validate(final String user, final String realm, final String
97127
throw new NullPointerException("The uri parameter may not be null.");
98128
} else if (nonce == null) {
99129
throw new NullPointerException("The nonce parameter may not be null.");
130+
} else if (algorithm == null) {
131+
throw new NullPointerException("The algorithm parameter may not be null.");
100132
}
101133
}
134+
135+
/**
136+
* @param username
137+
* @param realm
138+
* @param password
139+
* @return
140+
*/
141+
public static String HA1(String username, String realm, String password){
142+
String algorithm = RestcommConfiguration.getInstance().getMain().getClientAlgorithm();
143+
String ha1 = "";
144+
ha1 = DigestAuthentication.H(username+":"+realm+":"+password, algorithm);
145+
return ha1;
146+
}
102147
}

restcomm/restcomm.dao/src/main/java/org/restcomm/connect/dao/entities/Client.java

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
import org.restcomm.connect.commons.annotations.concurrency.Immutable;
2727
import org.restcomm.connect.commons.annotations.concurrency.NotThreadSafe;
2828
import org.restcomm.connect.commons.dao.Sid;
29+
import org.restcomm.connect.commons.util.DigestAuthentication;
2930

3031
/**
3132
* @author quintana.thomas@gmail.com (Thomas Quintana)
@@ -148,8 +149,14 @@ public Client setFriendlyName(final String friendlyName) {
148149
voiceUrl, voiceMethod, voiceFallbackUrl, voiceFallbackMethod, voiceApplicationSid, uri, pushClientIdentity);
149150
}
150151

151-
public Client setPassword(final String password) {
152-
return new Client(sid, dateCreated, DateTime.now(), accountSid, apiVersion, friendlyName, login, password, status,
152+
/**
153+
* @param login
154+
* @param password
155+
* @param realm
156+
* @return
157+
*/
158+
public Client setPassword(final String login, final String password, final String realm) {
159+
return new Client(sid, dateCreated, DateTime.now(), accountSid, apiVersion, friendlyName, login, DigestAuthentication.HA1(login, realm, password), status,
153160
voiceUrl, voiceMethod, voiceFallbackUrl, voiceFallbackMethod, voiceApplicationSid, uri, pushClientIdentity);
154161
}
155162

@@ -235,8 +242,13 @@ public void setLogin(final String login) {
235242
this.login = login;
236243
}
237244

238-
public void setPassword(final String password) {
239-
this.password = password;
245+
/**
246+
* @param login
247+
* @param password
248+
* @param realm
249+
*/
250+
public void setPassword(final String login, final String password, final String realm) {
251+
this.password = DigestAuthentication.HA1(login, realm, password);
240252
}
241253

242254
public void setStatus(final int status) {

restcomm/restcomm.dao/src/test/java/org/restcomm/connect/dao/mybatis/ClientsDaoTest.java

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
*/
2020
package org.restcomm.connect.dao.mybatis;
2121

22+
import java.io.IOException;
2223
import java.io.InputStream;
2324
import java.net.URI;
2425
import java.net.URISyntaxException;
@@ -40,15 +41,21 @@
4041
* @author quintana.thomas@gmail.com (Thomas Quintana)
4142
* @author maria farooq
4243
*/
43-
public final class ClientsDaoTest {
44+
public final class ClientsDaoTest extends DaoTest {
4445
private static MybatisDaoManager manager;
46+
private final String realm = "org1.restcomm.com";
4547

4648
public ClientsDaoTest() {
4749
super();
4850
}
4951

5052
@Before
51-
public void before() {
53+
public void before() throws IOException {
54+
55+
sandboxRoot = createTempDir("accountsTest");
56+
String mybatisFilesPath = getClass().getResource("/accountsDao").getFile();
57+
setupSandbox(mybatisFilesPath, sandboxRoot);
58+
5259
final InputStream data = getClass().getResourceAsStream("/mybatis.xml");
5360
final SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
5461
final SqlSessionFactory factory = builder.build(data);
@@ -74,7 +81,7 @@ public void createReadUpdateDelete() {
7481
builder.setApiVersion("2012-04-24");
7582
builder.setFriendlyName("Alice");
7683
builder.setLogin("alice");
77-
builder.setPassword("1234");
84+
builder.setPassword("alice", "1234", realm);
7885
builder.setStatus(Client.ENABLED);
7986
builder.setVoiceUrl(url);
8087
builder.setVoiceMethod(method);
@@ -110,7 +117,7 @@ public void createReadUpdateDelete() {
110117
method = "POST";
111118
String newClientIdentity = "newClientIdentity";
112119
client = client.setFriendlyName("Bob");
113-
client = client.setPassword("4321");
120+
client = client.setPassword(client.getLogin(), "4321", realm);
114121
client = client.setStatus(Client.DISABLED);
115122
client = client.setVoiceApplicationSid(application);
116123
client = client.setVoiceUrl(url);
@@ -161,7 +168,7 @@ public void readByUser() {
161168
builder.setApiVersion("2012-04-24");
162169
builder.setFriendlyName("Tom");
163170
builder.setLogin("tom");
164-
builder.setPassword("1234");
171+
builder.setPassword("tom", "1234", realm);
165172
builder.setStatus(Client.ENABLED);
166173
builder.setVoiceUrl(url);
167174
builder.setVoiceMethod(method);
@@ -208,7 +215,7 @@ public void readDeleteByAccountSid() {
208215
builder.setApiVersion("2012-04-24");
209216
builder.setFriendlyName("Tom");
210217
builder.setLogin("tom");
211-
builder.setPassword("1234");
218+
builder.setPassword("tom", "1234", realm);
212219
builder.setStatus(Client.ENABLED);
213220
builder.setVoiceUrl(url);
214221
builder.setVoiceMethod(method);

restcomm/restcomm.dao/src/test/java/org/restcomm/connect/dao/mybatis/DaoTest.java

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,6 @@
2323
import org.apache.commons.configuration.ConfigurationException;
2424
import org.apache.commons.configuration.XMLConfiguration;
2525
import org.apache.commons.io.FileUtils;
26-
import org.apache.commons.io.IOUtils;
2726
import org.restcomm.connect.commons.configuration.RestcommConfiguration;
2827
import org.restcomm.connect.commons.dao.Sid;
2928

0 commit comments

Comments
 (0)