Skip to content
Draft
336 changes: 336 additions & 0 deletions src/main/java/org/apache/maven/plugins/deploy/AbstractDeployMojo.java

Large diffs are not rendered by default.

68 changes: 30 additions & 38 deletions src/main/java/org/apache/maven/plugins/deploy/DeployFileMojo.java
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,6 @@
@SuppressWarnings("unused")
public class DeployFileMojo extends AbstractDeployMojo {
private static final String TAR = "tar.";
private static final String ILLEGAL_VERSION_CHARS = "\\/:\"<>|?*[](){},";

/**
* GroupId of the artifact to be deployed. Retrieved from POM file if specified.
Expand Down Expand Up @@ -117,6 +116,16 @@ public class DeployFileMojo extends AbstractDeployMojo {
/**
* Server Id to map on the &lt;id&gt; under &lt;server&gt; section of settings.xml In most cases, this parameter
* will be required for authentication.
* <p>
* <b>Security note:</b> the credentials looked up in <code>settings.xml</code> are selected purely by this id,
* so a mismatched id/url pair can point credentials kept for one server at a different URL. When this id
* matches a <code>settings.xml</code> server entry and the URL differs from every URL this build associates
* with the id, the deployment is refused unless <code>-Dmaven.deploy.allowCredentialReuse=true</code> is given
* on the command line. When no URL at all is on record for such an id, the deployment proceeds with a warning
* naming the URL the credentials will be sent to: deploy-file's parameters are command-line-supplied by
* nature, so the operator typing the pair is treated as the authorization that a POM cannot forge.
* Also note the default value <code>remote-repository</code>: if a server entry with that
* generic id exists in <code>settings.xml</code>, its credentials are used whenever this parameter is omitted.
*/
@Parameter(property = "repositoryId", defaultValue = "remote-repository", required = true)
private String repositoryId;
Expand Down Expand Up @@ -249,6 +258,7 @@ public void execute() throws MojoException {

initProperties();

validateCredentialBinding(repositoryId, url.replace(File.separator, "/"));
RemoteRepository deploymentRepository =
createDeploymentArtifactRepository(repositoryId, url.replace(File.separator, "/"));

Expand All @@ -273,6 +283,14 @@ public void execute() throws MojoException {
throw new MojoException("The artifact information is not valid: uses invalid characters.");
}

if (!isValidTypeOrExtension(packaging)) {
throw new MojoException("The packaging is not valid: uses invalid characters.");
}

if (!isValidClassifier(classifier)) {
throw new MojoException("The classifier is not valid: uses invalid characters.");
}

failIfOffline();
warnIfAffectedPackagingAndMaven(packaging);

Expand Down Expand Up @@ -364,12 +382,22 @@ public void execute() throws MojoException {
if (Files.isRegularFile(file)) {
String extension = getExtension(file);
String type = types.substring(ti, nti).trim();
String classifierEntry = classifiers.substring(ci, nci).trim();

if (!isValidTypeOrExtension(type)) {
throw new MojoException("The 'types' entry '" + type + "' is not valid:"
+ " uses invalid characters or is empty.");
}
if (!isValidClassifier(classifierEntry)) {
throw new MojoException("The 'classifiers' entry '" + classifierEntry + "' is not valid:"
+ " uses invalid characters.");
}

ProducedArtifact deployable = session.createProducedArtifact(
artifact.getGroupId(),
artifact.getArtifactId(),
artifact.getVersion().toString(),
classifiers.substring(ci, nci).trim(),
classifierEntry,
extension,
type);
artifactManager.setPath(deployable, file);
Expand Down Expand Up @@ -581,40 +609,4 @@ private String getExtension(final Path file) {
}
return "";
}

/**
* Returns {@code true} if passed in string is "valid Maven ID" (groupId or artifactId).
*/
private boolean isValidId(String id) {
if (id == null) {
return false;
}
for (int i = 0; i < id.length(); i++) {
char c = id.charAt(i);
if (!(c >= 'a' && c <= 'z'
|| c >= 'A' && c <= 'Z'
|| c >= '0' && c <= '9'
|| c == '-'
|| c == '_'
|| c == '.')) {
return false;
}
}
return true;
}

/**
* Returns {@code true} if passed in string is "valid Maven (simple. non range, expression, etc) version".
*/
private boolean isValidVersion(String version) {
if (version == null) {
return false;
}
for (int i = version.length() - 1; i >= 0; i--) {
if (ILLEGAL_VERSION_CHARS.indexOf(version.charAt(i)) >= 0) {
return false;
}
}
return true;
}
}
Loading
Loading