Skip to content
This repository has been archived by the owner on Feb 23, 2021. It is now read-only.

Commit

Permalink
Browse files Browse the repository at this point in the history
[FIXED JENKINS-16337] Provide basic syntactic validation of public keys.
Does not try to actually decode them.
  • Loading branch information
jglick committed Apr 7, 2017
1 parent 402b2ef commit da90302
Show file tree
Hide file tree
Showing 2 changed files with 41 additions and 0 deletions.
Expand Up @@ -4,13 +4,15 @@
import hudson.model.UserProperty;
import hudson.model.UserPropertyDescriptor;
import hudson.model.User;
import hudson.util.FormValidation;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.StringReader;
import java.security.PublicKey;

import org.kohsuke.stapler.DataBoundConstructor;
import org.kohsuke.stapler.QueryParameter;

/**
* @author Kohsuke Kawaguchi
Expand Down Expand Up @@ -55,6 +57,30 @@ public String getDisplayName() {
public UserProperty newInstance(User user) {
return null;
}

public FormValidation doCheckAuthorizedKeys(@QueryParameter String value) throws IOException {
// Try to match behavior of isAuthorizedKey as far as parsing.
final BufferedReader r = new BufferedReader(new StringReader(value));
String s;
while ((s = r.readLine()) != null) {
String[] tokens = s.split("\\s+");
if (tokens.length < 2) {
if (s.trim().isEmpty()) {
continue;
} else {
return FormValidation.warning("Unexpected line: ‘" + s + "’");
}
}
if (!tokens[0].matches("ssh-[a-z]+")) {
return FormValidation.warning("‘" + tokens[0] + "’ does not look like a valid key type");
}
if (!tokens[1].matches("[a-zA-Z0-9/+]+=*")) {
return FormValidation.error("‘" + tokens[1] + "’ does not look like a Base64-encoded public key");
}
}
return FormValidation.ok();
}

}

public static User findUser(PublicKey identity) {
Expand Down
15 changes: 15 additions & 0 deletions src/test/java/org/jenkinsci/main/modules/cli/auth/ssh/TheTest.java
Expand Up @@ -3,11 +3,13 @@
import hudson.cli.CLI;
import hudson.cli.CLICommand;
import hudson.model.User;
import hudson.util.FormValidation;

import java.util.Collections;
import jenkins.security.MasterToSlaveCallable;

import org.jvnet.hudson.test.HudsonTestCase;
import org.jvnet.hudson.test.Issue;
import org.jvnet.hudson.test.TestExtension;

/**
Expand Down Expand Up @@ -57,6 +59,19 @@ private void testRoundtrip(String privateKey, String publicKey) throws Exception
}
}

@Issue("JENKINS-16337")
public void testDoCheckAuthorizedKeys() throws Exception {
assertCheckOK(FormValidation.Kind.OK, "");
assertCheckOK(FormValidation.Kind.OK, PUBLIC_DSA_KEY);
assertCheckOK(FormValidation.Kind.OK, PUBLIC_RSA_KEY);
assertCheckOK(FormValidation.Kind.OK, PUBLIC_DSA_KEY + "\r\n" + PUBLIC_RSA_KEY + "\n\n");
assertCheckOK(FormValidation.Kind.WARNING, PRIVATE_RSA_KEY);
}
private void assertCheckOK(FormValidation.Kind kind, String value) throws Exception {
FormValidation r = jenkins.getDescriptorByType(UserPropertyImpl.DescriptorImpl.class).doCheckAuthorizedKeys(value);
assertEquals("check of ‘" + value + "’: " + r.renderHtml(), kind, r.kind);
}

private static final String PUBLIC_RSA_KEY = "ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAr+ZaQ/SI8xIr5BtMCh7gizoH/cVzEi8tCxwvHOu5eELzxl1FBwUH5/pRzMI31w1+WlYXBCYQSvcWgpLlAZn7VaJYCxUE9K9gMxLPmk81fUec8sFr5hSj6cPL3hWdk4CgdJ0M2Q/GNJExvbDsiFMFb/p9jnrKhHQ47mhT4HpMLTE4fG5+AB3liJZhaUo9lbHfmhpmpps9o1tE1z7YcIO4ckvCklxF+04mVRjKur3lcezh2i4TXjMGmkDgU7pTrwf9OM9rDo5dSpsAK/dGWlBT01jhv69wOfUitcYENAK07Tgyoti3pEYD3b2ugxQ0fe0LqoxFa//O540PjMhxEbmuQQ== xxx@yyy";

private static final String PRIVATE_RSA_KEY =
Expand Down

0 comments on commit da90302

Please sign in to comment.