mirror of
https://github.com/jenkinsci/jenkins.git
synced 2026-11-15 21:12:15 +00:00
Replacing org.kohsuke.gmaven by org.codehaus.gmaven
This commit is contained in:
1 parent
92c2503b1a
commit
bf80986734
9 files changed
+10
-20
No files matched your search
@@ -1,111 +0,0 @@
|
||||
package hudson.util
|
||||
|
||||
import com.trilead.ssh2.crypto.Base64
|
||||
import hudson.FilePath
|
||||
import jenkins.security.ConfidentialStoreRule
|
||||
import org.junit.Rule
|
||||
import org.junit.Test
|
||||
import org.junit.rules.TemporaryFolder
|
||||
|
||||
import javax.crypto.Cipher
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @author Kohsuke Kawaguchi
|
||||
*/
|
||||
class SecretRewriterTest {
|
||||
@Rule
|
||||
public MockSecretRule mockSecretRule = new MockSecretRule()
|
||||
|
||||
@Rule
|
||||
public ConfidentialStoreRule confidentialStoreRule = new ConfidentialStoreRule();
|
||||
|
||||
@Rule public TemporaryFolder tmp = new TemporaryFolder()
|
||||
|
||||
@Test
|
||||
void singleFileRewrite() {
|
||||
def o = encryptOld('foobar') // old
|
||||
def n = encryptNew('foobar') // new
|
||||
roundtrip "<foo>${o}</foo>",
|
||||
"<foo>${n}</foo>"
|
||||
|
||||
roundtrip "<foo>${o}</foo><foo>${o}</foo>",
|
||||
"<foo>${n}</foo><foo>${n}</foo>"
|
||||
|
||||
roundtrip "<foo>${n}</foo>",
|
||||
"<foo>${n}</foo>"
|
||||
|
||||
roundtrip " <foo>thisIsLegalBase64AndLongEnoughThatItCouldLookLikeSecret</foo> ",
|
||||
" <foo>thisIsLegalBase64AndLongEnoughThatItCouldLookLikeSecret</foo> "
|
||||
|
||||
// to be rewritten, it needs to be between a tag
|
||||
roundtrip "<foo>$o", "<foo>$o"
|
||||
roundtrip "$o</foo>", "$o</foo>"
|
||||
|
||||
//
|
||||
roundtrip "<abc>\n<foo>$o</foo>\n</abc>", "<abc>\n<foo>$n</foo>\n</abc>"
|
||||
}
|
||||
|
||||
void roundtrip(String before, String after) {
|
||||
def sr = new SecretRewriter(null);
|
||||
def f = File.createTempFile("test", "xml", tmp.root)
|
||||
f.text = before
|
||||
sr.rewrite(f,null)
|
||||
assert after.replaceAll(System.getProperty("line.separator"), "\n").trim()==f.text.replaceAll(System.getProperty("line.separator"), "\n").trim()
|
||||
}
|
||||
|
||||
String encryptOld(str) {
|
||||
def cipher = Secret.getCipher("AES");
|
||||
cipher.init(Cipher.ENCRYPT_MODE, Secret.legacyKey);
|
||||
return new String(Base64.encode(cipher.doFinal((str + Secret.MAGIC).getBytes("UTF-8"))))
|
||||
}
|
||||
|
||||
String encryptNew(str) {
|
||||
return Secret.fromString(str).encryptedValue
|
||||
}
|
||||
|
||||
/**
|
||||
* Directory rewrite and recursion detection
|
||||
*/
|
||||
@Test
|
||||
void recursionDetection() {
|
||||
def backup = tmp.newFolder("backup")
|
||||
def sw = new SecretRewriter(backup);
|
||||
def st = StreamTaskListener.fromStdout()
|
||||
|
||||
def o = encryptOld("Hello world")
|
||||
def n = encryptNew("Hello world")
|
||||
def payload = "<msg>$o</msg>"
|
||||
def answer = "<msg>$n</msg>"
|
||||
|
||||
// set up some directories with stuff
|
||||
def t = tmp.newFolder("t")
|
||||
def dirs = ["a", "b", "c", "c/d", "c/d/e"]
|
||||
dirs.each { p ->
|
||||
def d = new File(t, p)
|
||||
d.mkdir()
|
||||
new File(d,"foo.xml").text = payload
|
||||
}
|
||||
|
||||
// stuff outside
|
||||
def t2 = tmp.newFolder("t2")
|
||||
new File(t2,"foo.xml").text = payload
|
||||
|
||||
// some recursions as well as valid symlinks
|
||||
new FilePath(t).child("c/symlink").symlinkTo("..",st)
|
||||
new FilePath(t).child("b/symlink").symlinkTo(".",st)
|
||||
new FilePath(t).child("a/symlink").symlinkTo(t2.absolutePath,st)
|
||||
|
||||
assert 6==sw.rewriteRecursive(t, st)
|
||||
|
||||
dirs.each { p->
|
||||
assert new File(t,"$p/foo.xml").text.trim()==answer
|
||||
assert new File(backup,"$p/foo.xml").text.trim()==payload
|
||||
}
|
||||
|
||||
// t2 is only reachable by following a symlink. this should be covered, too
|
||||
assert new File(t2,"foo.xml").text.trim()==answer.trim();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,104 +0,0 @@
|
||||
/*
|
||||
* The MIT License
|
||||
*
|
||||
* Copyright (c) 2004-2010, Sun Microsystems, Inc., Kohsuke Kawaguchi
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
package hudson.util
|
||||
|
||||
import com.trilead.ssh2.crypto.Base64;
|
||||
import jenkins.model.Jenkins
|
||||
import jenkins.security.ConfidentialStoreRule;
|
||||
import org.junit.Rule
|
||||
import org.junit.Test
|
||||
|
||||
import javax.crypto.Cipher;
|
||||
|
||||
/**
|
||||
* @author Kohsuke Kawaguchi
|
||||
*/
|
||||
public class SecretTest {
|
||||
@Rule
|
||||
public ConfidentialStoreRule confidentialStore = new ConfidentialStoreRule()
|
||||
|
||||
@Rule
|
||||
public MockSecretRule mockSecretRule = new MockSecretRule()
|
||||
|
||||
@Test
|
||||
void testEncrypt() {
|
||||
def secret = Secret.fromString("abc");
|
||||
assert "abc"==secret.plainText;
|
||||
|
||||
// make sure we got some encryption going
|
||||
println secret.encryptedValue;
|
||||
assert !"abc".equals(secret.encryptedValue);
|
||||
|
||||
// can we round trip?
|
||||
assert secret==Secret.fromString(secret.encryptedValue);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testDecrypt() {
|
||||
assert "abc"==Secret.toString(Secret.fromString("abc"))
|
||||
}
|
||||
|
||||
@Test
|
||||
void testSerialization() {
|
||||
def s = Secret.fromString("Mr.Jenkins");
|
||||
def xml = Jenkins.XSTREAM.toXML(s);
|
||||
assert !xml.contains(s.plainText)
|
||||
assert xml.contains(s.encryptedValue)
|
||||
|
||||
def o = Jenkins.XSTREAM.fromXML(xml);
|
||||
assert o==s : xml;
|
||||
}
|
||||
|
||||
public static class Foo {
|
||||
Secret password;
|
||||
}
|
||||
|
||||
/**
|
||||
* Makes sure the serialization form is backward compatible with String.
|
||||
*/
|
||||
@Test
|
||||
void testCompatibilityFromString() {
|
||||
def tagName = Foo.class.name.replace("\$","_-");
|
||||
def xml = "<$tagName><password>secret</password></$tagName>";
|
||||
def foo = new Foo();
|
||||
Jenkins.XSTREAM.fromXML(xml, foo);
|
||||
assert "secret"==Secret.toString(foo.password)
|
||||
}
|
||||
|
||||
/**
|
||||
* Secret persisted with Jenkins.getSecretKey() should still decrypt OK.
|
||||
*/
|
||||
@Test
|
||||
void migrationFromLegacyKeyToConfidentialStore() {
|
||||
def legacy = Secret.legacyKey
|
||||
["Hello world","","\u0000unprintable"].each { str ->
|
||||
def cipher = Secret.getCipher("AES");
|
||||
cipher.init(Cipher.ENCRYPT_MODE, legacy);
|
||||
def old = new String(Base64.encode(cipher.doFinal((str + Secret.MAGIC).getBytes("UTF-8"))))
|
||||
def s = Secret.fromString(old)
|
||||
assert s.plainText==str : "secret by the old key should decrypt"
|
||||
assert s.encryptedValue!=old : "but when encrypting, ConfidentialKey should be in use"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,37 +0,0 @@
|
||||
package jenkins.security
|
||||
|
||||
import org.junit.Rule
|
||||
import org.junit.Test
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @author Kohsuke Kawaguchi
|
||||
*/
|
||||
class CryptoConfidentialKeyTest {
|
||||
@Rule
|
||||
public ConfidentialStoreRule store = new ConfidentialStoreRule()
|
||||
|
||||
def key = new CryptoConfidentialKey("test")
|
||||
|
||||
@Test
|
||||
void decryptGetsPlainTextBack() {
|
||||
["Hello world","","\u0000"].each { str ->
|
||||
assert key.decrypt().doFinal(key.encrypt().doFinal(str.bytes))==str.bytes
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
void multipleEncryptsAreIdempotent() {
|
||||
def str = "Hello world".bytes
|
||||
assert key.encrypt().doFinal(str)==key.encrypt().doFinal(str)
|
||||
}
|
||||
|
||||
@Test
|
||||
void loadingExistingKey() {
|
||||
def key2 = new CryptoConfidentialKey("test") // this will cause the key to be loaded from the disk
|
||||
["Hello world","","\u0000"].each { str ->
|
||||
assert key2.decrypt().doFinal(key.encrypt().doFinal(str.bytes))==str.bytes
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,54 +0,0 @@
|
||||
package jenkins.security
|
||||
|
||||
import hudson.FilePath
|
||||
import hudson.Functions
|
||||
import hudson.Util
|
||||
import org.junit.After
|
||||
import org.junit.Before
|
||||
import org.junit.Test
|
||||
|
||||
/**
|
||||
* @author Kohsuke Kawaguchi
|
||||
*/
|
||||
public class DefaultConfidentialStoreTest {
|
||||
|
||||
def tmp;
|
||||
|
||||
@Before
|
||||
void setup() {
|
||||
tmp = Util.createTempDir()
|
||||
}
|
||||
|
||||
@After
|
||||
void tearDown() {
|
||||
Util.deleteRecursive(tmp)
|
||||
}
|
||||
|
||||
@Test
|
||||
void roundtrip() {
|
||||
tmp.deleteDir() // let ConfidentialStore create a directory
|
||||
|
||||
def store = new DefaultConfidentialStore(tmp);
|
||||
def key = new ConfidentialKey("test") {};
|
||||
|
||||
// basic roundtrip
|
||||
def str = "Hello world!"
|
||||
store.store(key, str.bytes)
|
||||
assert new String(store.load(key))==str
|
||||
|
||||
// data storage should have some stuff
|
||||
assert new File(tmp,"test").exists()
|
||||
assert new File(tmp,"master.key").exists()
|
||||
|
||||
assert !new File(tmp,"test").text.contains("Hello") // the data shouldn't be a plain text, obviously
|
||||
|
||||
if (!Functions.isWindows())
|
||||
assert (new FilePath(tmp).mode()&0777) == 0700 // should be read only
|
||||
|
||||
// if the master key changes, we should gracefully fail to load the store
|
||||
new File(tmp,"master.key").delete()
|
||||
def store2 = new DefaultConfidentialStore(tmp)
|
||||
assert new File(tmp,"master.key").exists() // we should have a new key now
|
||||
assert store2.load(key)==null;
|
||||
}
|
||||
}
|
||||
@@ -1,39 +0,0 @@
|
||||
package jenkins.security
|
||||
|
||||
import org.junit.Rule
|
||||
import org.junit.Test
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @author Kohsuke Kawaguchi
|
||||
*/
|
||||
class HMACConfidentialKeyTest {
|
||||
@Rule
|
||||
public ConfidentialStoreRule store = new ConfidentialStoreRule()
|
||||
|
||||
def key = new HMACConfidentialKey("test",16)
|
||||
|
||||
@Test
|
||||
void basics() {
|
||||
def unique = [] as TreeSet
|
||||
["Hello world","","\u0000"].each { str ->
|
||||
def mac = key.mac(str)
|
||||
unique.add(mac)
|
||||
assert mac =~ /[0-9A-Fa-f]{32}/
|
||||
assert key.checkMac(str,mac)
|
||||
assert !key.checkMac("garbage",mac)
|
||||
}
|
||||
|
||||
assert unique.size()==3 // make sure all 3 MAC are different
|
||||
}
|
||||
|
||||
@Test
|
||||
void loadingExistingKey() {
|
||||
// this second key of the same ID will cause it to load the key from the disk
|
||||
def key2 = new HMACConfidentialKey("test",16)
|
||||
["Hello world","","\u0000"].each { str ->
|
||||
assert key.mac(str)==key2.mac(str)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,43 +0,0 @@
|
||||
package jenkins.security
|
||||
|
||||
import org.junit.Rule
|
||||
import org.junit.Test
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @author Kohsuke Kawaguchi
|
||||
*/
|
||||
class HexStringConfidentialKeyTest {
|
||||
@Rule
|
||||
public ConfidentialStoreRule store = new ConfidentialStoreRule()
|
||||
|
||||
@Test
|
||||
void hexStringShouldProduceHexString() {
|
||||
def key = new HexStringConfidentialKey("test",8)
|
||||
assert key.get() =~ /[A-Fa-f0-9]{8}/
|
||||
}
|
||||
|
||||
@Test
|
||||
void multipleGetsAreIdempotent() {
|
||||
def key = new HexStringConfidentialKey("test",8)
|
||||
assert key.get()==key.get()
|
||||
}
|
||||
|
||||
@Test
|
||||
void specifyLengthAndMakeSureItTakesEffect() {
|
||||
[8,16,32,256].each { n ->
|
||||
new HexStringConfidentialKey("test"+n,n).get().length()==n
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
void loadingExistingKey() {
|
||||
def key1 = new HexStringConfidentialKey("test",8)
|
||||
key1.get() // this causes the ke to be generated
|
||||
|
||||
// this second key of the same ID will cause it to load the key from the disk
|
||||
def key2 = new HexStringConfidentialKey("test",8)
|
||||
assert key1.get()==key2.get()
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user