Skip to content

Commit df00926

Browse files
Merge pull request #109 from duosecurity/ztcapin-479
Add CA bundle version and pinning status to user agent string
2 parents 853f56d + 0bda0e6 commit df00926

2 files changed

Lines changed: 81 additions & 1 deletion

File tree

duo-client/src/main/java/com/duosecurity/client/Http.java

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ public class Http {
3232
public static final int DEFAULT_TIMEOUT_SECS = 60;
3333
private static final int RATE_LIMIT_ERROR_CODE = 429;
3434

35+
private static final String CA_BUNDLE_VERSION = "1.0";
3536
public static final String UserAgentString = "Duo API Java/0.8.1-SNAPSHOT";
3637

3738
private final String method;
@@ -223,7 +224,8 @@ protected Http(String inMethod, String inHost, String inUri, int timeout) {
223224

224225
headers = new Headers.Builder();
225226
headers.add("Host", host);
226-
headers.add("user-agent", UserAgentString);
227+
headers.add("user-agent", String.format("%s ca_bundle/%s (ca_pinning=%s)",
228+
UserAgentString, CA_BUNDLE_VERSION, "enabled"));
227229

228230
CertificatePinner pinner = Util.createPinner(host, DEFAULT_CA_CERTS);
229231

@@ -397,6 +399,10 @@ public void addHeader(String name, String value) {
397399
headers.add(name, value);
398400
}
399401

402+
void setHeader(String name, String value) {
403+
headers.set(name, value);
404+
}
405+
400406
public void addParam(String name, String value) {
401407
params.put(name, value);
402408
}
@@ -687,6 +693,9 @@ public T build() {
687693
duoClient.addHeader(name, value);
688694
}
689695
}
696+
String caPinningStatus = disableCaPinning ? "disabled" : "enabled";
697+
duoClient.setHeader("user-agent", String.format("%s ca_bundle/%s (ca_pinning=%s)",
698+
UserAgentString, CA_BUNDLE_VERSION, caPinningStatus));
690699

691700
return duoClient;
692701
}
Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
package com.duosecurity.client;
2+
3+
import static org.junit.Assert.assertEquals;
4+
import static org.junit.Assert.assertTrue;
5+
6+
import java.lang.reflect.Field;
7+
import okhttp3.Headers;
8+
import org.junit.Test;
9+
10+
public class HttpUserAgentTest {
11+
12+
private Headers getHeaders(Http http) throws Exception {
13+
Field headersField = Http.class.getDeclaredField("headers");
14+
headersField.setAccessible(true);
15+
Headers.Builder headersBuilder = (Headers.Builder) headersField.get(http);
16+
return headersBuilder.build();
17+
}
18+
19+
private String getUserAgent(Http http) throws Exception {
20+
return getHeaders(http).get("user-agent");
21+
}
22+
23+
@Test
24+
public void testDefaultBuilder_includesCaBundleVersion() throws Exception {
25+
Http http = new Http.HttpBuilder("GET", "api-host.duosecurity.com", "/auth/v2/check")
26+
.build();
27+
28+
String userAgent = getUserAgent(http);
29+
assertTrue(userAgent.contains("ca_bundle/1.0"));
30+
}
31+
32+
@Test
33+
public void testDefaultBuilder_includesCaPinningEnabled() throws Exception {
34+
Http http = new Http.HttpBuilder("GET", "api-host.duosecurity.com", "/auth/v2/check")
35+
.build();
36+
37+
String userAgent = getUserAgent(http);
38+
assertTrue(userAgent.contains("(ca_pinning=enabled)"));
39+
}
40+
41+
@Test
42+
public void testDisableCaPinning_includesCaPinningDisabled() throws Exception {
43+
Http http = new Http.HttpBuilder("GET", "api-host.duosecurity.com", "/auth/v2/check")
44+
.disableCaPinning()
45+
.build();
46+
47+
String userAgent = getUserAgent(http);
48+
assertTrue(userAgent.contains("(ca_pinning=disabled)"));
49+
}
50+
51+
@Test
52+
public void testLegacyConstructor_includesCaBundleAndPinningEnabled() throws Exception {
53+
Http http = new Http("GET", "api-host.duosecurity.com", "/auth/v2/check");
54+
55+
String userAgent = getUserAgent(http);
56+
assertTrue(userAgent.contains("ca_bundle/1.0"));
57+
assertTrue(userAgent.contains("(ca_pinning=enabled)"));
58+
}
59+
60+
@Test
61+
public void testCustomUserAgentHeader_isReplacedNotDuplicated() throws Exception {
62+
Http http = new Http.HttpBuilder("GET", "api-host.duosecurity.com", "/auth/v2/check")
63+
.addHeader("user-agent", "MyApp/1.0")
64+
.build();
65+
66+
Headers headers = getHeaders(http);
67+
assertEquals(1, headers.values("user-agent").size());
68+
assertEquals(String.format("%s ca_bundle/1.0 (ca_pinning=enabled)", Http.UserAgentString),
69+
headers.get("user-agent"));
70+
}
71+
}

0 commit comments

Comments
 (0)