GH-9794: Encode SMB domain, username & password before SmbFile
Fixes: #9794 Issue link: https://github.com/spring-projects/spring-integration/issues/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 <110663902+smitsjelle@users.noreply.github.com> [artem.bilan@broadcom.com: 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 <artem.bilan@broadcom.com>
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2012-2024 the original author or authors.
|
||||
* Copyright 2012-2025 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -18,6 +18,8 @@ package org.springframework.integration.smb.session;
|
||||
|
||||
import java.net.URI;
|
||||
import java.net.URISyntaxException;
|
||||
import java.net.URLEncoder;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
|
||||
import jcifs.DialectVersion;
|
||||
|
||||
@@ -34,6 +36,7 @@ import org.springframework.util.StringUtils;
|
||||
* @author Prafull Kumar Soni
|
||||
* @author Artem Bilan
|
||||
* @author Gregory Bragg
|
||||
* @author Jelle Smits
|
||||
*
|
||||
* @since 6.0
|
||||
*/
|
||||
@@ -163,16 +166,19 @@ public class SmbConfig {
|
||||
this.smbMaxVersion = _smbMaxVersion;
|
||||
}
|
||||
|
||||
String getDomainUserPass(boolean _includePassword) {
|
||||
String getDomainUserPass(boolean _includePassword, boolean _urlEncode) {
|
||||
String domainUserPass;
|
||||
String username = _urlEncode ? URLEncoder.encode(this.username, StandardCharsets.UTF_8) : this.username;
|
||||
String password = _urlEncode ? URLEncoder.encode(this.password, StandardCharsets.UTF_8) : this.password;
|
||||
if (StringUtils.hasText(this.domain)) {
|
||||
domainUserPass = String.format("%s;%s", this.domain, this.username);
|
||||
String domain = _urlEncode ? URLEncoder.encode(this.domain, StandardCharsets.UTF_8) : this.domain;
|
||||
domainUserPass = String.format("%s;%s", domain, username);
|
||||
}
|
||||
else {
|
||||
domainUserPass = this.username;
|
||||
domainUserPass = username;
|
||||
}
|
||||
if (StringUtils.hasText(this.password)) {
|
||||
domainUserPass += ":" + (_includePassword ? this.password : "********");
|
||||
if (StringUtils.hasText(password)) {
|
||||
domainUserPass += ":" + (_includePassword ? password : "********");
|
||||
}
|
||||
return domainUserPass;
|
||||
}
|
||||
@@ -211,20 +217,22 @@ public class SmbConfig {
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the url string for the share connection without encoding.
|
||||
* Return the url string for the share connection without encoding
|
||||
* the host and path. The {@code domainUserPass} is encoded, as
|
||||
* {@link java.net.URL} requires them to be encoded otherwise its parsing fails.
|
||||
* Used in the {@link SmbShare} constructor delegation.
|
||||
* @param _includePassword whether password has to be masked in credentials of URL.
|
||||
* @return the url string for the share connection without encoding.
|
||||
* @since 6.3.8
|
||||
*/
|
||||
public final String rawUrl(boolean _includePassword) {
|
||||
String domainUserPass = getDomainUserPass(_includePassword);
|
||||
String domainUserPass = getDomainUserPass(_includePassword, true);
|
||||
String path = cleanPath();
|
||||
return "smb://%s@%s%s".formatted(domainUserPass, getHostPort(), path);
|
||||
}
|
||||
|
||||
private URI createUri(boolean _includePassword) {
|
||||
String domainUserPass = getDomainUserPass(_includePassword);
|
||||
String domainUserPass = getDomainUserPass(_includePassword, false);
|
||||
String path = cleanPath();
|
||||
try {
|
||||
return new URI("smb", domainUserPass, this.host, this.port, path, null, null);
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2012-2024 the original author or authors.
|
||||
* Copyright 2012-2025 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -17,8 +17,12 @@
|
||||
package org.springframework.integration.smb;
|
||||
|
||||
import java.net.URI;
|
||||
import java.net.URISyntaxException;
|
||||
import java.net.URL;
|
||||
import java.util.Properties;
|
||||
|
||||
import jcifs.CIFSContext;
|
||||
import jcifs.config.PropertyConfiguration;
|
||||
import jcifs.context.BaseContext;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import org.springframework.context.support.ClassPathXmlApplicationContext;
|
||||
@@ -32,11 +36,12 @@ import static org.assertj.core.api.Assertions.assertThat;
|
||||
* @author Prafull Kumar Soni
|
||||
* @author Artem Bilan
|
||||
* @author Gregory Bragg
|
||||
* @author Jelle Smits
|
||||
*/
|
||||
public class SmbMessageHistoryTests extends AbstractBaseTests {
|
||||
|
||||
@Test
|
||||
public void testMessageHistory() throws URISyntaxException {
|
||||
public void testMessageHistory() throws Exception {
|
||||
try (ClassPathXmlApplicationContext applicationContext = getApplicationContext()) {
|
||||
SourcePollingChannelAdapter adapter = applicationContext
|
||||
.getBean("smbInboundChannelAdapter", SourcePollingChannelAdapter.class);
|
||||
@@ -51,6 +56,12 @@ public class SmbMessageHistoryTests extends AbstractBaseTests {
|
||||
assertThat(uri.getUserInfo()).isEqualTo("sambagu@est:sambag%uest");
|
||||
assertThat(uri.getPath()).isEqualTo("/smb share/");
|
||||
assertThat(uri.getRawPath()).isEqualTo("/smb%20share/");
|
||||
|
||||
CIFSContext context = new BaseContext(new PropertyConfiguration(new Properties()));
|
||||
URL rawUrl = new URL(null, smbSessionFactory.rawUrl(true), context.getUrlHandler());
|
||||
assertThat(rawUrl.getHost()).isEqualTo("localhost");
|
||||
assertThat(rawUrl.getUserInfo()).isEqualTo("sambagu%40est:sambag%25uest");
|
||||
assertThat(rawUrl.getPath()).isEqualTo("/smb share/");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user