Skip to content

Commit fcd90a9

Browse files
smitsjelleartembilan
authored andcommitted
GH-9794: Encode SMB domain, username & password before SmbFile
Fixes: #9794 Issue link: #9794 The `SmbConfig.rawUrl()` method doesn't apply any URL encoding, resulting in parts of the `domainUserPass` that may contain a `@` character to break the URL logic in regard to determining the hostname. * Modify `SmbConfig.getDomainUserPass(_includePassword)` to conditionally encode the variables. Makes sure to encode the individual parts to not undesirably encode the `;` and `:` characters, breaking other logic. * Modify `SmbConfig.rawUrl(_includePassword)` and `SmbConfig.createUri(_includePassword)` to call the modified method with the correct `_urlEncode` variable Signed-off-by: Jelle Smits <[email protected]> [[email protected]: some code cleanup] * Add author to the affected classes * Remove redundant explicit exceptions list from the `SmbMessageHistoryTests` **Auto-cherry-pick to `6.3.x`** Signed-off-by: Artem Bilan <[email protected]>
1 parent 4b0d0e2 commit fcd90a9

File tree

2 files changed

+31
-12
lines changed

2 files changed

+31
-12
lines changed

spring-integration-smb/src/main/java/org/springframework/integration/smb/session/SmbConfig.java

Lines changed: 17 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2012-2024 the original author or authors.
2+
* Copyright 2012-2025 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -18,6 +18,8 @@
1818

1919
import java.net.URI;
2020
import java.net.URISyntaxException;
21+
import java.net.URLEncoder;
22+
import java.nio.charset.StandardCharsets;
2123

2224
import jcifs.DialectVersion;
2325

@@ -34,6 +36,7 @@
3436
* @author Prafull Kumar Soni
3537
* @author Artem Bilan
3638
* @author Gregory Bragg
39+
* @author Jelle Smits
3740
*
3841
* @since 6.0
3942
*/
@@ -163,16 +166,19 @@ public void setSmbMaxVersion(DialectVersion _smbMaxVersion) {
163166
this.smbMaxVersion = _smbMaxVersion;
164167
}
165168

166-
String getDomainUserPass(boolean _includePassword) {
169+
String getDomainUserPass(boolean _includePassword, boolean _urlEncode) {
167170
String domainUserPass;
171+
String username = _urlEncode ? URLEncoder.encode(this.username, StandardCharsets.UTF_8) : this.username;
172+
String password = _urlEncode ? URLEncoder.encode(this.password, StandardCharsets.UTF_8) : this.password;
168173
if (StringUtils.hasText(this.domain)) {
169-
domainUserPass = String.format("%s;%s", this.domain, this.username);
174+
String domain = _urlEncode ? URLEncoder.encode(this.domain, StandardCharsets.UTF_8) : this.domain;
175+
domainUserPass = String.format("%s;%s", domain, username);
170176
}
171177
else {
172-
domainUserPass = this.username;
178+
domainUserPass = username;
173179
}
174-
if (StringUtils.hasText(this.password)) {
175-
domainUserPass += ":" + (_includePassword ? this.password : "********");
180+
if (StringUtils.hasText(password)) {
181+
domainUserPass += ":" + (_includePassword ? password : "********");
176182
}
177183
return domainUserPass;
178184
}
@@ -211,20 +217,22 @@ public final String rawUrl() {
211217
}
212218

213219
/**
214-
* Return the url string for the share connection without encoding.
220+
* Return the url string for the share connection without encoding
221+
* the host and path. The {@code domainUserPass} is encoded, as
222+
* {@link java.net.URL} requires them to be encoded otherwise its parsing fails.
215223
* Used in the {@link SmbShare} constructor delegation.
216224
* @param _includePassword whether password has to be masked in credentials of URL.
217225
* @return the url string for the share connection without encoding.
218226
* @since 6.3.8
219227
*/
220228
public final String rawUrl(boolean _includePassword) {
221-
String domainUserPass = getDomainUserPass(_includePassword);
229+
String domainUserPass = getDomainUserPass(_includePassword, true);
222230
String path = cleanPath();
223231
return "smb://%s@%s%s".formatted(domainUserPass, getHostPort(), path);
224232
}
225233

226234
private URI createUri(boolean _includePassword) {
227-
String domainUserPass = getDomainUserPass(_includePassword);
235+
String domainUserPass = getDomainUserPass(_includePassword, false);
228236
String path = cleanPath();
229237
try {
230238
return new URI("smb", domainUserPass, this.host, this.port, path, null, null);

spring-integration-smb/src/test/java/org/springframework/integration/smb/SmbMessageHistoryTests.java

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2012-2024 the original author or authors.
2+
* Copyright 2012-2025 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -17,8 +17,12 @@
1717
package org.springframework.integration.smb;
1818

1919
import java.net.URI;
20-
import java.net.URISyntaxException;
20+
import java.net.URL;
21+
import java.util.Properties;
2122

23+
import jcifs.CIFSContext;
24+
import jcifs.config.PropertyConfiguration;
25+
import jcifs.context.BaseContext;
2226
import org.junit.jupiter.api.Test;
2327

2428
import org.springframework.context.support.ClassPathXmlApplicationContext;
@@ -32,11 +36,12 @@
3236
* @author Prafull Kumar Soni
3337
* @author Artem Bilan
3438
* @author Gregory Bragg
39+
* @author Jelle Smits
3540
*/
3641
public class SmbMessageHistoryTests extends AbstractBaseTests {
3742

3843
@Test
39-
public void testMessageHistory() throws URISyntaxException {
44+
public void testMessageHistory() throws Exception {
4045
try (ClassPathXmlApplicationContext applicationContext = getApplicationContext()) {
4146
SourcePollingChannelAdapter adapter = applicationContext
4247
.getBean("smbInboundChannelAdapter", SourcePollingChannelAdapter.class);
@@ -51,6 +56,12 @@ public void testMessageHistory() throws URISyntaxException {
5156
assertThat(uri.getUserInfo()).isEqualTo("sambagu@est:sambag%uest");
5257
assertThat(uri.getPath()).isEqualTo("/smb share/");
5358
assertThat(uri.getRawPath()).isEqualTo("/smb%20share/");
59+
60+
CIFSContext context = new BaseContext(new PropertyConfiguration(new Properties()));
61+
URL rawUrl = new URL(null, smbSessionFactory.rawUrl(true), context.getUrlHandler());
62+
assertThat(rawUrl.getHost()).isEqualTo("localhost");
63+
assertThat(rawUrl.getUserInfo()).isEqualTo("sambagu%40est:sambag%25uest");
64+
assertThat(rawUrl.getPath()).isEqualTo("/smb share/");
5465
}
5566
}
5667

0 commit comments

Comments
 (0)