diff --git a/documentation/manual/production.textile b/documentation/manual/production.textile index 9876b0063f..8101005e2b 100644 --- a/documentation/manual/production.textile +++ b/documentation/manual/production.textile @@ -189,7 +189,8 @@ bc. # X509 certificates certificate.key.file=conf/host.key certificate.file=conf/host.cert # In case your key file is password protected -certificate.password=secret +# certificate.key.file=conf/host.pass.key +# certificate.password=secret trustmanager.algorithm=JKS If you are using keystore: @@ -202,8 +203,13 @@ Note that the values above are the default values. You can generate self-signed certificates using *openssl*: -bc. openssl genrsa 1024 > host.key -openssl req -new -x509 -nodes -sha1 -days 365 -key host.key > host.cert +bc. openssl genrsa -des3 -passout pass:secret -out host.pass.key 2048 +openssl rsa -passin pass:secret -in host.pass.key -out host.key +openssl req -new -key host.key -out host.csr -subj '/C=GB/ST=Test State or Province/L=Test Locality/O=Organization Name/OU=Organizational Unit Name/CN=Common Name/emailAddress=test@email.address' +openssl x509 -req -days 3650 -in host.csr -signkey host.key -out host.cert + +note. the first command creates a password-protected-key ('host.pass.key'). +the second command converts/writes the same key ('host.key') without password protection. If you are using the Java keystore mechanism, then the following properties can be configured in your @application.conf@ file: diff --git a/framework/dependencies.yml b/framework/dependencies.yml index 39227487a5..75f9f0364e 100644 --- a/framework/dependencies.yml +++ b/framework/dependencies.yml @@ -42,7 +42,8 @@ require: &allDependencies - oauth.signpost -> signpost-core 1.2.1.2 - org.apache.geronimo.specs -> geronimo-servlet_2.5_spec 1.2 - org.apache.ivy -> ivy 2.4.0 - - org.bouncycastle -> bcprov-jdk15 1.46 + - org.bouncycastle -> bcprov-jdk15on 1.57 + - org.bouncycastle -> bcpkix-jdk15on 1.57 - org.codehaus.groovy -> groovy-all 2.4.11 - org.eclipse.jdt.core 3.12.3 - org.hibernate -> hibernate-core 5.2.10.patched diff --git a/framework/lib/bcpkix-jdk15on-1.57.jar b/framework/lib/bcpkix-jdk15on-1.57.jar new file mode 100644 index 0000000000..5ce7d5c5cc Binary files /dev/null and b/framework/lib/bcpkix-jdk15on-1.57.jar differ diff --git a/framework/lib/bcprov-jdk15-1.46.jar b/framework/lib/bcprov-jdk15-1.46.jar deleted file mode 100644 index daa0b54cc0..0000000000 Binary files a/framework/lib/bcprov-jdk15-1.46.jar and /dev/null differ diff --git a/framework/lib/bcprov-jdk15on-1.57.jar b/framework/lib/bcprov-jdk15on-1.57.jar new file mode 100644 index 0000000000..5a10986b3a Binary files /dev/null and b/framework/lib/bcprov-jdk15on-1.57.jar differ diff --git a/framework/src/play/server/ssl/SslHttpServerContextFactory.java b/framework/src/play/server/ssl/SslHttpServerContextFactory.java index 7f0642462f..e123209861 100644 --- a/framework/src/play/server/ssl/SslHttpServerContextFactory.java +++ b/framework/src/play/server/ssl/SslHttpServerContextFactory.java @@ -1,19 +1,24 @@ package play.server.ssl; +import org.bouncycastle.jcajce.provider.asymmetric.x509.CertificateFactory; import org.bouncycastle.jce.provider.BouncyCastleProvider; -import org.bouncycastle.openssl.PEMReader; -import org.bouncycastle.openssl.PasswordFinder; +import org.bouncycastle.openssl.PEMDecryptorProvider; +import org.bouncycastle.openssl.PEMEncryptedKeyPair; +import org.bouncycastle.openssl.PEMKeyPair; +import org.bouncycastle.openssl.PEMParser; +import org.bouncycastle.openssl.jcajce.JcaPEMKeyConverter; +import org.bouncycastle.openssl.jcajce.JcePEMDecryptorProviderBuilder; import play.Logger; import play.Play; import javax.net.ssl.*; +import java.io.File; import java.io.FileInputStream; import java.io.FileReader; import java.net.Socket; import java.security.*; import java.security.cert.X509Certificate; -import java.util.ArrayList; -import java.util.List; +import java.util.Collection; import java.util.Properties; public class SslHttpServerContextFactory { @@ -84,18 +89,22 @@ public PEMKeyManager() { final Properties p = Play.configuration; String keyFile = p.getProperty("certificate.key.file", "conf/host.key"); - try (PEMReader keyReader = new PEMReader(new FileReader(Play.getFile(keyFile)), new PEMPasswordFinder())) { - key = ((KeyPair) keyReader.readObject()).getPrivate(); - - try (PEMReader reader = new PEMReader(new FileReader(Play.getFile(p.getProperty("certificate.file", "conf/host.cert"))))) { - X509Certificate cert; - List chainVector = new ArrayList<>(); - - while ((cert = (X509Certificate) reader.readObject()) != null) { - chainVector.add(cert); - } - chain = chainVector.toArray(new X509Certificate[1]); + try (PEMParser keyReader = new PEMParser(new FileReader(Play.getFile(keyFile)))) { + final Object object = keyReader.readObject(); + JcaPEMKeyConverter converter = new JcaPEMKeyConverter().setProvider("BC"); + final KeyPair keyPair; + if (object instanceof PEMEncryptedKeyPair) { + PEMDecryptorProvider decProv = new JcePEMDecryptorProviderBuilder() + .build(Play.configuration.getProperty("certificate.password", "secret").toCharArray()); + keyPair = converter.getKeyPair(((PEMEncryptedKeyPair) object).decryptKeyPair(decProv)); + } else { + keyPair = converter.getKeyPair((PEMKeyPair) object); } + key = keyPair.getPrivate(); + + final File hostCertFile = Play.getFile(p.getProperty("certificate.file", "conf/host.cert")); + final Collection collection = new CertificateFactory().engineGenerateCertificates(new FileInputStream(hostCertFile)); + chain = (X509Certificate[]) collection.toArray(new X509Certificate[collection.size()]); } catch (Exception e) { Logger.error(e, "Failed to initialize PEMKeyManager from file %s", keyFile); } @@ -136,12 +145,4 @@ public PrivateKey getPrivateKey(String s) { return key; } } - - private static class PEMPasswordFinder implements PasswordFinder { - @Override - public char[] getPassword() { - return Play.configuration.getProperty("certificate.password", "secret").toCharArray(); - } - } - } diff --git a/resources/application-skel/conf/application.conf b/resources/application-skel/conf/application.conf index 636be241fc..f2264fa261 100644 --- a/resources/application-skel/conf/application.conf +++ b/resources/application-skel/conf/application.conf @@ -231,6 +231,16 @@ mail.smtp=mock # For SSL, use the play.ssl.netty.pipeline property # play.ssl.netty.pipeline = play.server.FlashPolicyHandler,org.jboss.netty.handler.codec.http.HttpRequestDecoder,play.server.StreamChunkAggregator,org.jboss.netty.handler.codec.http.HttpResponseEncoder,org.jboss.netty.handler.codec.http.HttpContentCompressor,org.jboss.netty.handler.stream.ChunkedWriteHandler,play.server.ssl.SslPlayHandler +# # X509 certificates +# # the following values are default values +# certificate.key.file=conf/host.key +# # certificate.password used only if certificate.key.file is password protected +# certificate.password=secret +# certificate.file=conf/host.cert +# trustmanager.algorithm=JKS +# keystore.algorithm=JKS +# keystore.password=secret +# keystore.file=conf/certificate.jks # Open file from errors pages # ~~~~~ diff --git a/samples-and-tests/i-am-a-developer/tests.py b/samples-and-tests/i-am-a-developer/tests.py index cdca8268b8..b70784b48e 100755 --- a/samples-and-tests/i-am-a-developer/tests.py +++ b/samples-and-tests/i-am-a-developer/tests.py @@ -1,20 +1,179 @@ #!/usr/bin/python -import unittest import os import shutil -import sys +import ssl import subprocess -import re +import sys +import threading import time +import unittest import urllib2 + import mechanize -import threading + # --- TESTS class IamADeveloper(unittest.TestCase): - + + def testSSLConfig(self): + + # Testing ssl config + step('Hello, I am testing SSL config') + + self.working_directory = bootstrapWorkingDirectory('i-am-testing-ssl-config-here') + + # play new job-app + step('Create a new project') + + self.play = callPlay(self, ['new', '%s/sslconfigapp' % self.working_directory, '--name=SSLCONFIGAPP']) + self.assert_(waitFor(self.play, 'The new application will be created')) + self.assert_(waitFor(self.play, 'OK, the application is created')) + self.assert_(waitFor(self.play, 'Have fun!')) + + self.play.wait() + + app = '%s/sslconfigapp' % self.working_directory + + step('Add config and files') + insert(app, "app/controllers/Application.java", 13, ' Logger.info("I am ssl secured!");') + + edit(app, "conf/application.conf", 32, 'http.port=-1') + edit(app, "conf/application.conf", 33, 'https.port=9000') + edit(app, "conf/application.conf", 232, + 'play.ssl.netty.pipeline = play.server.FlashPolicyHandler,org.jboss.netty.handler.codec.http.HttpRequestDecoder,play.server.StreamChunkAggregator,org.jboss.netty.handler.codec.http.HttpResponseEncoder,org.jboss.netty.handler.codec.http.HttpContentCompressor,org.jboss.netty.handler.stream.ChunkedWriteHandler,play.server.ssl.SslPlayHandler') + create(app, 'conf/host.key') + insert(app, "conf/host.key", 1, '-----BEGIN RSA PRIVATE KEY-----') + insert(app, "conf/host.key", 2, 'MIIEpQIBAAKCAQEAoOx9pCR7rZ50S9FotKVD2+aC36Hj4TkXZTZwEnh/fWyuiH2O') + insert(app, "conf/host.key", 3, 'Paj/dTw60Jvll4jshlnRHfJ6yfc/o7YlDUanLrQJm7I3/t3YNgqYg3WXeUTl+GrN') + insert(app, "conf/host.key", 4, 'Hn/3QgFGYqKobu8kfrwP4IapQRqlq4ZSdlR/bWpxnYSCZoXeeoimoSUcLlqD5dw7') + insert(app, "conf/host.key", 5, '7v2BlG2gqL5+lr5Fx4mDC12vczoUMRg88+VuA1ezU4cuXDe2MbpJMd7rqGN0xK4b') + insert(app, "conf/host.key", 6, 'CwkFtSJqBM1TH/Czr1S52hKrDTTys9PVw+eZSKO7BCk+PDq5jjx337XOWiO0kSHf') + insert(app, "conf/host.key", 7, 'V64x68xTojfzTzF304byr2Ytq6DjNbpZKwdYBwIDAQABAoIBAQCc6z7w6mp3uIWq') + insert(app, "conf/host.key", 8, '0P6K+ISdT7/aliCCJIu9tEHAoSOgiHQAwH4NflfsV9j6RqqxA2Gw+LBDxYkanDDA') + insert(app, "conf/host.key", 9, 'UQL8WSL5FbIw0q5rpqQIvnhN6ELWi+q8PFjcHuhawqeB0x7vXd52fqf0xxsQUw2t') + insert(app, "conf/host.key", 10, 'noOWw3qmlR9I/Eez9WImlk314RwDzc/bUsfBQhMKbNVHxstR8Q9YQQMp+xb9dqbL') + insert(app, "conf/host.key", 11, '3lfz3O70Q/Xc/JxXIOkqcfyoIT9CvpJf2MT1tkd1xolAV+4UJQwKQURlMKqcp7Yi') + insert(app, "conf/host.key", 12, 'NIxqv27ZGuhdzPCSFy3zcCIYMxXVvU+oSncGMlBpyf8ONDH2wZ7/nOtaz4Kf9tNZ') + insert(app, "conf/host.key", 13, 'ZcqtXd1RAoGBAM7DFMBd78hkJhLztXO5PqB3O87f438aDlQfIGDzi9/KD+Jy1TRz') + insert(app, "conf/host.key", 14, 'tJMLjmhPIOuy477k6+P3MmF3KeIjFzZg2Je56++rdpdX+E09Ts4s1gZkUAAfEyeI') + insert(app, "conf/host.key", 15, 'QJ53lrXJu0ShmXODSyEc+rtaUgsM0geL7EtacmrUQQI9yKbrUHmHw0glAoGBAMc+') + insert(app, "conf/host.key", 16, '9D13ne8bFLQ7upY6GuidgvG+ilAKaJ1YWNWjolTIV86RCEYNmgqxF0BzGT2Db55L') + insert(app, "conf/host.key", 17, 'Myt5epDOKJr0RRi7ddidUJFOAOfm/yciPbr+D34LCnj6rkdauAhYsjfjuWDNLHyf') + insert(app, "conf/host.key", 18, 'hjpBvvtMfqWE79vfIwVCKOy9xUVjqfZY2KDBu4G7AoGBAMSmjooXzgOOHRhRavdR') + insert(app, "conf/host.key", 19, '7Nq6DMxJ7RnqMk6X/De57ANBL7J0/YsRsWFZ0GwtNmZ2kl3xZNpBNk21BMTsExvJ') + insert(app, "conf/host.key", 20, 'KLfGQTyGnBh9ts/fy6AUzMrvhZdX9uPWl38gxtrHr7Eq8cQHz+ECqwaedQHFg81h') + insert(app, "conf/host.key", 21, 'q7BPqhspHVuAX+NCVBwCoB1xAoGBAME20mC9G6GgUE6LUWCXDjsfa7kEPlpqDZLv') + insert(app, "conf/host.key", 22, '9o2ONkAjW8sMJ8rPK99MZjDwrLxTNi153TA+iFXeJdBGKq9WMmyR+Ww/CW/ZOPt5') + insert(app, "conf/host.key", 23, 'IAWyk9F14Xz6E4FMfwRRBtpd8gnmTUq449CgqxRE1Ner93Hvi6VwyADz8lZc1Jf5') + insert(app, "conf/host.key", 24, 'BnG2DSA7AoGAAWRtgCEkhR/9GyLyAqoUd45FQdRdwIiDwRUsuazSMF2g+FSIfXqR') + insert(app, "conf/host.key", 25, 'MgEidXuKYTIRgsiDmgy6fy3XkSzaR1ehjC1uUyyiUzEd+guG9tURrRygR8S6VGw3') + insert(app, "conf/host.key", 26, 'mxX+1gneJnzA2cBminkc28ohIQegHEqKKif5gRsc2md+LsvDNR93io4=') + insert(app, "conf/host.key", 27, '-----END RSA PRIVATE KEY-----') + create(app, 'conf/host.pass.key') + insert(app, "conf/host.pass.key", 1, '-----BEGIN RSA PRIVATE KEY-----') + insert(app, "conf/host.pass.key", 2, 'Proc-Type: 4,ENCRYPTED') + insert(app, "conf/host.pass.key", 3, 'DEK-Info: DES-EDE3-CBC,FC6F4AA83014298F') + insert(app, "conf/host.pass.key", 4, '') + insert(app, "conf/host.pass.key", 5, 'ZxpC4NYQsMYCOfpMg3iRbQ5UQDBp50NGnT+wBgHnhTqXVUsIZ0x4eFvFKmIoGFne') + insert(app, "conf/host.pass.key", 6, 'hX2pnIMFpOJs4tRIItFyvjcwAARRZxg9KCkjL8cPBhNL4LNExYOTKE8QfTzTb9/l') + insert(app, "conf/host.pass.key", 7, 'DoF5EJraNwvXKlVNh9wrROW7oMJFqhkVRQN+lMnczTGPznnjbBvOr69ypU8/NWX/') + insert(app, "conf/host.pass.key", 8, 'JFgLYqBUnOPUKCaqxEuNzP632jOkhSdXmtl4ft1JFx/uoJG4rCGw5zOVHnTsCMbs') + insert(app, "conf/host.pass.key", 9, 'aWfzfYgnreKvSmwk+5J/0aHR14sXoJpPOk1KvJ3U347cJ/RB1hnnShAdEmYxqPmc') + insert(app, "conf/host.pass.key", 10, '7Hp2BXt86qlFs9SEBwptPtGmF+YAW7HdcgU0M1ONJ0/GysT4RWFJr5VO4QQWpQT/') + insert(app, "conf/host.pass.key", 11, 'DrX8odwKVSQHekmsJz4hD0CXj2v8KU7crbEtTemj3koxnbEn7gcZoGtTMmz37hZS') + insert(app, "conf/host.pass.key", 12, 'qJOolpPqHFV7WtheZ/+5ztSJ91eUgRqKTt1gLgQ6wbaCFfgsPIIRAjuklWnAyKxM') + insert(app, "conf/host.pass.key", 13, '0dxRb7pTCDLewZ7V2g9MzkF46r+eTCIw31NJC6EUsOYaj46bYbmdK5Smjqgc1z5S') + insert(app, "conf/host.pass.key", 14, 'jQGSFUUA+MRlLhx0e/old3fK1oUY1kujcDZcz57arykFDxNHSseFIauJOUeiw0Tp') + insert(app, "conf/host.pass.key", 15, '5nZJYtg4yWTEbLMi+iegu/pYZSbuy8APojIgPupg0FiFOED23J2ziXQs8ZxaG7w6') + insert(app, "conf/host.pass.key", 16, 'oc6SxWrubxCGt0dlEHAQnAB5eVZGcKCH4hVaF4w85j/oWf0Tw/kFAD1MqyiBPes3') + insert(app, "conf/host.pass.key", 17, 'BcrDyO4AJWpmocMZ5ERVkPhx1rqyRrpaYBMdTJ2LoQaKIGeDucfW3Iap0mk+jT31') + insert(app, "conf/host.pass.key", 18, 'RTVYNlCqoU1+oACqpV4mRQGW0BDIENvazCb+VJ0qHkedrM/Bx0Gxnx7jrlptOYEn') + insert(app, "conf/host.pass.key", 19, '2rU53bOIdwGw9+MjDV+jLKnxuwh56SI5wJzSBCr38jLlA/SgPDM+8K9AjeCJg0w5') + insert(app, "conf/host.pass.key", 20, 'C4Na4pDa3tSRwV2WsDJcLnWN+L1NoFNNMnePGzZHCBWaFI9WM2sZI5LsM+gZt37k') + insert(app, "conf/host.pass.key", 21, 'EnR/r8rn5Vig7hwxntW7D6IAka2Tkfl0Y+uvl373EGIv9d61/x6cxomPbYGwH0Sn') + insert(app, "conf/host.pass.key", 22, '6Emz3so5pXUuP8w2Gx7FNI9m7r+xOAfe87Eplc5DZiwtWyeSLOKDOnkwTxNdFMhk') + insert(app, "conf/host.pass.key", 23, 'GerNKG4RrMB5GEU0oI1rkMPlK4vf/K9ynHqLq5HjH839EzWH7aeqlo8059WMZ0Jz') + insert(app, "conf/host.pass.key", 24, 'qecDXcEZ2K9RkUPqGC2wdAGTyea/ElEWmplAWfqVHkD497IShQfTgJ23oLxFTDhd') + insert(app, "conf/host.pass.key", 25, 'IUso3Xj50N1U2+4JbYABv9zaXLRK+qTEPkTmeQHo+CJC0iIVQwGtQS9p3IcuLzKd') + insert(app, "conf/host.pass.key", 26, 's3wqL1Durxe+YVfHNqTYh2uC6eclSwA/21uDa59B37oK9Aymdzujps7IJQ147QWN') + insert(app, "conf/host.pass.key", 27, '4e39vDDrfPMthKiQAWm4f3+vduLxzShDgzLyVPDaYVfPAlD7UETz0x6eNCTZXDjg') + insert(app, "conf/host.pass.key", 28, 'S4JMnjhH8EFrzKdnUH40oeWa9RKKo5RwvRRRGNgR23OzcibI+54kl5DsMTI229+G') + insert(app, "conf/host.pass.key", 29, 'PDd5V4m+ahdfaPsM9DMr1mWGSN/hoLDJtMFPOiZP5R6OSTi99Tj5KJiglSdjmb6u') + insert(app, "conf/host.pass.key", 30, '-----END RSA PRIVATE KEY-----') + create(app, 'conf/host.cert') + insert(app, "conf/host.cert", 1, '-----BEGIN CERTIFICATE-----') + insert(app, "conf/host.cert", 2, 'MIID4DCCAsgCCQCdj5qAy7MGoTANBgkqhkiG9w0BAQsFADCBsTEfMB0GA1UECAwW') + insert(app, "conf/host.cert", 3, 'VGVzdCBTdGF0ZSBvciBQcm92aW5jZTEWMBQGA1UEBwwNVGVzdCBMb2NhbGl0eTEa') + insert(app, "conf/host.cert", 4, 'MBgGA1UECgwRT3JnYW5pemF0aW9uIE5hbWUxITAfBgNVBAsMGE9yZ2FuaXphdGlv') + insert(app, "conf/host.cert", 5, 'bmFsIFVuaXQgTmFtZTEUMBIGA1UEAwwLQ29tbW9uIE5hbWUxITAfBgkqhkiG9w0B') + insert(app, "conf/host.cert", 6, 'CQEWEnRlc3RAZW1haWwuYWRkcmVzczAeFw0xNzA1MjkxMjUyMDVaFw0yNzA1Mjcx') + insert(app, "conf/host.cert", 7, 'MjUyMDVaMIGxMR8wHQYDVQQIDBZUZXN0IFN0YXRlIG9yIFByb3ZpbmNlMRYwFAYD') + insert(app, "conf/host.cert", 8, 'VQQHDA1UZXN0IExvY2FsaXR5MRowGAYDVQQKDBFPcmdhbml6YXRpb24gTmFtZTEh') + insert(app, "conf/host.cert", 9, 'MB8GA1UECwwYT3JnYW5pemF0aW9uYWwgVW5pdCBOYW1lMRQwEgYDVQQDDAtDb21t') + insert(app, "conf/host.cert", 10, 'b24gTmFtZTEhMB8GCSqGSIb3DQEJARYSdGVzdEBlbWFpbC5hZGRyZXNzMIIBIjAN') + insert(app, "conf/host.cert", 11, 'BgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAoOx9pCR7rZ50S9FotKVD2+aC36Hj') + insert(app, "conf/host.cert", 12, '4TkXZTZwEnh/fWyuiH2OPaj/dTw60Jvll4jshlnRHfJ6yfc/o7YlDUanLrQJm7I3') + insert(app, "conf/host.cert", 13, '/t3YNgqYg3WXeUTl+GrNHn/3QgFGYqKobu8kfrwP4IapQRqlq4ZSdlR/bWpxnYSC') + insert(app, "conf/host.cert", 14, 'ZoXeeoimoSUcLlqD5dw77v2BlG2gqL5+lr5Fx4mDC12vczoUMRg88+VuA1ezU4cu') + insert(app, "conf/host.cert", 15, 'XDe2MbpJMd7rqGN0xK4bCwkFtSJqBM1TH/Czr1S52hKrDTTys9PVw+eZSKO7BCk+') + insert(app, "conf/host.cert", 16, 'PDq5jjx337XOWiO0kSHfV64x68xTojfzTzF304byr2Ytq6DjNbpZKwdYBwIDAQAB') + insert(app, "conf/host.cert", 17, 'MA0GCSqGSIb3DQEBCwUAA4IBAQAw+cuEp3wbLcTIzKCrZ7KzH3zaMtzIU5ZAjTkt') + insert(app, "conf/host.cert", 18, '66QSFALq/ZvAswAybpWKb+2EZZ8iV477W0nFJUkHIOrOav4qWJfmPtdp2k6d2Eey') + insert(app, "conf/host.cert", 19, 'cYQjrD9ghV7aKtKCstFdXo4h23FNaKb+kHSXjvEuf8EuDWilXKrjczmJAmGpBeSE') + insert(app, "conf/host.cert", 20, 'nUVGGYYMAKf+ndkuSYYnJs/V823o9npSiy0Ke83Z64Co04+yos+BMIuDIhP/+LOp') + insert(app, "conf/host.cert", 21, 'pesqro66VwKswcG9O/sjSCaiFgljlQARB4xKBSwR5py8hKDBKfoWnvCpaFPLS34P') + insert(app, "conf/host.cert", 22, 'rGPQp900aMtDjORTe2ZP2EP/rMSm7w/PL8djNVMtgFKzY2Tc') + insert(app, "conf/host.cert", 23, '-----END CERTIFICATE-----') + + + # Run the newly created application + step('Run our ssl-application') + + self.play = callPlay(self, ['run', app]) + #wait for play to be ready + self.assert_(waitFor(self.play, 'Listening for HTTPS on port 9000')) + + step("Send request to https") + + browser = mechanize.Browser() + response = browser.open('https://localhost:9000/') + + step("check that ssl message is logged") + self.assert_(waitFor(self.play, 'I am ssl secured!')) + + step("stop play") + killPlay('https') + self.play.wait() + + #now we're going to manually configure log4j to log debug messages + step('using key file with password') + + insert(app, "conf/application.conf", 236, + 'certificate.key.file = conf/host.pass.key') + + # re-run the application with new setting + step('re-run our ssl-application') + + self.play = callPlay(self, ['run', app]) + #wait for play to be ready + self.assert_(waitFor(self.play, 'Listening for HTTPS on port 9000')) + + step("Send request to https") + + browser = mechanize.Browser() + response = browser.open('https://localhost:9000/') + + step("check that ssl message is logged") + self.assert_(waitFor(self.play, 'I am ssl secured!')) + + step("stop play") + killPlay('https') + self.play.wait() + + step("done testing ssl config") + def testLogLevelsAndLog4jConfig(self): # Testing job developing @@ -80,8 +239,7 @@ def testLogLevelsAndLog4jConfig(self): insert(app, "conf/log4j.xml", 15, ' ') insert(app, "conf/log4j.xml", 16, ' ') insert(app, "conf/log4j.xml", 17, '') - - + # Run the newly created application step('re-run our logger-application') @@ -689,9 +847,9 @@ def timeout(process): killPlay() timeoutOccurred = True -def killPlay(): +def killPlay(http = 'http'): try: - urllib2.urlopen('http://localhost:9000/@kill') + urllib2.urlopen('%s://localhost:9000/@kill' % http) except: pass @@ -748,4 +906,13 @@ def rename(app, fro, to): os.rename(os.path.join(app, fro), os.path.join(app, to)) if __name__ == '__main__': + # thanks to: https://stackoverflow.com/a/35960702/3221476 + try: + _create_unverified_https_context = ssl._create_unverified_context + except AttributeError: + # Legacy Python that doesn't verify HTTPS certificates by default + pass + else: + # Handle target environment that doesn't support HTTPS verification + ssl._create_default_https_context = _create_unverified_https_context unittest.main()