From abe0e58888ffcfd79ed5e2343593e6df5dd6bb91 Mon Sep 17 00:00:00 2001 From: Will Sargent Date: Mon, 7 Jul 2014 00:36:05 -0700 Subject: [PATCH 01/53] Initial commit --- .gitignore | 16 ++ LICENSE | 13 + README.md | 238 +++++++++++++++++ activator | 336 ++++++++++++++++++++++++ activator.properties | 5 + app/Main.scala | 53 ++++ app/controllers/Application.scala | 12 + app/https/CustomSSLEngineProvider.scala | 86 ++++++ app/views/index.scala.html | 8 + build.sbt | 18 ++ conf/application.conf | 18 ++ conf/disabledAlgorithms.properties | 23 ++ conf/routes | 9 + conf/ws.conf | 27 ++ play | 62 +++++ project/build.properties | 4 + project/plugins.sbt | 18 ++ scripts/genca.sh | 25 ++ scripts/gencerts.sh | 11 + scripts/genclient.sh | 87 ++++++ scripts/genserver.sh | 60 +++++ scripts/gentrustanchor.sh | 19 ++ tutorial/index.html | 51 ++++ 23 files changed, 1199 insertions(+) create mode 100644 .gitignore create mode 100644 LICENSE create mode 100644 README.md create mode 100755 activator create mode 100644 activator.properties create mode 100644 app/Main.scala create mode 100644 app/controllers/Application.scala create mode 100644 app/https/CustomSSLEngineProvider.scala create mode 100644 app/views/index.scala.html create mode 100644 build.sbt create mode 100644 conf/application.conf create mode 100644 conf/disabledAlgorithms.properties create mode 100644 conf/routes create mode 100644 conf/ws.conf create mode 100755 play create mode 100644 project/build.properties create mode 100644 project/plugins.sbt create mode 100755 scripts/genca.sh create mode 100755 scripts/gencerts.sh create mode 100755 scripts/genclient.sh create mode 100755 scripts/genserver.sh create mode 100755 scripts/gentrustanchor.sh create mode 100644 tutorial/index.html diff --git a/.gitignore b/.gitignore new file mode 100644 index 000000000..905203716 --- /dev/null +++ b/.gitignore @@ -0,0 +1,16 @@ +logs +project/project +project/target +target +tmp +.history +dist +/.idea +/*.iml +/out +/certs +/.idea_modules +/.classpath +/.project +/RUNNING_PID +/.settings diff --git a/LICENSE b/LICENSE new file mode 100644 index 000000000..b8dd751c9 --- /dev/null +++ b/LICENSE @@ -0,0 +1,13 @@ +Copyright 2014 Typesafe, Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + +http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. \ No newline at end of file diff --git a/README.md b/README.md new file mode 100644 index 000000000..c83384cc4 --- /dev/null +++ b/README.md @@ -0,0 +1,238 @@ +# Example Play TLS Application + +This application shows how to use Play with SSL/TLS, using the Java Secure Socket Extension (JSSE) API. + +## Requirements + +You must have JDK 1.8 installed on your machine to run this, to take advantage of the new [security enhancements in JSSE](http://blog.ivanristic.com/2014/03/ssl-tls-improvements-in-java-8.html). + +## Generate Certificates + +To use HTTPS, you must have X.509 certificates. Generating certificates can be painful, so all the scripts needed to generate the certificates needed are included in the `certs` directory. For more detail, you can see the [Certificate Generation](http://www.playframework.com/documentation/2.3.x/CertificateGeneration) section in Play WS SSL. + +To generate certificates, run: + +``` +cd scripts/ +./gencerts.sh +``` + +and move all of the generated files into the `certs` directory: + +``` +cd scripts +mkdir ../certs +mv client* ../certs +mv example* ../certs +mv password ../certs +``` + +## Point example.com to localhost + +You may have noticed that the name on the generated certificates is `example.com` -- HTTPS requires that you have a reasonable hostname for your server. + +Rather than setting up a DNS entry or a remote server, we'll modify `/etc/hosts` to point to the local directory. + +``` +$ sudo /etc/hosts +``` + +``` +127.0.0.1 example.com www.example.com +``` + +## Run Play with HTTPS configuration + +Now that you've generated the certificates and added `example.com` to `/etc/hosts`, you can start Play itself. + +This application is not run with `activator` -- you should run it with `./play` instead, as there are a number of system properties required to use it effectively. + +[Configuring HTTPS](http://www.playframework.com/documentation/2.3.x/ConfiguringHttps) + +``` +./play run +``` + +## Checking the list of cipher suites: + +Download SSLyze: + +[https://github.com/iSECPartners/sslyze/releases](https://github.com/iSECPartners/sslyze/releases) + +And then run SSLyze against the play application: + +``` +cd sslyze-0_9-osx64 +python sslyze.py --regular www.example.com:9443 +``` + +You should see results like: + +``` + REGISTERING AVAILABLE PLUGINS + ----------------------------- + + PluginOpenSSLCipherSuites + PluginCertInfo + PluginCompression + PluginHSTS + PluginHeartbleed + PluginSessionRenegotiation + PluginSessionResumption + + + + CHECKING HOST(S) AVAILABILITY + ----------------------------- + + www.example.com:9443 => 127.0.0.1:9443 + + + + SCAN RESULTS FOR WWW.EXAMPLE.COM:9443 - 127.0.0.1:9443 + ------------------------------------------------------ + + * Session Renegotiation: + Client-initiated Renegotiations: Rejected + Secure Renegotiation: Supported + + * Compression: + DEFLATE Compression: Disabled + + * Heartbleed: + OpenSSL Heartbleed: NOT vulnerable + +Unhandled exception when processing --certinfo: +exceptions.KeyError - 'exponent' + + * Session Resumption: + With Session IDs: Not supported (0 successful, 5 failed, 0 errors, 5 total attempts). + With TLS Session Tickets: Not Supported - TLS ticket not assigned. + + * SSLV2 Cipher Suites: + Server rejected all cipher suites. + + * TLSV1_2 Cipher Suites: + Preferred: + ECDHE-ECDSA-AES256-SHA384 256 bits HTTP 200 OK + Accepted: + ECDHE-ECDSA-AES256-SHA384 256 bits HTTP 200 OK + ECDHE-ECDSA-AES256-SHA 256 bits HTTP 200 OK + ECDHE-ECDSA-AES256-GCM-SHA384 256 bits HTTP 200 OK + ECDHE-ECDSA-DES-CBC3-SHA 168 bits HTTP 200 OK + ECDHE-ECDSA-RC4-SHA 128 bits HTTP 200 OK + ECDHE-ECDSA-AES128-SHA256 128 bits HTTP 200 OK + ECDHE-ECDSA-AES128-SHA 128 bits HTTP 200 OK + ECDHE-ECDSA-AES128-GCM-SHA256 128 bits HTTP 200 OK + + * TLSV1_1 Cipher Suites: + Preferred: + ECDHE-ECDSA-AES256-SHA 256 bits HTTP 200 OK + Accepted: + ECDHE-ECDSA-AES256-SHA 256 bits HTTP 200 OK + ECDHE-ECDSA-DES-CBC3-SHA 168 bits HTTP 200 OK + ECDHE-ECDSA-RC4-SHA 128 bits HTTP 200 OK + ECDHE-ECDSA-AES128-SHA 128 bits HTTP 200 OK + + * TLSV1 Cipher Suites: + Preferred: + ECDHE-ECDSA-AES256-SHA 256 bits HTTP 200 OK + Accepted: + ECDHE-ECDSA-AES256-SHA 256 bits HTTP 200 OK + ECDHE-ECDSA-DES-CBC3-SHA 168 bits HTTP 200 OK + ECDHE-ECDSA-RC4-SHA 128 bits HTTP 200 OK + ECDHE-ECDSA-AES128-SHA 128 bits HTTP 200 OK + + * SSLV3 Cipher Suites: + Preferred: + ECDHE-ECDSA-AES256-SHA 256 bits HTTP 200 OK + Accepted: + ECDHE-ECDSA-AES256-SHA 256 bits HTTP 200 OK + ECDHE-ECDSA-DES-CBC3-SHA 168 bits HTTP 200 OK + ECDHE-ECDSA-RC4-SHA 128 bits HTTP 200 OK + ECDHE-ECDSA-AES128-SHA 128 bits HTTP 200 OK + + + + SCAN COMPLETED IN 9.51 S + ------------------------ + ``` + +## Turning on Client Authentication + +Now that you've verified that the server is running and can speak HTTPS, go into `./play` and change the `play.ssl.needClientAuth` setting from `false` to `true`. Then restart the server. You should see + +``` + ECDHE-ECDSA-RC4-SHA ClientCertificateRequested - Server requested a client certificate issued by one of the following CAs: '/C=US/ST=California/L=San Francisco/O=Example Company/OU=Example Org/CN=clientca'. +``` + +Now that the server requires client authentication, a client must now provide a certificate signed by the `clientca` root certificate before a connection can be established. + +## Connecting to the server with Play WS + +Fortunately, we happen to have [Play WS](http://www.playframework.com/documentation/2.3.x/ScalaWS), an HTTP client library that can use [TLS client authentication](http://www.playframework.com/documentation/2.3.x/WsSSL). + +The `ws.conf` script looks like this: + +``` +ws.ssl { + + protocol = "TLSv1.2" + + enabledProtocols = [ "TLSv1.2" ] + + enabledCiphers = [ + "TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384" + ] + + ws.ssl.disabledSignatureAlgorithms = "MD2, MD4, MD5, SHA1, RSA" + + ws.ssl.disabledKeyAlgorithms = "EC keySize < 384" + + keyManager = { + stores = [ + // Note: app must be run from ./play, which loads the KEY_PASSWORD environment variable. + { type: "JKS", path: "certs/client.jks", password: ${?KEY_PASSWORD} }, + ] + } + + trustManager = { + stores = [ + { type = "JKS", path = "certs/exampletrust.jks" } + ] + } +} + +``` + +Normally you would use [Play WS](http://www.playframework.com/documentation/2.3.x/ScalaWS) in the context of a Play application, but it can also be run directly from `Main`. + +Open up a new shell, and type: + +``` +$ ./play +> runMain Main +``` + +You should see: + +``` +[info] Running Main +header = (Content-Length,Buffer(106)) +header = (Content-Type,Buffer(text/html; charset=utf-8)) +body = + + + +

Congratulations! You are reading the page!

+ + +``` + +Now, to verify that it's only working because of the client's key, comment out the keyManager section in `ws.conf` and rerun `Main` -- you will see that the WS client fails client authentication: + +``` +failure = java.net.ConnectException: Received fatal alert: bad_certificate to https://example.com:9443/ +``` + +That's it. \ No newline at end of file diff --git a/activator b/activator new file mode 100755 index 000000000..00fc7d532 --- /dev/null +++ b/activator @@ -0,0 +1,336 @@ +#!/bin/bash + +### ------------------------------- ### +### Helper methods for BASH scripts ### +### ------------------------------- ### + +realpath () { +( + TARGET_FILE="$1" + + cd $(dirname "$TARGET_FILE") + TARGET_FILE=$(basename "$TARGET_FILE") + + COUNT=0 + while [ -L "$TARGET_FILE" -a $COUNT -lt 100 ] + do + TARGET_FILE=$(readlink "$TARGET_FILE") + cd $(dirname "$TARGET_FILE") + TARGET_FILE=$(basename "$TARGET_FILE") + COUNT=$(($COUNT + 1)) + done + + if [ "$TARGET_FILE" == "." -o "$TARGET_FILE" == ".." ]; then + cd "$TARGET_FILE" + TARGET_FILEPATH= + else + TARGET_FILEPATH=/$TARGET_FILE + fi + + # make sure we grab the actual windows path, instead of cygwin's path. + if ! is_cygwin; then + echo "$(pwd -P)/$TARGET_FILE" + else + echo $(cygwinpath "$(pwd -P)/$TARGET_FILE") + fi +) +} + +# TODO - Do we need to detect msys? + +# Uses uname to detect if we're in the odd cygwin environment. +is_cygwin() { + local os=$(uname -s) + case "$os" in + CYGWIN*) return 0 ;; + *) return 1 ;; + esac +} + +# This can fix cygwin style /cygdrive paths so we get the +# windows style paths. +cygwinpath() { + local file="$1" + if is_cygwin; then + echo $(cygpath -w $file) + else + echo $file + fi +} + +# Make something URI friendly +make_url() { + url="$1" + local nospaces=${url// /%20} + if is_cygwin; then + echo "/${nospaces//\\//}" + else + echo "$nospaces" + fi +} + +# Detect if we should use JAVA_HOME or just try PATH. +get_java_cmd() { + if [[ -n "$JAVA_HOME" ]] && [[ -x "$JAVA_HOME/bin/java" ]]; then + echo "$JAVA_HOME/bin/java" + else + echo "java" + fi +} + +echoerr () { + echo 1>&2 "$@" +} +vlog () { + [[ $verbose || $debug ]] && echoerr "$@" +} +dlog () { + [[ $debug ]] && echoerr "$@" +} +execRunner () { + # print the arguments one to a line, quoting any containing spaces + [[ $verbose || $debug ]] && echo "# Executing command line:" && { + for arg; do + if printf "%s\n" "$arg" | grep -q ' '; then + printf "\"%s\"\n" "$arg" + else + printf "%s\n" "$arg" + fi + done + echo "" + } + + exec "$@" +} +addJava () { + dlog "[addJava] arg = '$1'" + java_args=( "${java_args[@]}" "$1" ) +} +addApp () { + dlog "[addApp] arg = '$1'" + sbt_commands=( "${app_commands[@]}" "$1" ) +} +addResidual () { + dlog "[residual] arg = '$1'" + residual_args=( "${residual_args[@]}" "$1" ) +} +addDebugger () { + addJava "-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=$1" +} +addConfigOpts () { + dlog "[addConfigOpts] arg = '$*'" + for item in $* + do + addJava "$item" + done +} +# a ham-fisted attempt to move some memory settings in concert +# so they need not be messed around with individually. +get_mem_opts () { + local mem=${1:-1024} + local meta=$(( $mem / 4 )) + (( $meta > 256 )) || meta=256 + (( $meta < 1024 )) || meta=1024 + + # default is to set memory options but this can be overridden by code section below + memopts="-Xms${mem}m -Xmx${mem}m" + if [[ "${java_version}" > "1.8" ]]; then + extmemopts="-XX:MetaspaceSize=64m -XX:MaxMetaspaceSize=${meta}m" + else + extmemopts="-XX:PermSize=64m -XX:MaxPermSize=${meta}m" + fi + + if [[ "${java_opts}" == *-Xmx* ]] || [[ "${java_opts}" == *-Xms* ]] || [[ "${java_opts}" == *-XX:MaxPermSize* ]] || [[ "${java_opts}" == *-XX:ReservedCodeCacheSize* ]] || [[ "${java_opts}" == *-XX:MaxMetaspaceSize* ]]; then + # if we detect any of these settings in ${java_opts} we need to NOT output our settings. + # The reason is the Xms/Xmx, if they don't line up, cause errors. + memopts="" + extmemopts="" + fi + + echo "${memopts} ${extmemopts}" +} +require_arg () { + local type="$1" + local opt="$2" + local arg="$3" + if [[ -z "$arg" ]] || [[ "${arg:0:1}" == "-" ]]; then + die "$opt requires <$type> argument" + fi +} +require_arg () { + local type="$1" + local opt="$2" + local arg="$3" + if [[ -z "$arg" ]] || [[ "${arg:0:1}" == "-" ]]; then + die "$opt requires <$type> argument" + fi +} +is_function_defined() { + declare -f "$1" > /dev/null +} + +# If we're *not* running in a terminal, and we don't have any arguments, then we need to add the 'ui' parameter +detect_terminal_for_ui() { + [[ ! -t 0 ]] && [[ "${#residual_args}" == "0" ]] && { + addResidual "ui" + } + # SPECIAL TEST FOR MAC + [[ "$(uname)" == "Darwin" ]] && [[ "$HOME" == "$PWD" ]] && [[ "${#residual_args}" == "0" ]] && { + echo "Detected MAC OSX launched script...." + echo "Swapping to UI" + addResidual "ui" + } +} + +# Processes incoming arguments and places them in appropriate global variables. called by the run method. +process_args () { + while [[ $# -gt 0 ]]; do + case "$1" in + -h|-help) usage; exit 1 ;; + -v|-verbose) verbose=1 && shift ;; + -d|-debug) debug=1 && shift ;; + -mem) require_arg integer "$1" "$2" && app_mem="$2" && shift 2 ;; + -jvm-debug) [[ "$2" =~ ^[0-9]+$ ]] && addDebugger "$2" && shift || addDebugger 9999 && shift ;; + -java-home) require_arg path "$1" "$2" && java_cmd="$2/bin/java" && shift 2 ;; + -D*) addJava "$1" && shift ;; + -J*) addJava "${1:2}" && shift ;; + *) addResidual "$1" && shift ;; + esac + done + + is_function_defined process_my_args && { + myargs=("${residual_args[@]}") + residual_args=() + process_my_args "${myargs[@]}" + } +} + +# Actually runs the script. +run() { + # TODO - check for sane environment + + # process the combined args, then reset "$@" to the residuals + process_args "$@" + detect_terminal_for_ui + set -- "${residual_args[@]}" + argumentCount=$# + + #check for jline terminal fixes on cygwin + if is_cygwin; then + stty -icanon min 1 -echo > /dev/null 2>&1 + addJava "-Djline.terminal=jline.UnixTerminal" + addJava "-Dsbt.cygwin=true" + fi + + # run sbt + execRunner "$java_cmd" \ + "-Dactivator.home=$(make_url "$activator_home")" \ + $(get_mem_opts $app_mem) \ + ${java_opts[@]} \ + ${java_args[@]} \ + -jar "$app_launcher" \ + "${app_commands[@]}" \ + "${residual_args[@]}" + + local exit_code=$? + if is_cygwin; then + stty icanon echo > /dev/null 2>&1 + fi + exit $exit_code +} + +# Loads a configuration file full of default command line options for this script. +loadConfigFile() { + cat "$1" | sed '/^\#/d' +} + +### ------------------------------- ### +### Start of customized settings ### +### ------------------------------- ### +usage() { + cat < [options] + + Command: + ui Start the Activator UI + new [name] [template-id] Create a new project with [name] using template [template-id] + list-templates Print all available template names + -h | -help Print this message + + Options: + -v | -verbose Make this runner chattier + -d | -debug Set sbt log level to debug + -mem Set memory options (default: $sbt_mem, which is $(get_mem_opts $sbt_mem)) + -jvm-debug Turn on JVM debugging, open at the given port. + + # java version (default: java from PATH, currently $(java -version 2>&1 | grep version)) + -java-home Alternate JAVA_HOME + + # jvm options and output control + -Dkey=val Pass -Dkey=val directly to the java runtime + -J-X Pass option -X directly to the java runtime + (-J is stripped) + + # environment variables (read from context) + JAVA_OPTS Environment variable, if unset uses "" + SBT_OPTS Environment variable, if unset uses "" + ACTIVATOR_OPTS Environment variable, if unset uses "" + +In the case of duplicated or conflicting options, the order above +shows precedence: environment variables lowest, command line options highest. +EOM +} + +### ------------------------------- ### +### Main script ### +### ------------------------------- ### + +declare -a residual_args +declare -a java_args +declare -a app_commands +declare -r real_script_path="$(realpath "$0")" +declare -r activator_home="$(realpath "$(dirname "$real_script_path")")" +declare -r app_version="1.2.1" + +declare -r app_launcher="${activator_home}/activator-launch-${app_version}.jar" +declare -r script_name=activator +declare -r java_cmd=$(get_java_cmd) +declare -r java_opts=( "${ACTIVATOR_OPTS[@]}" "${SBT_OPTS[@]}" "${JAVA_OPTS[@]}" "${java_opts[@]}" ) +userhome="$HOME" +if is_cygwin; then + # cygwin sets home to something f-d up, set to real windows homedir + userhome="$USERPROFILE" +fi +declare -r activator_user_home_dir="${userhome}/.activator" +declare -r java_opts_config_home="${activator_user_home_dir}/activatorconfig.txt" +declare -r java_opts_config_version="${activator_user_home_dir}/${app_version}/activatorconfig.txt" + +# Now check to see if it's a good enough version +declare -r java_version=$("$java_cmd" -version 2>&1 | awk -F '"' '/version/ {print $2}') +if [[ "$java_version" == "" ]]; then + echo + echo No java installations was detected. + echo Please go to http://www.java.com/getjava/ and download + echo + exit 1 +elif [[ ! "$java_version" > "1.6" ]]; then + echo + echo The java installation you have is not up to date + echo Activator requires at least version 1.6+, you have + echo version $java_version + echo + echo Please go to http://www.java.com/getjava/ and download + echo a valid Java Runtime and install before running Activator. + echo + exit 1 +fi + +# if configuration files exist, prepend their contents to the java args so it can be processed by this runner +# a "versioned" config trumps one on the top level +if [[ -f "$java_opts_config_version" ]]; then + addConfigOpts $(loadConfigFile "$java_opts_config_version") +elif [[ -f "$java_opts_config_home" ]]; then + addConfigOpts $(loadConfigFile "$java_opts_config_home") +fi + +run "$@" diff --git a/activator.properties b/activator.properties new file mode 100644 index 000000000..eecf7afdf --- /dev/null +++ b/activator.properties @@ -0,0 +1,5 @@ +name=play-tls-example +title=Play Framework SSL/TLS Example +description=A Play application using HTTPS and WS with optional client authentication +tags=playframework,scala,tls,https,ssl,playws +authorTwitter=@will_sargent diff --git a/app/Main.scala b/app/Main.scala new file mode 100644 index 000000000..e5109fb56 --- /dev/null +++ b/app/Main.scala @@ -0,0 +1,53 @@ +import play.api.libs.ws._ +import play.api.libs.ws.ning._ +import play.api.libs.ws.ssl.debug.DebugConfiguration + +import com.typesafe.config.ConfigFactory + +import scala.util.{Failure, Success} + +/** + * Connects to example.com with a WS client running from Main. + * + * Please see http://www.playframework.com/documentation/2.3.x/WsSSL for more details. + */ +object Main { + + def newClient(rawConfig: play.api.Configuration): NingWSClient = { + val classLoader = Thread.currentThread().getContextClassLoader + val parser = new DefaultWSConfigParser(rawConfig, classLoader) + val clientConfig = parser.parse() + clientConfig.ssl.map { + _.debug.map(new DebugConfiguration().configure) + } + val builder = new NingAsyncHttpClientConfigBuilder(clientConfig) + val client = new NingWSClient(builder.build()) + client + } + + def printResponse(response:WSResponse) = { + response.allHeaders.foreach { header => + Console.println(s"header = $header") + } + val body = response.body + Console.println(s"body = $body") + } + + def main(args: Array[String]) { + import scala.concurrent.ExecutionContext.Implicits.global + + val config = play.api.Configuration(ConfigFactory.load("ws.conf")) + val client = newClient(config) + + val futureResponse = client.url("https://example.com:9443").get() + futureResponse.onComplete { + case Success(response) => + printResponse(response) + client.close() // closing the client must be done manually. + + case Failure(f) => + Console.println(s"failure = $f") + client.close() + } + } +} diff --git a/app/controllers/Application.scala b/app/controllers/Application.scala new file mode 100644 index 000000000..195c8cfb4 --- /dev/null +++ b/app/controllers/Application.scala @@ -0,0 +1,12 @@ +package controllers + +import play.api._ +import play.api.mvc._ + +object Application extends Controller { + + def index = Action { + Ok(views.html.index()) + } + +} \ No newline at end of file diff --git a/app/https/CustomSSLEngineProvider.scala b/app/https/CustomSSLEngineProvider.scala new file mode 100644 index 000000000..f9c9c5c4d --- /dev/null +++ b/app/https/CustomSSLEngineProvider.scala @@ -0,0 +1,86 @@ +package https + +import java.nio.file._ +import java.security.KeyStore +import javax.net.ssl._ + +import play.core.ApplicationProvider +import play.server.api._ + +class CustomSSLEngineProvider(appProvider: ApplicationProvider) extends SSLEngineProvider { + + def readPassword(): Array[Char] = { + val passwordPath = FileSystems.getDefault.getPath("certs", "password") + Files.readAllLines(passwordPath).get(0).toCharArray + } + + def readKeyInputStream(): java.io.InputStream = { + val keyPath = FileSystems.getDefault.getPath("certs", "example.com.jks") + Files.newInputStream(keyPath) + } + + def readTrustInputStream(): java.io.InputStream = { + val keyPath = FileSystems.getDefault.getPath("certs", "clientca.jks") + Files.newInputStream(keyPath) + } + + def readKeyManagers(): Array[KeyManager] = { + val password = readPassword() + val keyInputStream = readKeyInputStream() + try { + val keyStore = KeyStore.getInstance(KeyStore.getDefaultType) + keyStore.load(keyInputStream, password) + val kmf = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm) + kmf.init(keyStore, password) + kmf.getKeyManagers + } finally { + keyInputStream.close() + } + } + + def readTrustManagers(): Array[TrustManager] = { + val password = readPassword() + val trustInputStream = readTrustInputStream() + try { + val keyStore = KeyStore.getInstance(KeyStore.getDefaultType) + keyStore.load(trustInputStream, password) + val tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm) + tmf.init(keyStore) + tmf.getTrustManagers + } finally { + trustInputStream.close() + } + } + + def createSSLContext(applicationProvider: ApplicationProvider): SSLContext = { + val keyManagers = readKeyManagers() + val trustManagers = readTrustManagers() + + // Configure the SSL context to use TLS + val sslContext = SSLContext.getInstance("TLS") + sslContext.init(keyManagers, trustManagers, null) + sslContext + } + + override def createSSLEngine(): SSLEngine = { + val sslContext = createSSLContext(appProvider) + + // Start off with a clone of the default SSL parameters... + val sslParameters = sslContext.getDefaultSSLParameters + + // Tells the server to ignore client's cipher suite preference. + // http://docs.oracle.com/javase/8/docs/technotes/guides/security/jsse/JSSERefGuide.html#cipher_suite_preference + sslParameters.setUseCipherSuitesOrder(true) + + // http://docs.oracle.com/javase/8/docs/technotes/guides/security/jsse/JSSERefGuide.html#SSLParameters + val needClientAuth = java.lang.System.getProperty("play.ssl.needClientAuth") + sslParameters.setNeedClientAuth(java.lang.Boolean.parseBoolean(needClientAuth)) + + // Clone and modify the default SSL parameters. + val engine = sslContext.createSSLEngine + engine.setSSLParameters(sslParameters) + + engine + } + +} \ No newline at end of file diff --git a/app/views/index.scala.html b/app/views/index.scala.html new file mode 100644 index 000000000..9155a64bd --- /dev/null +++ b/app/views/index.scala.html @@ -0,0 +1,8 @@ +@() + + + +

Congratulations! You are reading the page!

+ + + diff --git a/build.sbt b/build.sbt new file mode 100644 index 000000000..419bf63f5 --- /dev/null +++ b/build.sbt @@ -0,0 +1,18 @@ +name := """activator-play-tls-example""" + +version := "1.0.0" + +lazy val root = (project in file(".")).enablePlugins(PlayScala) + +scalaVersion := "2.11.1" + +// We require JDK 1.8 to show usage of the latest JSSE APIs. +initialize := { + val _ = initialize.value // run the previous initialization + val specVersion = sys.props("java.specification.version") + assert(specVersion.contains("1.8"), "Java 1.8.0 or above required") +} + +libraryDependencies ++= Seq( + ws +) diff --git a/conf/application.conf b/conf/application.conf new file mode 100644 index 000000000..e7859cbe8 --- /dev/null +++ b/conf/application.conf @@ -0,0 +1,18 @@ +# See http://www.playframework.com/documentation/latest/ApplicationSecret for more details. +application.secret="cnwrSeFsJ8gur>ERM;;kAKmHtQlqi ${DIR}/password + +${DIR}/genca.sh +${DIR}/genclient.sh +${DIR}/genserver.sh +${DIR}/gentrustanchor.sh diff --git a/scripts/genclient.sh b/scripts/genclient.sh new file mode 100755 index 000000000..be09e7794 --- /dev/null +++ b/scripts/genclient.sh @@ -0,0 +1,87 @@ +#!/bin/bash + +export PW=`cat password` + +# Create a self signed certificate & private key to create a root certificate authority. +keytool -genkeypair -v \ + -alias clientca \ + -keystore client.jks \ + -dname "CN=clientca, OU=Example Org, O=Example Company, L=San Francisco, ST=California, C=US" \ + -keypass:env PW \ + -storepass:env PW \ + -keyalg EC \ + -keysize 256 \ + -ext KeyUsage:critical="keyCertSign" \ + -ext BasicConstraints:critical="ca:true" \ + -validity 365 + +# Create another key pair that will act as the client. We want this signed by the client CA. +keytool -genkeypair -v \ + -alias client \ + -keystore client.jks \ + -dname "CN=client, OU=Example Org, O=Example Company, L=San Francisco, ST=California, C=US" \ + -keypass:env PW \ + -storepass:env PW \ + -keyalg EC \ + -keysize 256 \ + +# Create a certificate signing request from the client certificate. +keytool -certreq -v \ + -alias client \ + -keypass:env PW \ + -storepass:env PW \ + -keystore client.jks \ + -file client.csr + +# Make clientCA create a certificate chain saying that client is signed by clientCA. +keytool -gencert -v \ + -alias clientca \ + -keypass:env PW \ + -storepass:env PW \ + -keystore client.jks \ + -infile client.csr \ + -outfile client.crt \ + -ext EKU="clientAuth" \ + -rfc + +# Export the client-ca certificate from the keystore. This goes to nginx under "ssl_client_certificate" +# and is presented in the CertificateRequest. +keytool -export -v \ + -alias clientca \ + -file clientca.crt \ + -storepass:env PW \ + -keystore client.jks \ + -rfc + +# Import the signed client certificate back into client.jks. This is important, as JSSE won't send a client +# certificate if it can't find one signed by the client-ca presented in the CertificateRequest. +keytool -import -v \ + -alias client \ + -file client.crt \ + -keystore client.jks \ + -storetype JKS \ + -storepass:env PW + +# Export the client CA to pkcs12, so it's safe. +keytool -importkeystore -v \ + -srcalias clientca \ + -srckeystore client.jks \ + -srcstorepass:env PW \ + -destkeystore client.p12 \ + -deststorepass:env PW \ + -deststoretype PKCS12 + +# Import the client CA's public certificate into a JKS store for Play Server to read (we don't use +# the PKCS12 because it's got the CA private key and we don't want that. +keytool -import -v \ + -alias clientca \ + -file clientca.crt \ + -keystore clientca.jks \ + -storepass:env PW << EOF +yes +EOF + +# List out the contents of client.jks just to confirm it. +keytool -list -v \ + -keystore client.jks \ + -storepass:env PW diff --git a/scripts/genserver.sh b/scripts/genserver.sh new file mode 100755 index 000000000..931c20194 --- /dev/null +++ b/scripts/genserver.sh @@ -0,0 +1,60 @@ +#!/bin/bash + +export PW=`cat password` + +# Create a server certificate, tied to example.com +keytool -genkeypair -v \ + -alias example.com \ + -dname "CN=example.com, OU=Example Org, O=Example Company, L=San Francisco, ST=California, C=US" \ + -keystore example.com.jks \ + -keypass:env PW \ + -storepass:env PW \ + -keyalg EC \ + -keysize 256 \ + -validity 385 + +# Create a certificate signing request for example.com +keytool -certreq -v \ + -alias example.com \ + -keypass:env PW \ + -storepass:env PW \ + -keystore example.com.jks \ + -file example.com.csr + +# Tell exampleCA to sign the example.com certificate. +# Technically, digitalSignature for DHE or ECDHE, keyEncipherment for RSA +keytool -gencert -v \ + -alias exampleca \ + -keypass:env PW \ + -storepass:env PW \ + -keystore exampleca.jks \ + -infile example.com.csr \ + -outfile example.com.crt \ + -ext KeyUsage:critical="digitalSignature,keyEncipherment" \ + -ext EKU="serverAuth" \ + -ext SAN="DNS:example.com" \ + -rfc + +# Tell example.com.jks it can trust exampleca as a signer. +keytool -import -v \ + -alias exampleca \ + -file exampleca.crt \ + -keystore example.com.jks \ + -storetype JKS \ + -storepass:env PW << EOF +yes +EOF + +# Import the signed certificate back into example.com.jks +keytool -import -v \ + -alias example.com \ + -file example.com.crt \ + -keystore example.com.jks \ + -storetype JKS \ + -storepass:env PW + +# List out the contents of example.com.jks just to confirm it. +# If you are using Play as a TLS termination point, this is the key store you should use. +keytool -list -v \ + -keystore example.com.jks \ + -storepass:env PW diff --git a/scripts/gentrustanchor.sh b/scripts/gentrustanchor.sh new file mode 100755 index 000000000..3a8533c7e --- /dev/null +++ b/scripts/gentrustanchor.sh @@ -0,0 +1,19 @@ +#!/bin/bash + +export PW=`cat password` + +# Create a JKS keystore that trusts the example CA, with the default password. +# This is used by the client in the trustmanager section. +keytool -import -v \ + -alias exampleca \ + -file exampleca.crt \ + -keypass:env PW \ + -storepass changeit \ + -keystore exampletrust.jks << EOF +yes +EOF + +# List out the details of the store password. +keytool -list -v \ + -keystore exampletrust.jks \ + -storepass changeit \ No newline at end of file diff --git a/tutorial/index.html b/tutorial/index.html new file mode 100644 index 000000000..effed0ffd --- /dev/null +++ b/tutorial/index.html @@ -0,0 +1,51 @@ + + + Play TLS Example + + +
+

Play TLS Example

+ +
+

Setup

+ +

+ Please see the README for instructions on how to configure and run Play to run over HTTPS.

+ +

+ In particular, note that you must have the following: +

+ +
    +
  • Be running JDK 1.8
  • +
  • Have generated certificates according to the README
  • +
  • Added example.com to /etc/hosts
  • +
  • Be running the included ./play script
  • +
+
+ +
+

Server HTTPS

+ +

+ Play is capable of running HTTPS on the server. Play's SSLEngine can be configured for client authentication. +

+

In this example, CustomSSLEngineProvider does the work of setting up the SSLEngine's parameters. +

+ +
+ +
+

Client HTTPS

+ +

+ Play can also talk to an HTTPS server using Play WS, even using client authentication. With some additional code, it can use Play WS to communicate outside of Play's application context. +

+

+ In this example, the Main class can be run independently, and will connect to the Play HTTPS server. Play WS will use Play WS SSL configured with the ws.conf to set up the appropriate passwords and key stores. +

+
+ +
+ + \ No newline at end of file From 8c0311657ce01a5c44659c53710dbbcdd90dae1b Mon Sep 17 00:00:00 2001 From: Will Sargent Date: Mon, 7 Jul 2014 01:14:25 -0700 Subject: [PATCH 02/53] Clean up play script and readme. --- README.md | 2 +- play | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index c83384cc4..88c0ac0d4 100644 --- a/README.md +++ b/README.md @@ -47,7 +47,7 @@ Now that you've generated the certificates and added `example.com` to `/etc/host This application is not run with `activator` -- you should run it with `./play` instead, as there are a number of system properties required to use it effectively. -[Configuring HTTPS](http://www.playframework.com/documentation/2.3.x/ConfiguringHttps) +The `CustomSSLEngineProvider` is responsible for Play's HTTPS server. More details can be found in [Configuring HTTPS](http://www.playframework.com/documentation/2.3.x/ConfiguringHttps). ``` ./play run diff --git a/play b/play index 857e00430..d9fc0e553 100755 --- a/play +++ b/play @@ -19,7 +19,7 @@ JVM_OPTIONS="$JVM_OPTIONS -Dhttps.port=9443" JVM_OPTIONS="$JVM_OPTIONS -Dplay.http.sslengineprovider=https.CustomSSLEngineProvider" # Enable this if you want to turn on client authentication -JVM_OPTIONS="$JVM_OPTIONS -Dplay.ssl.needClientAuth=true" +#JVM_OPTIONS="$JVM_OPTIONS -Dplay.ssl.needClientAuth=true" # Enable the handshake parameter to be extended for better protection. # http://docs.oracle.com/javase/8/docs/technotes/guides/security/jsse/JSSERefGuide.html#customizing_dh_keys From 2deb91ad77f9aad7c0431113d04590889429a390 Mon Sep 17 00:00:00 2001 From: Will Sargent Date: Mon, 7 Jul 2014 05:51:06 -0700 Subject: [PATCH 03/53] Fix directory --- README.md | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 88c0ac0d4..79c38f556 100644 --- a/README.md +++ b/README.md @@ -8,7 +8,7 @@ You must have JDK 1.8 installed on your machine to run this, to take advantage o ## Generate Certificates -To use HTTPS, you must have X.509 certificates. Generating certificates can be painful, so all the scripts needed to generate the certificates needed are included in the `certs` directory. For more detail, you can see the [Certificate Generation](http://www.playframework.com/documentation/2.3.x/CertificateGeneration) section in Play WS SSL. +To use HTTPS, you must have X.509 certificates. Generating certificates can be painful, so all the scripts needed to generate the certificates needed are included in the `scripts` directory. For more detail, you can see the [Certificate Generation](http://www.playframework.com/documentation/2.3.x/CertificateGeneration) section in Play WS SSL. To generate certificates, run: @@ -17,7 +17,7 @@ cd scripts/ ./gencerts.sh ``` -and move all of the generated files into the `certs` directory: +and move all of the generated files into the (newly created) `certs` directory: ``` cd scripts @@ -160,7 +160,13 @@ exceptions.KeyError - 'exponent' ## Turning on Client Authentication -Now that you've verified that the server is running and can speak HTTPS, go into `./play` and change the `play.ssl.needClientAuth` setting from `false` to `true`. Then restart the server. You should see +Now that you've verified that the server is running and can speak HTTPS, go into `./play` script and uncomment the `play.ssl.needClientAuth` setting: + +``` +JVM_OPTIONS="$JVM_OPTIONS -Dplay.ssl.needClientAuth=true" +``` + +Then restart the server. You should see ``` ECDHE-ECDSA-RC4-SHA ClientCertificateRequested - Server requested a client certificate issued by one of the following CAs: '/C=US/ST=California/L=San Francisco/O=Example Company/OU=Example Org/CN=clientca'. @@ -235,4 +241,7 @@ Now, to verify that it's only working because of the client's key, comment out t failure = java.net.ConnectException: Received fatal alert: bad_certificate to https://example.com:9443/ ``` -That's it. \ No newline at end of file +## Conclusion + +That's it -- you have made Play work (with TLS 1.2 and ECDSA certificates). Please look through the ./play script and the certificate generation scripts for more details, but that should be enough to get you started. + From fa4490445a0ffd1c7dd12a5f200a48263d097268 Mon Sep 17 00:00:00 2001 From: Will Sargent Date: Tue, 8 Jul 2014 14:58:01 -0700 Subject: [PATCH 04/53] Update readme to talk about unlimited JCE --- README.md | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 79c38f556..898d961f7 100644 --- a/README.md +++ b/README.md @@ -6,6 +6,16 @@ This application shows how to use Play with SSL/TLS, using the Java Secure Socke You must have JDK 1.8 installed on your machine to run this, to take advantage of the new [security enhancements in JSSE](http://blog.ivanristic.com/2014/03/ssl-tls-improvements-in-java-8.html). +* Go to the [Java downloads](http://www.oracle.com/technetwork/java/javase/downloads/index.html) page. +* Search for "Java Platform (JDK) 8u5" and download the files. +* Follow the [installation instructions](http://docs.oracle.com/javase/8/docs/technotes/guides/install/install_overview.html) for your platform. + +To use the `TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384` cipher suite, you must have the Unlimited Strength policy files installed: + +* Go to the [Java downloads](http://www.oracle.com/technetwork/java/javase/downloads/index.html) page. +* Search for "Java Cryptography Extension (JCE) Unlimited Strength Jurisdiction Policy Files for JDK/JRE 8" +* Install the policy files in `${java.home}/lib/security/`. + ## Generate Certificates To use HTTPS, you must have X.509 certificates. Generating certificates can be painful, so all the scripts needed to generate the certificates needed are included in the `scripts` directory. For more detail, you can see the [Certificate Generation](http://www.playframework.com/documentation/2.3.x/CertificateGeneration) section in Play WS SSL. @@ -208,9 +218,10 @@ ws.ssl { ] } } - ``` +`TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384` is a strong cipher suite recommended by the NSA Suite B RFC. (However, note that Bruce Schneier believes that the [ECC constants have been manipulated](https://www.schneier.com/blog/archives/2013/09/the_nsa_is_brea.html#c1675929) by the NSA.) Note that you need the JCE Unlimited Policy files in order to use this cipher suite. + Normally you would use [Play WS](http://www.playframework.com/documentation/2.3.x/ScalaWS) in the context of a Play application, but it can also be run directly from `Main`. Open up a new shell, and type: From 22f4e14c0e49444656c1686a3753b745d9d80556 Mon Sep 17 00:00:00 2001 From: Will Sargent Date: Tue, 8 Jul 2014 15:03:35 -0700 Subject: [PATCH 05/53] Update readme again --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 898d961f7..c50b69ecb 100644 --- a/README.md +++ b/README.md @@ -220,7 +220,7 @@ ws.ssl { } ``` -`TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384` is a strong cipher suite recommended by the NSA Suite B RFC. (However, note that Bruce Schneier believes that the [ECC constants have been manipulated](https://www.schneier.com/blog/archives/2013/09/the_nsa_is_brea.html#c1675929) by the NSA.) Note that you need the JCE Unlimited Policy files in order to use this cipher suite. +`TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384` is a strong cipher suite in the [Suite B Profile for Transport Layer Security](http://tools.ietf.org/html/rfc5430). (Bruce Schneier believes that the [ECC constants have been manipulated](https://www.schneier.com/blog/archives/2013/09/the_nsa_is_brea.html#c1675929) by the NSA, but other options are limited at this point.) Note that you need the JCE Unlimited Policy files in order to use this cipher suite -- see the Requirements section above if you haven't already installed it. Normally you would use [Play WS](http://www.playframework.com/documentation/2.3.x/ScalaWS) in the context of a Play application, but it can also be run directly from `Main`. From 5be2e7920c392b6549a2d789cbb5f3dc48bcd3ff Mon Sep 17 00:00:00 2001 From: Will Sargent Date: Mon, 8 Jun 2015 16:07:06 +0200 Subject: [PATCH 06/53] Update to Play 2.4.0 --- README.md | 2 +- activator | 336 ------------------------------------- app/Main.scala | 19 ++- app/views/index.scala.html | 17 +- build.sbt | 9 +- conf/application.conf | 16 +- conf/logback.xml | 44 +++++ conf/ws.conf | 2 +- play | 4 +- project/build.properties | 2 +- project/plugins.sbt | 15 +- 11 files changed, 78 insertions(+), 388 deletions(-) delete mode 100755 activator create mode 100644 conf/logback.xml diff --git a/README.md b/README.md index c50b69ecb..d117fd373 100644 --- a/README.md +++ b/README.md @@ -44,7 +44,7 @@ You may have noticed that the name on the generated certificates is `example.com Rather than setting up a DNS entry or a remote server, we'll modify `/etc/hosts` to point to the local directory. ``` -$ sudo /etc/hosts +$ sudo vi /etc/hosts ``` ``` diff --git a/activator b/activator deleted file mode 100755 index 00fc7d532..000000000 --- a/activator +++ /dev/null @@ -1,336 +0,0 @@ -#!/bin/bash - -### ------------------------------- ### -### Helper methods for BASH scripts ### -### ------------------------------- ### - -realpath () { -( - TARGET_FILE="$1" - - cd $(dirname "$TARGET_FILE") - TARGET_FILE=$(basename "$TARGET_FILE") - - COUNT=0 - while [ -L "$TARGET_FILE" -a $COUNT -lt 100 ] - do - TARGET_FILE=$(readlink "$TARGET_FILE") - cd $(dirname "$TARGET_FILE") - TARGET_FILE=$(basename "$TARGET_FILE") - COUNT=$(($COUNT + 1)) - done - - if [ "$TARGET_FILE" == "." -o "$TARGET_FILE" == ".." ]; then - cd "$TARGET_FILE" - TARGET_FILEPATH= - else - TARGET_FILEPATH=/$TARGET_FILE - fi - - # make sure we grab the actual windows path, instead of cygwin's path. - if ! is_cygwin; then - echo "$(pwd -P)/$TARGET_FILE" - else - echo $(cygwinpath "$(pwd -P)/$TARGET_FILE") - fi -) -} - -# TODO - Do we need to detect msys? - -# Uses uname to detect if we're in the odd cygwin environment. -is_cygwin() { - local os=$(uname -s) - case "$os" in - CYGWIN*) return 0 ;; - *) return 1 ;; - esac -} - -# This can fix cygwin style /cygdrive paths so we get the -# windows style paths. -cygwinpath() { - local file="$1" - if is_cygwin; then - echo $(cygpath -w $file) - else - echo $file - fi -} - -# Make something URI friendly -make_url() { - url="$1" - local nospaces=${url// /%20} - if is_cygwin; then - echo "/${nospaces//\\//}" - else - echo "$nospaces" - fi -} - -# Detect if we should use JAVA_HOME or just try PATH. -get_java_cmd() { - if [[ -n "$JAVA_HOME" ]] && [[ -x "$JAVA_HOME/bin/java" ]]; then - echo "$JAVA_HOME/bin/java" - else - echo "java" - fi -} - -echoerr () { - echo 1>&2 "$@" -} -vlog () { - [[ $verbose || $debug ]] && echoerr "$@" -} -dlog () { - [[ $debug ]] && echoerr "$@" -} -execRunner () { - # print the arguments one to a line, quoting any containing spaces - [[ $verbose || $debug ]] && echo "# Executing command line:" && { - for arg; do - if printf "%s\n" "$arg" | grep -q ' '; then - printf "\"%s\"\n" "$arg" - else - printf "%s\n" "$arg" - fi - done - echo "" - } - - exec "$@" -} -addJava () { - dlog "[addJava] arg = '$1'" - java_args=( "${java_args[@]}" "$1" ) -} -addApp () { - dlog "[addApp] arg = '$1'" - sbt_commands=( "${app_commands[@]}" "$1" ) -} -addResidual () { - dlog "[residual] arg = '$1'" - residual_args=( "${residual_args[@]}" "$1" ) -} -addDebugger () { - addJava "-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=$1" -} -addConfigOpts () { - dlog "[addConfigOpts] arg = '$*'" - for item in $* - do - addJava "$item" - done -} -# a ham-fisted attempt to move some memory settings in concert -# so they need not be messed around with individually. -get_mem_opts () { - local mem=${1:-1024} - local meta=$(( $mem / 4 )) - (( $meta > 256 )) || meta=256 - (( $meta < 1024 )) || meta=1024 - - # default is to set memory options but this can be overridden by code section below - memopts="-Xms${mem}m -Xmx${mem}m" - if [[ "${java_version}" > "1.8" ]]; then - extmemopts="-XX:MetaspaceSize=64m -XX:MaxMetaspaceSize=${meta}m" - else - extmemopts="-XX:PermSize=64m -XX:MaxPermSize=${meta}m" - fi - - if [[ "${java_opts}" == *-Xmx* ]] || [[ "${java_opts}" == *-Xms* ]] || [[ "${java_opts}" == *-XX:MaxPermSize* ]] || [[ "${java_opts}" == *-XX:ReservedCodeCacheSize* ]] || [[ "${java_opts}" == *-XX:MaxMetaspaceSize* ]]; then - # if we detect any of these settings in ${java_opts} we need to NOT output our settings. - # The reason is the Xms/Xmx, if they don't line up, cause errors. - memopts="" - extmemopts="" - fi - - echo "${memopts} ${extmemopts}" -} -require_arg () { - local type="$1" - local opt="$2" - local arg="$3" - if [[ -z "$arg" ]] || [[ "${arg:0:1}" == "-" ]]; then - die "$opt requires <$type> argument" - fi -} -require_arg () { - local type="$1" - local opt="$2" - local arg="$3" - if [[ -z "$arg" ]] || [[ "${arg:0:1}" == "-" ]]; then - die "$opt requires <$type> argument" - fi -} -is_function_defined() { - declare -f "$1" > /dev/null -} - -# If we're *not* running in a terminal, and we don't have any arguments, then we need to add the 'ui' parameter -detect_terminal_for_ui() { - [[ ! -t 0 ]] && [[ "${#residual_args}" == "0" ]] && { - addResidual "ui" - } - # SPECIAL TEST FOR MAC - [[ "$(uname)" == "Darwin" ]] && [[ "$HOME" == "$PWD" ]] && [[ "${#residual_args}" == "0" ]] && { - echo "Detected MAC OSX launched script...." - echo "Swapping to UI" - addResidual "ui" - } -} - -# Processes incoming arguments and places them in appropriate global variables. called by the run method. -process_args () { - while [[ $# -gt 0 ]]; do - case "$1" in - -h|-help) usage; exit 1 ;; - -v|-verbose) verbose=1 && shift ;; - -d|-debug) debug=1 && shift ;; - -mem) require_arg integer "$1" "$2" && app_mem="$2" && shift 2 ;; - -jvm-debug) [[ "$2" =~ ^[0-9]+$ ]] && addDebugger "$2" && shift || addDebugger 9999 && shift ;; - -java-home) require_arg path "$1" "$2" && java_cmd="$2/bin/java" && shift 2 ;; - -D*) addJava "$1" && shift ;; - -J*) addJava "${1:2}" && shift ;; - *) addResidual "$1" && shift ;; - esac - done - - is_function_defined process_my_args && { - myargs=("${residual_args[@]}") - residual_args=() - process_my_args "${myargs[@]}" - } -} - -# Actually runs the script. -run() { - # TODO - check for sane environment - - # process the combined args, then reset "$@" to the residuals - process_args "$@" - detect_terminal_for_ui - set -- "${residual_args[@]}" - argumentCount=$# - - #check for jline terminal fixes on cygwin - if is_cygwin; then - stty -icanon min 1 -echo > /dev/null 2>&1 - addJava "-Djline.terminal=jline.UnixTerminal" - addJava "-Dsbt.cygwin=true" - fi - - # run sbt - execRunner "$java_cmd" \ - "-Dactivator.home=$(make_url "$activator_home")" \ - $(get_mem_opts $app_mem) \ - ${java_opts[@]} \ - ${java_args[@]} \ - -jar "$app_launcher" \ - "${app_commands[@]}" \ - "${residual_args[@]}" - - local exit_code=$? - if is_cygwin; then - stty icanon echo > /dev/null 2>&1 - fi - exit $exit_code -} - -# Loads a configuration file full of default command line options for this script. -loadConfigFile() { - cat "$1" | sed '/^\#/d' -} - -### ------------------------------- ### -### Start of customized settings ### -### ------------------------------- ### -usage() { - cat < [options] - - Command: - ui Start the Activator UI - new [name] [template-id] Create a new project with [name] using template [template-id] - list-templates Print all available template names - -h | -help Print this message - - Options: - -v | -verbose Make this runner chattier - -d | -debug Set sbt log level to debug - -mem Set memory options (default: $sbt_mem, which is $(get_mem_opts $sbt_mem)) - -jvm-debug Turn on JVM debugging, open at the given port. - - # java version (default: java from PATH, currently $(java -version 2>&1 | grep version)) - -java-home Alternate JAVA_HOME - - # jvm options and output control - -Dkey=val Pass -Dkey=val directly to the java runtime - -J-X Pass option -X directly to the java runtime - (-J is stripped) - - # environment variables (read from context) - JAVA_OPTS Environment variable, if unset uses "" - SBT_OPTS Environment variable, if unset uses "" - ACTIVATOR_OPTS Environment variable, if unset uses "" - -In the case of duplicated or conflicting options, the order above -shows precedence: environment variables lowest, command line options highest. -EOM -} - -### ------------------------------- ### -### Main script ### -### ------------------------------- ### - -declare -a residual_args -declare -a java_args -declare -a app_commands -declare -r real_script_path="$(realpath "$0")" -declare -r activator_home="$(realpath "$(dirname "$real_script_path")")" -declare -r app_version="1.2.1" - -declare -r app_launcher="${activator_home}/activator-launch-${app_version}.jar" -declare -r script_name=activator -declare -r java_cmd=$(get_java_cmd) -declare -r java_opts=( "${ACTIVATOR_OPTS[@]}" "${SBT_OPTS[@]}" "${JAVA_OPTS[@]}" "${java_opts[@]}" ) -userhome="$HOME" -if is_cygwin; then - # cygwin sets home to something f-d up, set to real windows homedir - userhome="$USERPROFILE" -fi -declare -r activator_user_home_dir="${userhome}/.activator" -declare -r java_opts_config_home="${activator_user_home_dir}/activatorconfig.txt" -declare -r java_opts_config_version="${activator_user_home_dir}/${app_version}/activatorconfig.txt" - -# Now check to see if it's a good enough version -declare -r java_version=$("$java_cmd" -version 2>&1 | awk -F '"' '/version/ {print $2}') -if [[ "$java_version" == "" ]]; then - echo - echo No java installations was detected. - echo Please go to http://www.java.com/getjava/ and download - echo - exit 1 -elif [[ ! "$java_version" > "1.6" ]]; then - echo - echo The java installation you have is not up to date - echo Activator requires at least version 1.6+, you have - echo version $java_version - echo - echo Please go to http://www.java.com/getjava/ and download - echo a valid Java Runtime and install before running Activator. - echo - exit 1 -fi - -# if configuration files exist, prepend their contents to the java args so it can be processed by this runner -# a "versioned" config trumps one on the top level -if [[ -f "$java_opts_config_version" ]]; then - addConfigOpts $(loadConfigFile "$java_opts_config_version") -elif [[ -f "$java_opts_config_home" ]]; then - addConfigOpts $(loadConfigFile "$java_opts_config_home") -fi - -run "$@" diff --git a/app/Main.scala b/app/Main.scala index e5109fb56..a0d21f953 100644 --- a/app/Main.scala +++ b/app/Main.scala @@ -1,3 +1,4 @@ +import play.api.{Mode, Environment} import play.api.libs.ws._ import play.api.libs.ws.ning._ import play.api.libs.ws.ssl.debug.DebugConfiguration @@ -13,15 +14,14 @@ import scala.util.{Failure, Success} */ object Main { - def newClient(rawConfig: play.api.Configuration): NingWSClient = { - val classLoader = Thread.currentThread().getContextClassLoader - val parser = new DefaultWSConfigParser(rawConfig, classLoader) + def newClient(configuration: play.api.Configuration, environment: Environment): NingWSClient = { + val parser = new WSConfigParser(configuration, environment) val clientConfig = parser.parse() - clientConfig.ssl.map { - _.debug.map(new DebugConfiguration().configure) - } - val builder = new NingAsyncHttpClientConfigBuilder(clientConfig) - val client = new NingWSClient(builder.build()) + val ningParser = new NingWSClientConfigParser(clientConfig, configuration, environment) + val ningClientConfig = ningParser.parse() + val builder = new NingAsyncHttpClientConfigBuilder(ningClientConfig) + val asyncHttpClientConfig = builder.build() + val client = new NingWSClient(asyncHttpClientConfig) client } @@ -37,7 +37,8 @@ object Main { import scala.concurrent.ExecutionContext.Implicits.global val config = play.api.Configuration(ConfigFactory.load("ws.conf")) - val client = newClient(config) + val environment = play.api.Environment.simple(new java.io.File("./conf"), Mode.Dev) + val client = newClient(config, environment) val futureResponse = client.url("https://example.com:9443").get() futureResponse.onComplete { diff --git a/app/views/index.scala.html b/app/views/index.scala.html index 9155a64bd..4c7dd0970 100644 --- a/app/views/index.scala.html +++ b/app/views/index.scala.html @@ -1,8 +1,19 @@ @() - -

Congratulations! You are reading the page!

- + +

Congratulations! You are reading the page!

+ +

+ You should look for the HTTPS indicator in the browser toolbar. If you don't find it: +

+ +
    +
  • Generate the certificates and install as described in the README
  • +
  • Set up the example.com domain in /etc/hosts as described in the README
  • +
  • Run "./play run"
  • +
+ + diff --git a/build.sbt b/build.sbt index 419bf63f5..34eae755b 100644 --- a/build.sbt +++ b/build.sbt @@ -4,14 +4,7 @@ version := "1.0.0" lazy val root = (project in file(".")).enablePlugins(PlayScala) -scalaVersion := "2.11.1" - -// We require JDK 1.8 to show usage of the latest JSSE APIs. -initialize := { - val _ = initialize.value // run the previous initialization - val specVersion = sys.props("java.specification.version") - assert(specVersion.contains("1.8"), "Java 1.8.0 or above required") -} +scalaVersion := "2.11.6" libraryDependencies ++= Seq( ws diff --git a/conf/application.conf b/conf/application.conf index e7859cbe8..ed986eab4 100644 --- a/conf/application.conf +++ b/conf/application.conf @@ -1,18 +1,8 @@ # See http://www.playframework.com/documentation/latest/ApplicationSecret for more details. -application.secret="cnwrSeFsJ8gur>ERM;;kAKmHtQlqi + --> + + + + + + + ${application.home}/logs/application.log + + %date [%level] from %logger in %thread - %message%n%xException + + + + + + %coloredLevel %logger{15} - %message%n%xException{10} + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/conf/ws.conf b/conf/ws.conf index a99053e77..440f144d4 100644 --- a/conf/ws.conf +++ b/conf/ws.conf @@ -1,4 +1,4 @@ -ws.ssl { +play.ws.ssl { protocol = "TLSv1.2" diff --git a/play b/play index d9fc0e553..458eb1f23 100755 --- a/play +++ b/play @@ -1,6 +1,6 @@ #!/bin/bash -ACTIVATOR=./activator +ACTIVATOR=activator # Export the keystore password for use in ws.conf export KEY_PASSWORD=`cat certs/password` @@ -59,4 +59,4 @@ JVM_OPTIONS="$JVM_OPTIONS -Dsun.security.ssl.allowLegacyHelloMessages=false" #JVM_OPTIONS="$JVM_OPTIONS -Djava.security.debug=certpath:x509:ocsp" # Run Play -$ACTIVATOR $JVM_OPTIONS $*; \ No newline at end of file +$ACTIVATOR $JVM_OPTIONS $*; diff --git a/project/build.properties b/project/build.properties index a588da102..9b11f2742 100644 --- a/project/build.properties +++ b/project/build.properties @@ -1,4 +1,4 @@ #Activator-generated Properties #Sun Jul 06 17:54:30 PDT 2014 template.uuid=af582966-096a-43df-a504-5ddae8d4ebf1 -sbt.version=0.13.5 +sbt.version=0.13.8 diff --git a/project/plugins.sbt b/project/plugins.sbt index 17d13506d..1705a22eb 100644 --- a/project/plugins.sbt +++ b/project/plugins.sbt @@ -1,18 +1,5 @@ resolvers += "Typesafe repository" at "http://repo.typesafe.com/typesafe/releases/" // The Play plugin -addSbtPlugin("com.typesafe.play" % "sbt-plugin" % "2.3.1") +addSbtPlugin("com.typesafe.play" % "sbt-plugin" % "2.4.0") -// web plugins - -addSbtPlugin("com.typesafe.sbt" % "sbt-coffeescript" % "1.0.0") - -addSbtPlugin("com.typesafe.sbt" % "sbt-less" % "1.0.0") - -addSbtPlugin("com.typesafe.sbt" % "sbt-jshint" % "1.0.0") - -addSbtPlugin("com.typesafe.sbt" % "sbt-rjs" % "1.0.1") - -addSbtPlugin("com.typesafe.sbt" % "sbt-digest" % "1.0.0") - -addSbtPlugin("com.typesafe.sbt" % "sbt-mocha" % "1.0.0") From de99f2f0e82aa17405a84bc0cdb340016729b059 Mon Sep 17 00:00:00 2001 From: Will Sargent Date: Tue, 9 Jun 2015 09:49:02 +0200 Subject: [PATCH 07/53] Add integration test for Play TLS example. --- app/Main.scala | 16 ++---- app/https/ClientMethods.scala | 22 ++++++++ build.sbt | 3 +- test/integration/HowsMySSLSpec.scala | 77 ++++++++++++++++++++++++++++ 4 files changed, 104 insertions(+), 14 deletions(-) create mode 100644 app/https/ClientMethods.scala create mode 100644 test/integration/HowsMySSLSpec.scala diff --git a/app/Main.scala b/app/Main.scala index a0d21f953..ec5d39391 100644 --- a/app/Main.scala +++ b/app/Main.scala @@ -1,3 +1,4 @@ +import https.ClientMethods import play.api.{Mode, Environment} import play.api.libs.ws._ import play.api.libs.ws.ning._ @@ -12,18 +13,7 @@ import scala.util.{Failure, Success} * * Please see http://www.playframework.com/documentation/2.3.x/WsSSL for more details. */ -object Main { - - def newClient(configuration: play.api.Configuration, environment: Environment): NingWSClient = { - val parser = new WSConfigParser(configuration, environment) - val clientConfig = parser.parse() - val ningParser = new NingWSClientConfigParser(clientConfig, configuration, environment) - val ningClientConfig = ningParser.parse() - val builder = new NingAsyncHttpClientConfigBuilder(ningClientConfig) - val asyncHttpClientConfig = builder.build() - val client = new NingWSClient(asyncHttpClientConfig) - client - } +object Main extends https.ClientMethods { def printResponse(response:WSResponse) = { response.allHeaders.foreach { header => @@ -38,7 +28,7 @@ object Main { val config = play.api.Configuration(ConfigFactory.load("ws.conf")) val environment = play.api.Environment.simple(new java.io.File("./conf"), Mode.Dev) - val client = newClient(config, environment) + val client = createClient(config, environment) val futureResponse = client.url("https://example.com:9443").get() futureResponse.onComplete { diff --git a/app/https/ClientMethods.scala b/app/https/ClientMethods.scala new file mode 100644 index 000000000..cf15eec94 --- /dev/null +++ b/app/https/ClientMethods.scala @@ -0,0 +1,22 @@ +package https + +import play.api.Environment +import play.api.libs.ws.WSConfigParser +import play.api.libs.ws.ning.{NingAsyncHttpClientConfigBuilder, NingWSClient, NingWSClientConfigParser} + +/** + * + */ +trait ClientMethods { + + def createClient(configuration: play.api.Configuration, environment: Environment): NingWSClient = { + val parser = new WSConfigParser(configuration, environment) + val clientConfig = parser.parse() + val ningParser = new NingWSClientConfigParser(clientConfig, configuration, environment) + val ningClientConfig = ningParser.parse() + val builder = new NingAsyncHttpClientConfigBuilder(ningClientConfig) + val asyncHttpClientConfig = builder.build() + val client = new NingWSClient(asyncHttpClientConfig) + client + } +} diff --git a/build.sbt b/build.sbt index 34eae755b..10f2e2481 100644 --- a/build.sbt +++ b/build.sbt @@ -7,5 +7,6 @@ lazy val root = (project in file(".")).enablePlugins(PlayScala) scalaVersion := "2.11.6" libraryDependencies ++= Seq( - ws + ws, + specs2 % Test ) diff --git a/test/integration/HowsMySSLSpec.scala b/test/integration/HowsMySSLSpec.scala new file mode 100644 index 000000000..941d2a223 --- /dev/null +++ b/test/integration/HowsMySSLSpec.scala @@ -0,0 +1,77 @@ +package integration + +import com.typesafe.config.ConfigFactory +import org.junit.runner._ +import org.specs2.runner._ +import play.api.Mode +import play.api.libs.json.Json +import play.api.test._ + +import scala.concurrent.duration._ + +@RunWith(classOf[JUnitRunner]) +class HowsMySSLSpec extends PlaySpecification with https.ClientMethods { + + "WS" should { + + "connect to a remote server " in { + val input = """play.ws.ssl { + | //enabledProtocols = [ TLSv1.2 ] + |} + """.stripMargin + val config = play.api.Configuration(ConfigFactory.parseString(input).withFallback(ConfigFactory.defaultReference())) + val environment = play.api.Environment.simple(new java.io.File("./conf"), Mode.Dev) + val client = createClient(config, environment) + + val response = await(client.url("https://www.howsmyssl.com/a/check").get())(2 seconds) + val jsonOutput = response.json + val expected = + """{"given_cipher_suites":[ + | "TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256", + | "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256", + | "TLS_RSA_WITH_AES_128_CBC_SHA256", + | "TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256", + | "TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256", + | "TLS_DHE_RSA_WITH_AES_128_CBC_SHA256", + | "TLS_DHE_DSS_WITH_AES_128_CBC_SHA256", + | "TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA", + | "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA", + | "TLS_RSA_WITH_AES_128_CBC_SHA", + | "TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA", + | "TLS_ECDH_RSA_WITH_AES_128_CBC_SHA", + | "TLS_DHE_RSA_WITH_AES_128_CBC_SHA", + | "TLS_DHE_DSS_WITH_AES_128_CBC_SHA", + | "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256", + | "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256", + | "TLS_RSA_WITH_AES_128_GCM_SHA256", + | "TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256", + | "TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256", + | "TLS_DHE_RSA_WITH_AES_128_GCM_SHA256", + | "TLS_DHE_DSS_WITH_AES_128_GCM_SHA256", + | "TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA", + | "TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA", + | "TLS_RSA_WITH_3DES_EDE_CBC_SHA", + | "TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA", + | "TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA", + | "TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA", + | "TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA", + | "TLS_EMPTY_RENEGOTIATION_INFO_SCSV" + | ], + | "ephemeral_keys_supported":true, + | "session_ticket_supported":false, + | "tls_compression_supported":false, + | "unknown_cipher_suite_supported":false, + | "beast_vuln":false, + | "able_to_detect_n_minus_one_splitting":false, + | "insecure_cipher_suites":{}, + | "tls_version":"TLS 1.2", + | "rating":"Improvable" + |} + """.stripMargin + val expectedJson = Json.parse(expected) + + jsonOutput must beEqualTo(expectedJson) + } + } + +} \ No newline at end of file From d42c43d24ec50877644e09629660e19f916d3954 Mon Sep 17 00:00:00 2001 From: Will Sargent Date: Thu, 26 May 2016 18:33:27 -0700 Subject: [PATCH 08/53] Upgrade to Play 2.5.3 --- app/Main.scala | 13 +++++- app/controllers/Application.scala | 4 +- app/https/ClientMethods.scala | 16 ++++---- build.sbt | 2 +- conf/logback.xml | 6 +-- project/build.properties | 2 +- project/plugins.sbt | 2 +- test/integration/HowsMySSLSpec.scala | 61 +++++++--------------------- 8 files changed, 42 insertions(+), 64 deletions(-) diff --git a/app/Main.scala b/app/Main.scala index ec5d39391..c7204a798 100644 --- a/app/Main.scala +++ b/app/Main.scala @@ -1,10 +1,12 @@ +import akka.actor.ActorSystem +import akka.stream.ActorMaterializer import https.ClientMethods -import play.api.{Mode, Environment} +import play.api.{Environment, Mode} import play.api.libs.ws._ import play.api.libs.ws.ning._ import play.api.libs.ws.ssl.debug.DebugConfiguration - import com.typesafe.config.ConfigFactory +import play.api.test.WsTestClient import scala.util.{Failure, Success} @@ -28,6 +30,11 @@ object Main extends https.ClientMethods { val config = play.api.Configuration(ConfigFactory.load("ws.conf")) val environment = play.api.Environment.simple(new java.io.File("./conf"), Mode.Dev) + + val name = "testing" + val system = ActorSystem(name) + implicit val materializer = ActorMaterializer(namePrefix = Some(name))(system) + val client = createClient(config, environment) val futureResponse = client.url("https://example.com:9443").get() @@ -40,5 +47,7 @@ object Main extends https.ClientMethods { Console.println(s"failure = $f") client.close() } + + system.terminate() } } diff --git a/app/controllers/Application.scala b/app/controllers/Application.scala index 195c8cfb4..924337881 100644 --- a/app/controllers/Application.scala +++ b/app/controllers/Application.scala @@ -3,10 +3,10 @@ package controllers import play.api._ import play.api.mvc._ -object Application extends Controller { +class Application extends Controller { def index = Action { Ok(views.html.index()) } -} \ No newline at end of file +} diff --git a/app/https/ClientMethods.scala b/app/https/ClientMethods.scala index cf15eec94..8e6423166 100644 --- a/app/https/ClientMethods.scala +++ b/app/https/ClientMethods.scala @@ -1,22 +1,24 @@ package https +import akka.stream.Materializer +import org.asynchttpclient.AsyncHttpClientConfig import play.api.Environment import play.api.libs.ws.WSConfigParser -import play.api.libs.ws.ning.{NingAsyncHttpClientConfigBuilder, NingWSClient, NingWSClientConfigParser} +import play.api.libs.ws.ahc._ /** * */ trait ClientMethods { - def createClient(configuration: play.api.Configuration, environment: Environment): NingWSClient = { + def createClient(configuration: play.api.Configuration, environment: Environment)(implicit mat: Materializer) = { val parser = new WSConfigParser(configuration, environment) val clientConfig = parser.parse() - val ningParser = new NingWSClientConfigParser(clientConfig, configuration, environment) - val ningClientConfig = ningParser.parse() - val builder = new NingAsyncHttpClientConfigBuilder(ningClientConfig) - val asyncHttpClientConfig = builder.build() - val client = new NingWSClient(asyncHttpClientConfig) + val ahcParser = new AhcWSClientConfigParser(clientConfig, configuration, environment) + val ahcConfig = ahcParser.parse() + val builder = new AhcConfigBuilder(ahcConfig) + val asyncHttpClientConfig: AsyncHttpClientConfig = builder.build() + val client = new AhcWSClient(asyncHttpClientConfig)(mat) client } } diff --git a/build.sbt b/build.sbt index 10f2e2481..59c6bfbbf 100644 --- a/build.sbt +++ b/build.sbt @@ -4,7 +4,7 @@ version := "1.0.0" lazy val root = (project in file(".")).enablePlugins(PlayScala) -scalaVersion := "2.11.6" +scalaVersion := "2.11.8" libraryDependencies ++= Seq( ws, diff --git a/conf/logback.xml b/conf/logback.xml index 76534affc..804ffacc2 100644 --- a/conf/logback.xml +++ b/conf/logback.xml @@ -4,10 +4,10 @@ - + - ${application.home}/logs/application.log + ${application.home:-.}/logs/application.log %date [%level] from %logger in %thread - %message%n%xException @@ -41,4 +41,4 @@ - \ No newline at end of file + diff --git a/project/build.properties b/project/build.properties index 9b11f2742..b8490b554 100644 --- a/project/build.properties +++ b/project/build.properties @@ -1,4 +1,4 @@ #Activator-generated Properties #Sun Jul 06 17:54:30 PDT 2014 template.uuid=af582966-096a-43df-a504-5ddae8d4ebf1 -sbt.version=0.13.8 +sbt.version=0.13.11 diff --git a/project/plugins.sbt b/project/plugins.sbt index 1705a22eb..3af9547cc 100644 --- a/project/plugins.sbt +++ b/project/plugins.sbt @@ -1,5 +1,5 @@ resolvers += "Typesafe repository" at "http://repo.typesafe.com/typesafe/releases/" // The Play plugin -addSbtPlugin("com.typesafe.play" % "sbt-plugin" % "2.4.0") +addSbtPlugin("com.typesafe.play" % "sbt-plugin" % "2.5.3") diff --git a/test/integration/HowsMySSLSpec.scala b/test/integration/HowsMySSLSpec.scala index 941d2a223..da0587694 100644 --- a/test/integration/HowsMySSLSpec.scala +++ b/test/integration/HowsMySSLSpec.scala @@ -1,10 +1,12 @@ package integration +import akka.actor.ActorSystem +import akka.stream.ActorMaterializer import com.typesafe.config.ConfigFactory import org.junit.runner._ import org.specs2.runner._ import play.api.Mode -import play.api.libs.json.Json +import play.api.libs.json.{JsValue, Json} import play.api.test._ import scala.concurrent.duration._ @@ -21,57 +23,22 @@ class HowsMySSLSpec extends PlaySpecification with https.ClientMethods { """.stripMargin val config = play.api.Configuration(ConfigFactory.parseString(input).withFallback(ConfigFactory.defaultReference())) val environment = play.api.Environment.simple(new java.io.File("./conf"), Mode.Dev) + + val name = "testing" + val system = ActorSystem(name) + implicit val materializer = ActorMaterializer(namePrefix = Some(name))(system) + val client = createClient(config, environment) val response = await(client.url("https://www.howsmyssl.com/a/check").get())(2 seconds) val jsonOutput = response.json - val expected = - """{"given_cipher_suites":[ - | "TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256", - | "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256", - | "TLS_RSA_WITH_AES_128_CBC_SHA256", - | "TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256", - | "TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256", - | "TLS_DHE_RSA_WITH_AES_128_CBC_SHA256", - | "TLS_DHE_DSS_WITH_AES_128_CBC_SHA256", - | "TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA", - | "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA", - | "TLS_RSA_WITH_AES_128_CBC_SHA", - | "TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA", - | "TLS_ECDH_RSA_WITH_AES_128_CBC_SHA", - | "TLS_DHE_RSA_WITH_AES_128_CBC_SHA", - | "TLS_DHE_DSS_WITH_AES_128_CBC_SHA", - | "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256", - | "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256", - | "TLS_RSA_WITH_AES_128_GCM_SHA256", - | "TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256", - | "TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256", - | "TLS_DHE_RSA_WITH_AES_128_GCM_SHA256", - | "TLS_DHE_DSS_WITH_AES_128_GCM_SHA256", - | "TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA", - | "TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA", - | "TLS_RSA_WITH_3DES_EDE_CBC_SHA", - | "TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA", - | "TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA", - | "TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA", - | "TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA", - | "TLS_EMPTY_RENEGOTIATION_INFO_SCSV" - | ], - | "ephemeral_keys_supported":true, - | "session_ticket_supported":false, - | "tls_compression_supported":false, - | "unknown_cipher_suite_supported":false, - | "beast_vuln":false, - | "able_to_detect_n_minus_one_splitting":false, - | "insecure_cipher_suites":{}, - | "tls_version":"TLS 1.2", - | "rating":"Improvable" - |} - """.stripMargin - val expectedJson = Json.parse(expected) - jsonOutput must beEqualTo(expectedJson) + system.terminate() + client.close() + + val tlsVersion = (jsonOutput \ "tls_version").as[String] + tlsVersion must contain("TLS 1.2") } } -} \ No newline at end of file +} From dd99b66e5b80310ee3ed8bc0924e38c0c5e75d68 Mon Sep 17 00:00:00 2001 From: Will Sargent Date: Fri, 8 Jul 2016 17:37:52 -0700 Subject: [PATCH 09/53] Add SNI support --- LICENSE | 10 +- README.md | 20 ++-- app/Main.scala | 10 +- app/controllers/Application.scala | 12 --- app/controllers/HomeController.scala | 23 ++++ app/https/CustomSSLEngineProvider.scala | 19 +++- app/https/SniKeyManager.scala | 100 ++++++++++++++++++ app/router/MultiSiteRequestHandler.scala | 36 +++++++ app/views/forHost.scala.html | 3 + app/views/index.scala.html | 6 +- build.sbt | 17 ++- conf/application.conf | 2 +- conf/logback.xml | 3 +- conf/routes | 10 +- conf/ws.conf | 8 +- .../one/app/controllers/HomeController.scala | 24 +++++ modules/one/app/views/one/index.scala.html | 13 +++ modules/one/conf/one.routes | 3 + modules/one/project/build.properties | 4 + .../two/app/controllers/HomeController.scala | 14 +++ modules/two/app/views/two/index.scala.html | 13 +++ modules/two/conf/two.routes | 4 + modules/two/project/build.properties | 1 + play | 2 +- scripts/{genserver.sh => gen-example.com.sh} | 0 scripts/gen-one.example.com.sh | 50 +++++++++ scripts/gen-two.example.com.sh | 50 +++++++++ scripts/gen-wildcard.example.com.sh | 50 +++++++++ scripts/gencerts.sh | 7 +- 29 files changed, 464 insertions(+), 50 deletions(-) delete mode 100644 app/controllers/Application.scala create mode 100644 app/controllers/HomeController.scala create mode 100644 app/https/SniKeyManager.scala create mode 100644 app/router/MultiSiteRequestHandler.scala create mode 100644 app/views/forHost.scala.html create mode 100644 modules/one/app/controllers/HomeController.scala create mode 100644 modules/one/app/views/one/index.scala.html create mode 100644 modules/one/conf/one.routes create mode 100644 modules/one/project/build.properties create mode 100644 modules/two/app/controllers/HomeController.scala create mode 100644 modules/two/app/views/two/index.scala.html create mode 100644 modules/two/conf/two.routes create mode 100644 modules/two/project/build.properties rename scripts/{genserver.sh => gen-example.com.sh} (100%) create mode 100755 scripts/gen-one.example.com.sh create mode 100755 scripts/gen-two.example.com.sh create mode 100755 scripts/gen-wildcard.example.com.sh diff --git a/LICENSE b/LICENSE index b8dd751c9..4d9259c30 100644 --- a/LICENSE +++ b/LICENSE @@ -1,4 +1,4 @@ -Copyright 2014 Typesafe, Inc. +Copyright 2014 - 2016 Lightbend, Inc. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -10,4 +10,10 @@ Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and -limitations under the License. \ No newline at end of file +limitations under the License. + +The SNIKeyManager is Copyright (c) 2014 Graham Edgecombe under the following license: + +"Permission to use, copy, modify, and/or distribute this software for any +purpose with or without fee is hereby granted, provided that the above +copyright notice and this permission notice appear in all copies." diff --git a/README.md b/README.md index d117fd373..a59517666 100644 --- a/README.md +++ b/README.md @@ -27,16 +27,6 @@ cd scripts/ ./gencerts.sh ``` -and move all of the generated files into the (newly created) `certs` directory: - -``` -cd scripts -mkdir ../certs -mv client* ../certs -mv example* ../certs -mv password ../certs -``` - ## Point example.com to localhost You may have noticed that the name on the generated certificates is `example.com` -- HTTPS requires that you have a reasonable hostname for your server. @@ -48,7 +38,7 @@ $ sudo vi /etc/hosts ``` ``` -127.0.0.1 example.com www.example.com +127.0.0.1 example.com one.example.com two.example.com ``` ## Run Play with HTTPS configuration @@ -57,12 +47,18 @@ Now that you've generated the certificates and added `example.com` to `/etc/host This application is not run with `activator` -- you should run it with `./play` instead, as there are a number of system properties required to use it effectively. -The `CustomSSLEngineProvider` is responsible for Play's HTTPS server. More details can be found in [Configuring HTTPS](http://www.playframework.com/documentation/2.3.x/ConfiguringHttps). +The `CustomSSLEngineProvider` is responsible for Play's HTTPS server. More details can be found in [Configuring HTTPS](http://www.playframework.com/documentation/2.5.x/ConfiguringHttps). ``` ./play run ``` +## Run Server Name Indication + +If you want to return different certificates for the hostname, you can use the SniKeyManager to return an alias corresponding to the hostname. + +For example, going to "http://one.example.com:9443" will return a certificate corresponding to "one.example.com", while "http://two.example.com:9443" will return a certificate corresponding to "two.example.com". + ## Checking the list of cipher suites: Download SSLyze: diff --git a/app/Main.scala b/app/Main.scala index c7204a798..4e30109bf 100644 --- a/app/Main.scala +++ b/app/Main.scala @@ -17,12 +17,14 @@ import scala.util.{Failure, Success} */ object Main extends https.ClientMethods { + private val logger = org.slf4j.LoggerFactory.getLogger("application") + def printResponse(response:WSResponse) = { response.allHeaders.foreach { header => - Console.println(s"header = $header") + logger.info(s"header = $header") } val body = response.body - Console.println(s"body = $body") + logger.info(s"body = $body") } def main(args: Array[String]) { @@ -37,14 +39,14 @@ object Main extends https.ClientMethods { val client = createClient(config, environment) - val futureResponse = client.url("https://example.com:9443").get() + val futureResponse = client.url("https://one.example.com:9443").get() futureResponse.onComplete { case Success(response) => printResponse(response) client.close() // closing the client must be done manually. case Failure(f) => - Console.println(s"failure = $f") + logger.error(s"failure = $f", f) client.close() } diff --git a/app/controllers/Application.scala b/app/controllers/Application.scala deleted file mode 100644 index 924337881..000000000 --- a/app/controllers/Application.scala +++ /dev/null @@ -1,12 +0,0 @@ -package controllers - -import play.api._ -import play.api.mvc._ - -class Application extends Controller { - - def index = Action { - Ok(views.html.index()) - } - -} diff --git a/app/controllers/HomeController.scala b/app/controllers/HomeController.scala new file mode 100644 index 000000000..a553a74dd --- /dev/null +++ b/app/controllers/HomeController.scala @@ -0,0 +1,23 @@ +package controllers + +import play.api._ +import play.api.mvc._ + +class HomeController extends Controller { + + private val allowedHosts = Seq("one", "two") + + def index = Action { implicit request => + Ok(views.html.index()) + } + + def forHost(host: String) = Action { implicit request => + if (allowedHosts.contains(host)) { + Ok(views.html.forHost(host)) + } else { + Forbidden("Not an allowed host") + } + } + +} + diff --git a/app/https/CustomSSLEngineProvider.scala b/app/https/CustomSSLEngineProvider.scala index f9c9c5c4d..58189c843 100644 --- a/app/https/CustomSSLEngineProvider.scala +++ b/app/https/CustomSSLEngineProvider.scala @@ -9,18 +9,20 @@ import play.server.api._ class CustomSSLEngineProvider(appProvider: ApplicationProvider) extends SSLEngineProvider { + val certificateDirectory: String = "scripts" + def readPassword(): Array[Char] = { - val passwordPath = FileSystems.getDefault.getPath("certs", "password") + val passwordPath = FileSystems.getDefault.getPath(certificateDirectory, "password") Files.readAllLines(passwordPath).get(0).toCharArray } def readKeyInputStream(): java.io.InputStream = { - val keyPath = FileSystems.getDefault.getPath("certs", "example.com.jks") + val keyPath = FileSystems.getDefault.getPath(certificateDirectory, "example.com.jks") Files.newInputStream(keyPath) } def readTrustInputStream(): java.io.InputStream = { - val keyPath = FileSystems.getDefault.getPath("certs", "clientca.jks") + val keyPath = FileSystems.getDefault.getPath(certificateDirectory, "clientca.jks") Files.newInputStream(keyPath) } @@ -32,7 +34,14 @@ class CustomSSLEngineProvider(appProvider: ApplicationProvider) extends SSLEngin keyStore.load(keyInputStream, password) val kmf = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm) kmf.init(keyStore, password) - kmf.getKeyManagers + + // Now that we have the key manager, we have to extend it with SNIKeyManager so we + // get the extendedEngineAlias + val keyManagers = kmf.getKeyManagers + val onlyKeyManager: X509ExtendedKeyManager = keyManagers(0).asInstanceOf[X509ExtendedKeyManager] + val defaultAlias = Some("wildcard.example.com") + val sniKeyManager = new SniKeyManager(onlyKeyManager, defaultAlias) + Array(sniKeyManager) } finally { keyInputStream.close() } @@ -83,4 +92,4 @@ class CustomSSLEngineProvider(appProvider: ApplicationProvider) extends SSLEngin engine } -} \ No newline at end of file +} diff --git a/app/https/SniKeyManager.scala b/app/https/SniKeyManager.scala new file mode 100644 index 000000000..2102d6d8b --- /dev/null +++ b/app/https/SniKeyManager.scala @@ -0,0 +1,100 @@ +/* +Copyright (c) 2014 Graham Edgecombe +Permission to use, copy, modify, and/or distribute this software for any +purpose with or without fee is hereby granted, provided that the above +copyright notice and this permission notice appear in all copies. + +THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +*/ +package https + +import java.net.Socket +import java.security.cert.X509Certificate +import java.security.{Principal, PrivateKey} +import javax.net.ssl._ + +import org.slf4j.Logger + +/** + * This class picks out a specific certificate when given a request that has + * an SNI hostname associated with it. This is done through + * chooseEngineServerAlias, which under normal circumstances return null, but + * in this case should return the alias associated with the sni hostname. + * + * Taken from https://github.com/grahamedgecombe/netty-sni-example + */ +final class SniKeyManager(val keyManager: X509ExtendedKeyManager, val defaultAlias: Option[String]) extends X509ExtendedKeyManager { + + private val logger: Logger = org.slf4j.LoggerFactory.getLogger(this.getClass) + + override def getClientAliases(keyType: String, issuers: Array[Principal]): Array[String] = { + throw new UnsupportedOperationException + } + + override def chooseClientAlias(keyType: Array[String], issuers: Array[Principal], socket: Socket): String = { + throw new UnsupportedOperationException + } + + override def chooseEngineClientAlias(keyType: Array[String], issuers: Array[Principal], engine: SSLEngine): String = { + throw new UnsupportedOperationException + } + + override def getServerAliases(keyType: String, issuers: Array[Principal]): Array[String] = { + keyManager.getServerAliases(keyType, issuers) + } + + override def chooseServerAlias(keyType: String, issuers: Array[Principal], socket: Socket): String = { + throw new UnsupportedOperationException + } + + /** + * Returns an alias (a name to pick out of the keystore) when given a hostname. + */ + override def chooseEngineServerAlias(keyType: String, issuers: Array[Principal], engine: SSLEngine): String = { + val session: ExtendedSSLSession = engine.getHandshakeSession.asInstanceOf[ExtendedSSLSession] + + getSNIHostname(session) match { + case Some(hostname) if hasCertChain(hostname) && hasPrivateKey(hostname) => + logger.debug("chooseEngineServerAlias: using selected sniHostname {} as server alias", hostname) + hostname + case None => + defaultAlias match { + case Some(alias) => + logger.debug("chooseEngineServerAlias: using defaultAlias {} as server alias", defaultAlias) + alias + case None => + logger.debug("chooseEngineServerAlias: no alias found, using super method") + super.chooseEngineServerAlias(keyType, issuers, engine) + } + } + } + + override def getCertificateChain(alias: String): Array[X509Certificate] = { + keyManager.getCertificateChain(alias) + } + + override def getPrivateKey(alias: String): PrivateKey = { + keyManager.getPrivateKey(alias) + } + + private def getSNIHostname(session: ExtendedSSLSession): Option[String] = { + import scala.collection.JavaConverters._ + session.getRequestedServerNames.asScala.find { name => + name.getType == StandardConstants.SNI_HOST_NAME + }.map { + case name: SNIHostName => + name.getAsciiName + } + } + + private def hasCertChain(hostname: String): Boolean = getCertificateChain(hostname) != null + + private def hasPrivateKey(hostname: String): Boolean = getPrivateKey(hostname) != null + +} diff --git a/app/router/MultiSiteRequestHandler.scala b/app/router/MultiSiteRequestHandler.scala new file mode 100644 index 000000000..321906fcb --- /dev/null +++ b/app/router/MultiSiteRequestHandler.scala @@ -0,0 +1,36 @@ +package router + +import javax.inject._ + +import play.api.mvc.RequestHeader +import play.api.http.HttpConfiguration +import play.api.http.DefaultHttpRequestHandler +import play.api.http.HttpErrorHandler +import play.api.http._ + +class MultiSiteRequestHandler @Inject() (errorHandler: HttpErrorHandler, + configuration: HttpConfiguration, + filters: HttpFilters, + defaultRouter: router.Routes, + oneRouter: one.Routes, + twoRouter: two.Routes) + extends DefaultHttpRequestHandler(defaultRouter, errorHandler, configuration, filters) { + + override def routeRequest(request: RequestHeader) = { + + // assuming local ports in development -- will need to change in prod + val host = request.host.split(":")(0) + + host match { + case "one.example.com" => + oneRouter.routes.lift(request) + + case "two.example.com" => + twoRouter.routes.lift(request) + + case other => + super.routeRequest(request) + } + + } +} diff --git a/app/views/forHost.scala.html b/app/views/forHost.scala.html new file mode 100644 index 000000000..21134971e --- /dev/null +++ b/app/views/forHost.scala.html @@ -0,0 +1,3 @@ +@(host: String) + +This is the redirection page for @host site. diff --git a/app/views/index.scala.html b/app/views/index.scala.html index 4c7dd0970..13f3232d6 100644 --- a/app/views/index.scala.html +++ b/app/views/index.scala.html @@ -2,7 +2,11 @@ -

Congratulations! You are reading the page!

+

Congratulations! You are reading the page! This is the "default" page.

+ +

+ The X.509 certificate the server sent you should be for "example.com". You can go to one.example.com or two.example.com to see ServerNameIndication at work. +

You should look for the HTTPS indicator in the browser toolbar. If you don't find it: diff --git a/build.sbt b/build.sbt index 59c6bfbbf..776848f39 100644 --- a/build.sbt +++ b/build.sbt @@ -2,11 +2,26 @@ name := """activator-play-tls-example""" version := "1.0.0" +lazy val one = (project in file("modules/one")).enablePlugins(PlayScala) + +lazy val two = (project in file("modules/two")).enablePlugins(PlayScala) + lazy val root = (project in file(".")).enablePlugins(PlayScala) + .aggregate(one, two) + .dependsOn(one, two) -scalaVersion := "2.11.8" +scalaVersion in ThisBuild := "2.11.8" libraryDependencies ++= Seq( ws, specs2 % Test ) + +fork in run := true + +// Uncomment if you want to run "./play client" explicitly without SNI. +//javaOptions in run += "-Djsse.enableSNIExtension=false" + +javaOptions in run += "-Djavax.net.debug=ssl:handshake" + +addCommandAlias("client", "runMain Main") diff --git a/conf/application.conf b/conf/application.conf index ed986eab4..84eb9de06 100644 --- a/conf/application.conf +++ b/conf/application.conf @@ -4,5 +4,5 @@ play.crypto.secret=${?APPLICATION_SECRET} play.i18n.langs = ["en"] -include "ws" +play.http.requestHandler = "router.MultiSiteRequestHandler" diff --git a/conf/logback.xml b/conf/logback.xml index 804ffacc2..cff83df7a 100644 --- a/conf/logback.xml +++ b/conf/logback.xml @@ -28,7 +28,8 @@ - + + diff --git a/conf/routes b/conf/routes index 20fd042f3..544234a37 100644 --- a/conf/routes +++ b/conf/routes @@ -1,9 +1,5 @@ -# Routes -# This file defines all application routes (Higher priority routes first) -# ~~~~ +GET / controllers.HomeController.index() -# Home page -GET / controllers.Application.index +GET /for/*host controllers.HomeController.forHost(host) -# Map static resources from the /public folder to the /assets URL path -GET /assets/*file controllers.Assets.at(path="/public", file) +GET /assets/*file controllers.Assets.at(path="/public", file) diff --git a/conf/ws.conf b/conf/ws.conf index 440f144d4..c1cd73f49 100644 --- a/conf/ws.conf +++ b/conf/ws.conf @@ -1,5 +1,9 @@ play.ws.ssl { + debug = { + handshake = true + } + protocol = "TLSv1.2" enabledProtocols = [ "TLSv1.2" ] @@ -15,13 +19,13 @@ play.ws.ssl { keyManager = { stores = [ // Note: must be run from ./play, which loads the KEY_PASSWORD environment variable. - { type: "JKS", path: "certs/client.jks", password: ${?KEY_PASSWORD} }, + { type: "JKS", path: "scripts/client.jks", password: ${?KEY_PASSWORD} }, ] } trustManager = { stores = [ - { type = "JKS", path = "certs/exampletrust.jks" } + { type = "JKS", path = "scripts/exampletrust.jks" } ] } } diff --git a/modules/one/app/controllers/HomeController.scala b/modules/one/app/controllers/HomeController.scala new file mode 100644 index 000000000..8531ab4ee --- /dev/null +++ b/modules/one/app/controllers/HomeController.scala @@ -0,0 +1,24 @@ +package controllers.one + +import javax.inject._ +import play.api._ +import play.api.mvc._ + +/** + * This controller creates an `Action` to handle HTTP requests to the + * application's home page. + */ +@Singleton +class HomeController @Inject() extends Controller { + + /** + * Create an Action to render an HTML page with a welcome message. + * The configuration in the `routes` file means that this method + * will be called when the application receives a `GET` request with + * a path of `/`. + */ + def index = Action { + Ok(views.html.one.index()) + } + +} diff --git a/modules/one/app/views/one/index.scala.html b/modules/one/app/views/one/index.scala.html new file mode 100644 index 000000000..c4ddd867f --- /dev/null +++ b/modules/one/app/views/one/index.scala.html @@ -0,0 +1,13 @@ +@() + + + + +

You are reading the page for one.example.com

+ +

+ The X.509 certificate the server sent you should be specifically for "one.example.com". + + + + diff --git a/modules/one/conf/one.routes b/modules/one/conf/one.routes new file mode 100644 index 000000000..7bcca0251 --- /dev/null +++ b/modules/one/conf/one.routes @@ -0,0 +1,3 @@ +GET / controllers.one.HomeController.index() + +GET /assets/*file controllers.Assets.at(path="/public/lib/one", file) diff --git a/modules/one/project/build.properties b/modules/one/project/build.properties new file mode 100644 index 000000000..e812e6272 --- /dev/null +++ b/modules/one/project/build.properties @@ -0,0 +1,4 @@ +#Activator-generated Properties +#Fri Jul 08 22:56:54 PDT 2016 +template.uuid=f57599cf-a4f5-4333-9ff1-55d48fd49891 +sbt.version=0.13.11 diff --git a/modules/two/app/controllers/HomeController.scala b/modules/two/app/controllers/HomeController.scala new file mode 100644 index 000000000..efa4a2499 --- /dev/null +++ b/modules/two/app/controllers/HomeController.scala @@ -0,0 +1,14 @@ +package controllers.two + +import javax.inject._ +import play.api._ +import play.api.mvc._ + +@Singleton +class HomeController @Inject() extends Controller { + + def index = Action { + Ok(views.html.two.index()) + } + +} diff --git a/modules/two/app/views/two/index.scala.html b/modules/two/app/views/two/index.scala.html new file mode 100644 index 000000000..97d4a0369 --- /dev/null +++ b/modules/two/app/views/two/index.scala.html @@ -0,0 +1,13 @@ +@() + + + + +

You are reading the page for two.example.com

+ +

+ The X.509 certificate the server sent you should be specifically for "two.example.com". + + + + diff --git a/modules/two/conf/two.routes b/modules/two/conf/two.routes new file mode 100644 index 000000000..24e45db3c --- /dev/null +++ b/modules/two/conf/two.routes @@ -0,0 +1,4 @@ +GET / controllers.two.HomeController.index() + + +GET /assets/*file controllers.Assets.at(path="/public/lib/two", file) diff --git a/modules/two/project/build.properties b/modules/two/project/build.properties new file mode 100644 index 000000000..43b8278c6 --- /dev/null +++ b/modules/two/project/build.properties @@ -0,0 +1 @@ +sbt.version=0.13.11 diff --git a/play b/play index 458eb1f23..5295b4bbd 100755 --- a/play +++ b/play @@ -3,7 +3,7 @@ ACTIVATOR=activator # Export the keystore password for use in ws.conf -export KEY_PASSWORD=`cat certs/password` +export KEY_PASSWORD=`cat scripts/password` # Turn on HTTPS, turn off HTTP. # This should be https://example.com:9443 diff --git a/scripts/genserver.sh b/scripts/gen-example.com.sh similarity index 100% rename from scripts/genserver.sh rename to scripts/gen-example.com.sh diff --git a/scripts/gen-one.example.com.sh b/scripts/gen-one.example.com.sh new file mode 100755 index 000000000..b8ada7bef --- /dev/null +++ b/scripts/gen-one.example.com.sh @@ -0,0 +1,50 @@ +#!/bin/bash + +export PW=`cat password` + +# Create a server certificate, tied to one.example.com +keytool -genkeypair -v \ + -alias one.example.com \ + -dname "CN=one.example.com, OU=Example Org, O=Example Company, L=San Francisco, ST=California, C=US" \ + -keystore example.com.jks \ + -keypass:env PW \ + -storepass:env PW \ + -keyalg EC \ + -keysize 256 \ + -validity 385 + +# Create a certificate signing request for one.example.com +keytool -certreq -v \ + -alias one.example.com \ + -keypass:env PW \ + -storepass:env PW \ + -keystore example.com.jks \ + -file one.example.com.csr + +# Tell exampleCA to sign the example.com certificate. +# Technically, digitalSignature for DHE or ECDHE, keyEncipherment for RSA +keytool -gencert -v \ + -alias exampleca \ + -keypass:env PW \ + -storepass:env PW \ + -keystore exampleca.jks \ + -infile one.example.com.csr \ + -outfile one.example.com.crt \ + -ext KeyUsage:critical="digitalSignature,keyEncipherment" \ + -ext EKU="serverAuth" \ + -ext SAN="DNS:one.example.com" \ + -rfc + +# Import the signed certificate back into example.com.jks +keytool -import -v \ + -alias one.example.com \ + -file one.example.com.crt \ + -keystore example.com.jks \ + -storetype JKS \ + -storepass:env PW + +# List out the contents of example.com.jks just to confirm it. +# If you are using Play as a TLS termination point, this is the key store you should use. +#keytool -list -v \ +# -keystore example.com.jks \ +# -storepass:env PW diff --git a/scripts/gen-two.example.com.sh b/scripts/gen-two.example.com.sh new file mode 100755 index 000000000..9a1ec0556 --- /dev/null +++ b/scripts/gen-two.example.com.sh @@ -0,0 +1,50 @@ +#!/bin/bash + +export PW=`cat password` + +# Create a server certificate, tied to two.example.com +keytool -genkeypair -v \ + -alias two.example.com \ + -dname "CN=two.example.com, OU=Example Org, O=Example Company, L=San Francisco, ST=California, C=US" \ + -keystore example.com.jks \ + -keypass:env PW \ + -storepass:env PW \ + -keyalg EC \ + -keysize 256 \ + -validity 385 + +# Create a certificate signing request for two.example.com +keytool -certreq -v \ + -alias two.example.com \ + -keypass:env PW \ + -storepass:env PW \ + -keystore example.com.jks \ + -file two.example.com.csr + +# Tell exampleCA to sign the two.example.com certificate. +# Technically, digitalSignature for DHE or ECDHE, keyEncipherment for RSA +keytool -gencert -v \ + -alias exampleca \ + -keypass:env PW \ + -storepass:env PW \ + -keystore exampleca.jks \ + -infile two.example.com.csr \ + -outfile two.example.com.crt \ + -ext KeyUsage:critical="digitalSignature,keyEncipherment" \ + -ext EKU="serverAuth" \ + -ext SAN="DNS:two.example.com" \ + -rfc + +# Import the signed certificate back into example.com.jks +keytool -import -v \ + -alias two.example.com \ + -file two.example.com.crt \ + -keystore example.com.jks \ + -storetype JKS \ + -storepass:env PW + +# List out the contents of example.com.jks just to confirm it. +# If you are using Play as a TLS termination point, this is the key store you should use. +#keytool -list -v \ +# -keystore example.com.jks \ +# -storepass:env PW diff --git a/scripts/gen-wildcard.example.com.sh b/scripts/gen-wildcard.example.com.sh new file mode 100755 index 000000000..2ff11e21f --- /dev/null +++ b/scripts/gen-wildcard.example.com.sh @@ -0,0 +1,50 @@ +#!/bin/bash + +export PW=`cat password` + +# Create a server certificate, tied to *.example.com +keytool -genkeypair -v \ + -alias wildcard.example.com \ + -dname "CN=*.example.com, OU=Example Org, O=Example Company, L=San Francisco, ST=California, C=US" \ + -keystore example.com.jks \ + -keypass:env PW \ + -storepass:env PW \ + -keyalg EC \ + -keysize 256 \ + -validity 385 + +# Create a certificate signing request for example.com +keytool -certreq -v \ + -alias wildcard.example.com \ + -keypass:env PW \ + -storepass:env PW \ + -keystore example.com.jks \ + -file wildcard.example.com.csr + +# Tell exampleCA to sign the example.com certificate. +# Technically, digitalSignature for DHE or ECDHE, keyEncipherment for RSA +# You'd think you could use SAN here, but https://stackoverflow.com/questions/33827789/self-signed-certificate-dnsname-components-must-begin-with-a-letter +keytool -gencert -v \ + -alias exampleca \ + -keypass:env PW \ + -storepass:env PW \ + -keystore exampleca.jks \ + -infile wildcard.example.com.csr \ + -outfile wildcard.example.com.crt \ + -ext KeyUsage:critical="digitalSignature,keyEncipherment" \ + -ext EKU="serverAuth" \ + -rfc + +# Import the signed certificate back into example.com.jks +keytool -import -v \ + -alias wildcard.example.com \ + -file wildcard.example.com.crt \ + -keystore example.com.jks \ + -storetype JKS \ + -storepass:env PW + +# List out the contents of example.com.jks just to confirm it. +# If you are using Play as a TLS termination point, this is the key store you should use. +#keytool -list -v \ +# -keystore example.com.jks \ +# -storepass:env PW diff --git a/scripts/gencerts.sh b/scripts/gencerts.sh index 1be10b8da..f50832043 100755 --- a/scripts/gencerts.sh +++ b/scripts/gencerts.sh @@ -7,5 +7,10 @@ echo ${PW} > ${DIR}/password ${DIR}/genca.sh ${DIR}/genclient.sh -${DIR}/genserver.sh + +${DIR}/gen-example.com.sh +${DIR}/gen-one.example.com.sh +${DIR}/gen-two.example.com.sh +${DIR}/gen-wildcard.example.com.sh + ${DIR}/gentrustanchor.sh From cc7d7d9de64ed8044a9fec510b9075aa2dc13d88 Mon Sep 17 00:00:00 2001 From: Will Sargent Date: Sun, 10 Jul 2016 17:50:58 -0700 Subject: [PATCH 10/53] Tweak the fallback for wildcard virtual hosts --- README.md | 10 ++++++---- app/controllers/HomeController.scala | 13 +++++-------- app/https/SniKeyManager.scala | 2 +- app/views/forHost.scala.html | 2 +- conf/routes | 2 +- 5 files changed, 14 insertions(+), 15 deletions(-) diff --git a/README.md b/README.md index a59517666..2a96cb2e9 100644 --- a/README.md +++ b/README.md @@ -38,12 +38,12 @@ $ sudo vi /etc/hosts ``` ``` -127.0.0.1 example.com one.example.com two.example.com +127.0.0.1 example.com one.example.com two.example.com three.example.com ``` ## Run Play with HTTPS configuration -Now that you've generated the certificates and added `example.com` to `/etc/hosts`, you can start Play itself. +Now that you've generated the certificates and added the `example.com` host entries to `/etc/hosts`, you can start Play itself. This application is not run with `activator` -- you should run it with `./play` instead, as there are a number of system properties required to use it effectively. @@ -53,11 +53,13 @@ The `CustomSSLEngineProvider` is responsible for Play's HTTPS server. More deta ./play run ``` -## Run Server Name Indication +## Virtual Hosts and Server Name Indication If you want to return different certificates for the hostname, you can use the SniKeyManager to return an alias corresponding to the hostname. -For example, going to "http://one.example.com:9443" will return a certificate corresponding to "one.example.com", while "http://two.example.com:9443" will return a certificate corresponding to "two.example.com". +For example, going to "https://one.example.com:9443" will return a certificate corresponding to "one.example.com", while "https://two.example.com:9443" will return a certificate corresponding to "two.example.com". + +If there is no match, then a wildcard certificate will be used, and the main website's index method will redirect to `forHost` with the hostname. So, if you go to "https://three.example.com:9443" and there is no site for that, the wildcard certificate and the home page will redirect you to "https://three.example.com:9443/for/three". ## Checking the list of cipher suites: diff --git a/app/controllers/HomeController.scala b/app/controllers/HomeController.scala index a553a74dd..2de9c1874 100644 --- a/app/controllers/HomeController.scala +++ b/app/controllers/HomeController.scala @@ -5,18 +5,15 @@ import play.api.mvc._ class HomeController extends Controller { - private val allowedHosts = Seq("one", "two") - def index = Action { implicit request => - Ok(views.html.index()) + val filtered = request.host.split(":")(0).replace(".example.com", "") + + Redirect(routes.HomeController.forHost(filtered)) } def forHost(host: String) = Action { implicit request => - if (allowedHosts.contains(host)) { - Ok(views.html.forHost(host)) - } else { - Forbidden("Not an allowed host") - } + // prevent any browser caching... + Ok(views.html.forHost(host)).withHeaders("Cache-Control" -> "no-store") } } diff --git a/app/https/SniKeyManager.scala b/app/https/SniKeyManager.scala index 2102d6d8b..07abc2566 100644 --- a/app/https/SniKeyManager.scala +++ b/app/https/SniKeyManager.scala @@ -63,7 +63,7 @@ final class SniKeyManager(val keyManager: X509ExtendedKeyManager, val defaultAli case Some(hostname) if hasCertChain(hostname) && hasPrivateKey(hostname) => logger.debug("chooseEngineServerAlias: using selected sniHostname {} as server alias", hostname) hostname - case None => + case _ => defaultAlias match { case Some(alias) => logger.debug("chooseEngineServerAlias: using defaultAlias {} as server alias", defaultAlias) diff --git a/app/views/forHost.scala.html b/app/views/forHost.scala.html index 21134971e..b5e62eebb 100644 --- a/app/views/forHost.scala.html +++ b/app/views/forHost.scala.html @@ -1,3 +1,3 @@ @(host: String) -This is the redirection page for @host site. +This is the page for @host site. diff --git a/conf/routes b/conf/routes index 544234a37..00f80739a 100644 --- a/conf/routes +++ b/conf/routes @@ -1,4 +1,4 @@ -GET / controllers.HomeController.index() +GET / controllers.HomeController.index GET /for/*host controllers.HomeController.forHost(host) From c87f55dba188e40c1e341e361427086095e211de Mon Sep 17 00:00:00 2001 From: Will Sargent Date: Sun, 10 Jul 2016 18:18:00 -0700 Subject: [PATCH 11/53] Tweak subdomains --- app/controllers/HomeController.scala | 16 +++++++++------- app/views/forHost.scala.html | 3 --- app/views/index.scala.html | 24 ++---------------------- conf/routes | 2 -- 4 files changed, 11 insertions(+), 34 deletions(-) delete mode 100644 app/views/forHost.scala.html diff --git a/app/controllers/HomeController.scala b/app/controllers/HomeController.scala index 2de9c1874..a874b4410 100644 --- a/app/controllers/HomeController.scala +++ b/app/controllers/HomeController.scala @@ -6,15 +6,17 @@ import play.api.mvc._ class HomeController extends Controller { def index = Action { implicit request => - val filtered = request.host.split(":")(0).replace(".example.com", "") - - Redirect(routes.HomeController.forHost(filtered)) + Ok(views.html.index(subdomain)).withHeaders("Cache-Control" -> "no-store") } - def forHost(host: String) = Action { implicit request => - // prevent any browser caching... - Ok(views.html.forHost(host)).withHeaders("Cache-Control" -> "no-store") - } + private def subdomain(implicit r: Request[_]): String = { + // pull out the host part of the request URI + val s = r.host.split(":")(0).replace(".example.com", "") + // This is technically user input, so need to make sure this isn't + // anything fun like unicode characters or javascript. + // It will still go through DNS, so that's something. + s + } } diff --git a/app/views/forHost.scala.html b/app/views/forHost.scala.html deleted file mode 100644 index b5e62eebb..000000000 --- a/app/views/forHost.scala.html +++ /dev/null @@ -1,3 +0,0 @@ -@(host: String) - -This is the page for @host site. diff --git a/app/views/index.scala.html b/app/views/index.scala.html index 13f3232d6..55b9f23ed 100644 --- a/app/views/index.scala.html +++ b/app/views/index.scala.html @@ -1,23 +1,3 @@ -@() - - - -

Congratulations! You are reading the page! This is the "default" page.

- -

- The X.509 certificate the server sent you should be for "example.com". You can go to one.example.com or two.example.com to see ServerNameIndication at work. -

- -

- You should look for the HTTPS indicator in the browser toolbar. If you don't find it: -

- -
    -
  • Generate the certificates and install as described in the README
  • -
  • Set up the example.com domain in /etc/hosts as described in the README
  • -
  • Run "./play run"
  • -
- - - +@(subdomain: String) +This is the page for the @subdomain site. diff --git a/conf/routes b/conf/routes index 00f80739a..59b4b4567 100644 --- a/conf/routes +++ b/conf/routes @@ -1,5 +1,3 @@ GET / controllers.HomeController.index -GET /for/*host controllers.HomeController.forHost(host) - GET /assets/*file controllers.Assets.at(path="/public", file) From d04757d124f6ad273c5cf72ca20cc960ca199ac4 Mon Sep 17 00:00:00 2001 From: Will Sargent Date: Thu, 13 Oct 2016 12:03:31 -0700 Subject: [PATCH 12/53] Update subbuild with scalaversion (#12) --- build.sbt | 4 ++-- modules/one/build.sbt | 2 ++ modules/two/build.sbt | 2 ++ 3 files changed, 6 insertions(+), 2 deletions(-) create mode 100644 modules/one/build.sbt create mode 100644 modules/two/build.sbt diff --git a/build.sbt b/build.sbt index 776848f39..d8ea25a01 100644 --- a/build.sbt +++ b/build.sbt @@ -1,4 +1,4 @@ -name := """activator-play-tls-example""" +name := """play-tls-example""" version := "1.0.0" @@ -10,7 +10,7 @@ lazy val root = (project in file(".")).enablePlugins(PlayScala) .aggregate(one, two) .dependsOn(one, two) -scalaVersion in ThisBuild := "2.11.8" +scalaVersion := "2.11.8" libraryDependencies ++= Seq( ws, diff --git a/modules/one/build.sbt b/modules/one/build.sbt new file mode 100644 index 000000000..2a664ab50 --- /dev/null +++ b/modules/one/build.sbt @@ -0,0 +1,2 @@ + +scalaVersion := "2.11.8" \ No newline at end of file diff --git a/modules/two/build.sbt b/modules/two/build.sbt new file mode 100644 index 000000000..2a664ab50 --- /dev/null +++ b/modules/two/build.sbt @@ -0,0 +1,2 @@ + +scalaVersion := "2.11.8" \ No newline at end of file From 5f739895f63cab10cdcb5df31d430953cd45b64e Mon Sep 17 00:00:00 2001 From: Will Sargent Date: Thu, 13 Oct 2016 12:03:55 -0700 Subject: [PATCH 13/53] Updated with template-control on 2016-10-13T18:34:52.326Z (#11) File-Pattern: **/build.sbt If-Found-In-Line: "com.typesafe.play" %% "play-slick" Replace-Line-With: libraryDependencies += "com.typesafe.play" %% "play-slick" % "2.0.2" If-Found-In-Line: "com.typesafe.play" %% "play-slick-evolutions" Replace-Line-With: libraryDependencies += "com.typesafe.play" %% "play-slick-evolutions" % "2.0.2" If-Found-In-Line: scala-guice Replace-Line-With: libraryDependencies += "net.codingwell" %% "scala-guice" % "4.1.0" If-Found-In-Line: "com.softwaremill.macwire" %% "macros" Replace-Line-With: libraryDependencies += "com.softwaremill.macwire" %% "macros" % "2.2.2" % "provided" If-Found-In-Line: gatling-charts-highcharts Replace-Line-With: libraryDependencies += "io.gatling.highcharts" % "gatling-charts-highcharts" % "2.2.2" % Test If-Found-In-Line: scalaVersion Replace-Line-With: scalaVersion := "2.11.8" If-Found-In-Line: scalatestplus-play Replace-Line-With: libraryDependencies += "org.scalatestplus.play" %% "scalatestplus-play" % "1.5.1" % Test If-Found-In-Line: play-bootstrap Replace-Line-With: libraryDependencies += "com.adrianhurt" %% "play-bootstrap" % "1.0-P25-B3" If-Found-In-Line: gatling-test-framework Replace-Line-With: libraryDependencies += "io.gatling" % "gatling-test-framework" % "2.2.2" % Test If-Found-In-Line: "com.typesafe.play" %% "anorm" Replace-Line-With: libraryDependencies += "com.typesafe.play" %% "anorm" % "2.5.0" If-Found-In-Line: com.h2database Replace-Line-With: libraryDependencies += "com.h2database" % "h2" % "1.4.190" If-Found-In-Line: "com.softwaremill.macwire" %% "proxy" Replace-Line-With: libraryDependencies += "com.softwaremill.macwire" %% "proxy" % "2.2.2" If-Found-In-Line: "com.softwaremill.macwire" %% "util" Replace-Line-With: libraryDependencies += "com.softwaremill.macwire" %% "util" % "2.2.2" File-Pattern: **/build.properties If-Found-In-Line: sbt.version Replace-Line-With: sbt.version=0.13.12 File-Pattern: **/application.conf File-Pattern: **/plugins.sbt If-Found-In-Line: sbt-mocha Replace-Line-With: addSbtPlugin("com.typesafe.sbt" % "sbt-mocha" % "1.1.0") If-Found-In-Line: sbt-sassify Replace-Line-With: addSbtPlugin("org.irundaia.sbt" % "sbt-sassify" % "1.4.6") If-Found-In-Line: sbt-less Replace-Line-With: addSbtPlugin("com.typesafe.sbt" % "sbt-less" % "1.1.0") If-Found-In-Line: sbt-play-enhancer Replace-Line-With: addSbtPlugin("com.typesafe.sbt" % "sbt-play-enhancer" % "1.1.0") If-Found-In-Line: sbt-play-ebean Replace-Line-With: addSbtPlugin("com.typesafe.sbt" % "sbt-play-ebean" % "3.0.1") If-Found-In-Line: sbt-jshint Replace-Line-With: addSbtPlugin("com.typesafe.sbt" % "sbt-jshint" % "1.0.4") If-Found-In-Line: sbt-coffeescript Replace-Line-With: addSbtPlugin("com.typesafe.sbt" % "sbt-coffeescript" % "1.0.0") If-Found-In-Line: sbt-rjs Replace-Line-With: addSbtPlugin("com.typesafe.sbt" % "sbt-rjs" % "1.0.8") If-Found-In-Line: sbt-plugin Replace-Line-With: addSbtPlugin("com.typesafe.play" % "sbt-plugin" % "2.5.9") If-Found-In-Line: sbt-digest Replace-Line-With: addSbtPlugin("com.typesafe.sbt" % "sbt-digest" % "1.1.1") --- modules/one/project/build.properties | 2 +- modules/two/project/build.properties | 2 +- project/build.properties | 2 +- project/plugins.sbt | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/modules/one/project/build.properties b/modules/one/project/build.properties index e812e6272..07d874d65 100644 --- a/modules/one/project/build.properties +++ b/modules/one/project/build.properties @@ -1,4 +1,4 @@ #Activator-generated Properties #Fri Jul 08 22:56:54 PDT 2016 template.uuid=f57599cf-a4f5-4333-9ff1-55d48fd49891 -sbt.version=0.13.11 +sbt.version=0.13.12 diff --git a/modules/two/project/build.properties b/modules/two/project/build.properties index 43b8278c6..35c88bab7 100644 --- a/modules/two/project/build.properties +++ b/modules/two/project/build.properties @@ -1 +1 @@ -sbt.version=0.13.11 +sbt.version=0.13.12 diff --git a/project/build.properties b/project/build.properties index b8490b554..d071d1bc4 100644 --- a/project/build.properties +++ b/project/build.properties @@ -1,4 +1,4 @@ #Activator-generated Properties #Sun Jul 06 17:54:30 PDT 2014 template.uuid=af582966-096a-43df-a504-5ddae8d4ebf1 -sbt.version=0.13.11 +sbt.version=0.13.12 diff --git a/project/plugins.sbt b/project/plugins.sbt index 3af9547cc..10c911c0b 100644 --- a/project/plugins.sbt +++ b/project/plugins.sbt @@ -1,5 +1,5 @@ resolvers += "Typesafe repository" at "http://repo.typesafe.com/typesafe/releases/" // The Play plugin -addSbtPlugin("com.typesafe.play" % "sbt-plugin" % "2.5.3") +addSbtPlugin("com.typesafe.play" % "sbt-plugin" % "2.5.9") From a5570ee31bb4ff3246d9458f235dcb1caf88ae29 Mon Sep 17 00:00:00 2001 From: Will Sargent Date: Thu, 13 Oct 2016 12:26:35 -0700 Subject: [PATCH 14/53] Updated with template-control on 2016-10-13T19:11:13.731Z (#13) File-Pattern: **/build.sbt If-Found-In-Line: "com.typesafe.play" %% "play-slick" Replace-Line-With: libraryDependencies += "com.typesafe.play" %% "play-slick" % "2.0.2" If-Found-In-Line: "com.typesafe.play" %% "play-slick-evolutions" Replace-Line-With: libraryDependencies += "com.typesafe.play" %% "play-slick-evolutions" % "2.0.2" If-Found-In-Line: scala-guice Replace-Line-With: libraryDependencies += "net.codingwell" %% "scala-guice" % "4.1.0" If-Found-In-Line: "com.softwaremill.macwire" %% "macros" Replace-Line-With: libraryDependencies += "com.softwaremill.macwire" %% "macros" % "2.2.2" % "provided" If-Found-In-Line: gatling-charts-highcharts Replace-Line-With: libraryDependencies += "io.gatling.highcharts" % "gatling-charts-highcharts" % "2.2.2" % Test If-Found-In-Line: scalaVersion Replace-Line-With: scalaVersion := "2.11.8" If-Found-In-Line: scalatestplus-play Replace-Line-With: libraryDependencies += "org.scalatestplus.play" %% "scalatestplus-play" % "1.5.1" % Test If-Found-In-Line: play-bootstrap Replace-Line-With: libraryDependencies += "com.adrianhurt" %% "play-bootstrap" % "1.0-P25-B3" If-Found-In-Line: gatling-test-framework Replace-Line-With: libraryDependencies += "io.gatling" % "gatling-test-framework" % "2.2.2" % Test If-Found-In-Line: "com.typesafe.play" %% "anorm" Replace-Line-With: libraryDependencies += "com.typesafe.play" %% "anorm" % "2.5.0" If-Found-In-Line: com.h2database Replace-Line-With: libraryDependencies += "com.h2database" % "h2" % "1.4.190" If-Found-In-Line: "com.softwaremill.macwire" %% "proxy" Replace-Line-With: libraryDependencies += "com.softwaremill.macwire" %% "proxy" % "2.2.2" If-Found-In-Line: "com.softwaremill.macwire" %% "util" Replace-Line-With: libraryDependencies += "com.softwaremill.macwire" %% "util" % "2.2.2" File-Pattern: **/build.properties If-Found-In-Line: sbt.version Replace-Line-With: sbt.version=0.13.12 File-Pattern: **/application.conf File-Pattern: **/plugins.sbt If-Found-In-Line: sbt-mocha Replace-Line-With: addSbtPlugin("com.typesafe.sbt" % "sbt-mocha" % "1.1.0") If-Found-In-Line: sbt-sassify Replace-Line-With: addSbtPlugin("org.irundaia.sbt" % "sbt-sassify" % "1.4.6") If-Found-In-Line: sbt-less Replace-Line-With: addSbtPlugin("com.typesafe.sbt" % "sbt-less" % "1.1.0") If-Found-In-Line: sbt-play-enhancer Replace-Line-With: addSbtPlugin("com.typesafe.sbt" % "sbt-play-enhancer" % "1.1.0") If-Found-In-Line: sbt-play-ebean Replace-Line-With: addSbtPlugin("com.typesafe.sbt" % "sbt-play-ebean" % "3.0.1") If-Found-In-Line: sbt-jshint Replace-Line-With: addSbtPlugin("com.typesafe.sbt" % "sbt-jshint" % "1.0.4") If-Found-In-Line: sbt-coffeescript Replace-Line-With: addSbtPlugin("com.typesafe.sbt" % "sbt-coffeescript" % "1.0.0") If-Found-In-Line: sbt-rjs Replace-Line-With: addSbtPlugin("com.typesafe.sbt" % "sbt-rjs" % "1.0.8") If-Found-In-Line: sbt-plugin Replace-Line-With: addSbtPlugin("com.typesafe.play" % "sbt-plugin" % "2.5.9") If-Found-In-Line: sbt-digest Replace-Line-With: addSbtPlugin("com.typesafe.sbt" % "sbt-digest" % "1.1.1") --- modules/one/build.sbt | 2 +- modules/two/build.sbt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/modules/one/build.sbt b/modules/one/build.sbt index 2a664ab50..8dc16f157 100644 --- a/modules/one/build.sbt +++ b/modules/one/build.sbt @@ -1,2 +1,2 @@ -scalaVersion := "2.11.8" \ No newline at end of file +scalaVersion := "2.11.8" diff --git a/modules/two/build.sbt b/modules/two/build.sbt index 2a664ab50..8dc16f157 100644 --- a/modules/two/build.sbt +++ b/modules/two/build.sbt @@ -1,2 +1,2 @@ -scalaVersion := "2.11.8" \ No newline at end of file +scalaVersion := "2.11.8" From be9803bf904837abab1f7f86c39bc4c24900c56b Mon Sep 17 00:00:00 2001 From: Will Sargent Date: Wed, 9 Nov 2016 21:17:01 -0800 Subject: [PATCH 15/53] Updated with template-control on 2016-10-29T01:14:28.127Z (#14) **/build.properties: sbt.version=0.13.13 **/build.properties: sbt.version=0.13.13 **/build.properties: sbt.version=0.13.13 --- modules/one/project/build.properties | 2 +- modules/two/project/build.properties | 2 +- project/build.properties | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/modules/one/project/build.properties b/modules/one/project/build.properties index 07d874d65..e8ed0c8e4 100644 --- a/modules/one/project/build.properties +++ b/modules/one/project/build.properties @@ -1,4 +1,4 @@ #Activator-generated Properties #Fri Jul 08 22:56:54 PDT 2016 template.uuid=f57599cf-a4f5-4333-9ff1-55d48fd49891 -sbt.version=0.13.12 +sbt.version=0.13.13 diff --git a/modules/two/project/build.properties b/modules/two/project/build.properties index 35c88bab7..27e88aa11 100644 --- a/modules/two/project/build.properties +++ b/modules/two/project/build.properties @@ -1 +1 @@ -sbt.version=0.13.12 +sbt.version=0.13.13 diff --git a/project/build.properties b/project/build.properties index d071d1bc4..6bd264564 100644 --- a/project/build.properties +++ b/project/build.properties @@ -1,4 +1,4 @@ #Activator-generated Properties #Sun Jul 06 17:54:30 PDT 2014 template.uuid=af582966-096a-43df-a504-5ddae8d4ebf1 -sbt.version=0.13.12 +sbt.version=0.13.13 From 899af63b18f9c5aaad4c53f0efb1c54bbb968be1 Mon Sep 17 00:00:00 2001 From: Will Sargent Date: Wed, 9 Nov 2016 21:23:22 -0800 Subject: [PATCH 16/53] Updated with template-control on 2016-11-10T05:21:54.985Z (#15) /LICENSE: wrote /LICENSE --- LICENSE | 22 +++++----------------- 1 file changed, 5 insertions(+), 17 deletions(-) diff --git a/LICENSE b/LICENSE index 4d9259c30..b018ae2bc 100644 --- a/LICENSE +++ b/LICENSE @@ -1,19 +1,7 @@ -Copyright 2014 - 2016 Lightbend, Inc. +License +------- +Written in 2016 by Lightbend -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at +To the extent possible under law, the author(s) have dedicated all copyright and related and neighboring rights to this software to the public domain worldwide. This software is distributed without any warranty. -http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. - -The SNIKeyManager is Copyright (c) 2014 Graham Edgecombe under the following license: - -"Permission to use, copy, modify, and/or distribute this software for any -purpose with or without fee is hereby granted, provided that the above -copyright notice and this permission notice appear in all copies." +You should have received a copy of the CC0 Public Domain Dedication along with this software. If not, see . From afb2dedaad88b303409e865368eaa1c30ba9ecb9 Mon Sep 17 00:00:00 2001 From: Will Sargent Date: Fri, 18 Nov 2016 16:35:34 -0800 Subject: [PATCH 17/53] Updated with template-control on 2016-11-19T00:08:11.286Z (#16) /LICENSE: wrote /LICENSE **/plugins.sbt: addSbtPlugin("com.typesafe.play" % "sbt-plugin" % "2.5.10") --- project/plugins.sbt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/project/plugins.sbt b/project/plugins.sbt index 10c911c0b..069ef4530 100644 --- a/project/plugins.sbt +++ b/project/plugins.sbt @@ -1,5 +1,5 @@ resolvers += "Typesafe repository" at "http://repo.typesafe.com/typesafe/releases/" // The Play plugin -addSbtPlugin("com.typesafe.play" % "sbt-plugin" % "2.5.9") +addSbtPlugin("com.typesafe.play" % "sbt-plugin" % "2.5.10") From 7626ff9a6a3fc84114c538cdbe645da4f9f6366f Mon Sep 17 00:00:00 2001 From: Will Sargent Date: Fri, 17 Feb 2017 15:41:41 -0800 Subject: [PATCH 18/53] Updated with template-control on 2017-02-17T05:59:28.119Z (#18) /LICENSE: wrote /LICENSE **/build.sbt: scalaVersion := "2.12.1" **/build.sbt: scalaVersion := "2.12.1" **/build.sbt: scalaVersion := "2.12.1" **/plugins.sbt: addSbtPlugin("com.typesafe.play" % "sbt-plugin" % "2.6.0-M1") --- build.sbt | 2 +- modules/one/build.sbt | 2 +- modules/two/build.sbt | 2 +- project/plugins.sbt | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/build.sbt b/build.sbt index d8ea25a01..a089929d1 100644 --- a/build.sbt +++ b/build.sbt @@ -10,7 +10,7 @@ lazy val root = (project in file(".")).enablePlugins(PlayScala) .aggregate(one, two) .dependsOn(one, two) -scalaVersion := "2.11.8" +scalaVersion := "2.12.1" libraryDependencies ++= Seq( ws, diff --git a/modules/one/build.sbt b/modules/one/build.sbt index 8dc16f157..7a5e11a9b 100644 --- a/modules/one/build.sbt +++ b/modules/one/build.sbt @@ -1,2 +1,2 @@ -scalaVersion := "2.11.8" +scalaVersion := "2.12.1" diff --git a/modules/two/build.sbt b/modules/two/build.sbt index 8dc16f157..7a5e11a9b 100644 --- a/modules/two/build.sbt +++ b/modules/two/build.sbt @@ -1,2 +1,2 @@ -scalaVersion := "2.11.8" +scalaVersion := "2.12.1" diff --git a/project/plugins.sbt b/project/plugins.sbt index 069ef4530..1c0f2e2cd 100644 --- a/project/plugins.sbt +++ b/project/plugins.sbt @@ -1,5 +1,5 @@ resolvers += "Typesafe repository" at "http://repo.typesafe.com/typesafe/releases/" // The Play plugin -addSbtPlugin("com.typesafe.play" % "sbt-plugin" % "2.5.10") +addSbtPlugin("com.typesafe.play" % "sbt-plugin" % "2.6.0-M1") From d7649530a76c611e00d4de2ce2d56bac447e1bac Mon Sep 17 00:00:00 2001 From: Will Sargent Date: Tue, 28 Feb 2017 21:12:20 -0800 Subject: [PATCH 19/53] Update for 2.6.x (#19) * Update for 2.6.x * Add sample test * Add server spec --- .travis.yml | 15 +++++ activator.properties | 5 -- app/Main.scala | 17 ++--- app/controllers/HomeController.scala | 4 +- app/https/ClientMethods.scala | 24 ------- build.sbt | 6 +- conf/application.conf | 7 +- conf/ws.conf | 12 ---- .../one/app/controllers/HomeController.scala | 2 +- .../two/app/controllers/HomeController.scala | 2 +- play | 4 +- scripts/client.crt | 15 +++++ scripts/client.csr | 10 +++ scripts/client.jks | Bin 0 -> 2095 bytes scripts/client.p12 | Bin 0 -> 1101 bytes scripts/clientca.crt | 14 ++++ scripts/clientca.jks | Bin 0 -> 631 bytes scripts/example.com.crt | 16 +++++ scripts/example.com.csr | 10 +++ scripts/example.com.jks | Bin 0 -> 6174 bytes scripts/exampleca.crt | 14 ++++ scripts/exampleca.jks | Bin 0 -> 768 bytes scripts/exampletrust.jks | Bin 0 -> 633 bytes scripts/one.example.com.crt | 16 +++++ scripts/one.example.com.csr | 10 +++ scripts/password | 1 + scripts/two.example.com.crt | 16 +++++ scripts/two.example.com.csr | 10 +++ scripts/wildcard.example.com.crt | 15 +++++ scripts/wildcard.example.com.csr | 10 +++ .../GuiceOneHttpsServerPerTest.scala | 62 ++++++++++++++++++ test/integration/HowsMySSLSpec.scala | 44 ------------- test/integration/ServerSpec.scala | 36 ++++++++++ 33 files changed, 287 insertions(+), 110 deletions(-) create mode 100644 .travis.yml delete mode 100644 activator.properties delete mode 100644 app/https/ClientMethods.scala create mode 100644 scripts/client.crt create mode 100644 scripts/client.csr create mode 100644 scripts/client.jks create mode 100644 scripts/client.p12 create mode 100644 scripts/clientca.crt create mode 100644 scripts/clientca.jks create mode 100644 scripts/example.com.crt create mode 100644 scripts/example.com.csr create mode 100644 scripts/example.com.jks create mode 100644 scripts/exampleca.crt create mode 100644 scripts/exampleca.jks create mode 100644 scripts/exampletrust.jks create mode 100644 scripts/one.example.com.crt create mode 100644 scripts/one.example.com.csr create mode 100644 scripts/password create mode 100644 scripts/two.example.com.crt create mode 100644 scripts/two.example.com.csr create mode 100644 scripts/wildcard.example.com.crt create mode 100644 scripts/wildcard.example.com.csr create mode 100644 test/integration/GuiceOneHttpsServerPerTest.scala delete mode 100644 test/integration/HowsMySSLSpec.scala create mode 100644 test/integration/ServerSpec.scala diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 000000000..74486cdfd --- /dev/null +++ b/.travis.yml @@ -0,0 +1,15 @@ +language: scala +scala: +- 2.12.1 +jdk: +- oraclejdk8 +cache: + directories: + - "$HOME/.ivy2/cache" +before_cache: +- rm -rf $HOME/.ivy2/cache/com.typesafe.play/* +- rm -rf $HOME/.ivy2/cache/scala_*/sbt_*/com.typesafe.play/* +- find $HOME/.ivy2/cache -name "ivydata-*.properties" -print0 | xargs -n10 -0 rm +notifications: + slack: + secure: K6HWTI6zJpQfxS7sH5ZQ1jEK5TkkUl5GtcGinNecHMBqvfS4IXAnU23lz/kLqCqMVPIFaRx1g6UwgJgMvR4XWeIhpzLOzAnOOcmv+kQzv7A8vEJBM20z1HNzDcxzvuNNO2BHn8EjXh5VD65vXMcA+lKzUxASey/Rs+CBReQWE7M= \ No newline at end of file diff --git a/activator.properties b/activator.properties deleted file mode 100644 index eecf7afdf..000000000 --- a/activator.properties +++ /dev/null @@ -1,5 +0,0 @@ -name=play-tls-example -title=Play Framework SSL/TLS Example -description=A Play application using HTTPS and WS with optional client authentication -tags=playframework,scala,tls,https,ssl,playws -authorTwitter=@will_sargent diff --git a/app/Main.scala b/app/Main.scala index 4e30109bf..76a835f4d 100644 --- a/app/Main.scala +++ b/app/Main.scala @@ -1,21 +1,17 @@ import akka.actor.ActorSystem import akka.stream.ActorMaterializer -import https.ClientMethods -import play.api.{Environment, Mode} import play.api.libs.ws._ -import play.api.libs.ws.ning._ -import play.api.libs.ws.ssl.debug.DebugConfiguration import com.typesafe.config.ConfigFactory -import play.api.test.WsTestClient +import play.api.libs.ws.ahc.{AhcWSClient, AhcWSClientConfigFactory} import scala.util.{Failure, Success} /** * Connects to example.com with a WS client running from Main. * - * Please see http://www.playframework.com/documentation/2.3.x/WsSSL for more details. + * Please see http://www.playframework.com/documentation/latest/WsSSL for more details. */ -object Main extends https.ClientMethods { +object Main { private val logger = org.slf4j.LoggerFactory.getLogger("application") @@ -30,15 +26,12 @@ object Main extends https.ClientMethods { def main(args: Array[String]) { import scala.concurrent.ExecutionContext.Implicits.global - val config = play.api.Configuration(ConfigFactory.load("ws.conf")) - val environment = play.api.Environment.simple(new java.io.File("./conf"), Mode.Dev) - + val config = AhcWSClientConfigFactory.forConfig(ConfigFactory.load("ws.conf"), getClass.getClassLoader) val name = "testing" val system = ActorSystem(name) implicit val materializer = ActorMaterializer(namePrefix = Some(name))(system) - val client = createClient(config, environment) - + val client = AhcWSClient(config) val futureResponse = client.url("https://one.example.com:9443").get() futureResponse.onComplete { case Success(response) => diff --git a/app/controllers/HomeController.scala b/app/controllers/HomeController.scala index a874b4410..8440f71c5 100644 --- a/app/controllers/HomeController.scala +++ b/app/controllers/HomeController.scala @@ -1,9 +1,11 @@ package controllers +import javax.inject.Inject + import play.api._ import play.api.mvc._ -class HomeController extends Controller { +class HomeController @Inject()(cc: ControllerComponents) extends AbstractController(cc) { def index = Action { implicit request => Ok(views.html.index(subdomain)).withHeaders("Cache-Control" -> "no-store") diff --git a/app/https/ClientMethods.scala b/app/https/ClientMethods.scala deleted file mode 100644 index 8e6423166..000000000 --- a/app/https/ClientMethods.scala +++ /dev/null @@ -1,24 +0,0 @@ -package https - -import akka.stream.Materializer -import org.asynchttpclient.AsyncHttpClientConfig -import play.api.Environment -import play.api.libs.ws.WSConfigParser -import play.api.libs.ws.ahc._ - -/** - * - */ -trait ClientMethods { - - def createClient(configuration: play.api.Configuration, environment: Environment)(implicit mat: Materializer) = { - val parser = new WSConfigParser(configuration, environment) - val clientConfig = parser.parse() - val ahcParser = new AhcWSClientConfigParser(clientConfig, configuration, environment) - val ahcConfig = ahcParser.parse() - val builder = new AhcConfigBuilder(ahcConfig) - val asyncHttpClientConfig: AsyncHttpClientConfig = builder.build() - val client = new AhcWSClient(asyncHttpClientConfig)(mat) - client - } -} diff --git a/build.sbt b/build.sbt index a089929d1..c35f8ee53 100644 --- a/build.sbt +++ b/build.sbt @@ -12,10 +12,8 @@ lazy val root = (project in file(".")).enablePlugins(PlayScala) scalaVersion := "2.12.1" -libraryDependencies ++= Seq( - ws, - specs2 % Test -) +libraryDependencies += ws +libraryDependencies += "org.scalatestplus.play" %% "scalatestplus-play" % "2.0.0-M2" % Test fork in run := true diff --git a/conf/application.conf b/conf/application.conf index 84eb9de06..eb19dfec5 100644 --- a/conf/application.conf +++ b/conf/application.conf @@ -1,8 +1,7 @@ # See http://www.playframework.com/documentation/latest/ApplicationSecret for more details. -play.crypto.secret="changeme" -play.crypto.secret=${?APPLICATION_SECRET} - -play.i18n.langs = ["en"] +play.http.secret.key="changeme" +play.http.secret.key=${?APPLICATION_SECRET} play.http.requestHandler = "router.MultiSiteRequestHandler" +play.server.https.engineProvider=https.CustomSSLEngineProvider \ No newline at end of file diff --git a/conf/ws.conf b/conf/ws.conf index c1cd73f49..f82e8dd57 100644 --- a/conf/ws.conf +++ b/conf/ws.conf @@ -4,18 +4,6 @@ play.ws.ssl { handshake = true } - protocol = "TLSv1.2" - - enabledProtocols = [ "TLSv1.2" ] - - enabledCiphers = [ - "TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384" - ] - - ws.ssl.disabledSignatureAlgorithms = "MD2, MD4, MD5, SHA1, RSA" - - ws.ssl.disabledKeyAlgorithms = "EC keySize < 384" - keyManager = { stores = [ // Note: must be run from ./play, which loads the KEY_PASSWORD environment variable. diff --git a/modules/one/app/controllers/HomeController.scala b/modules/one/app/controllers/HomeController.scala index 8531ab4ee..687c481bd 100644 --- a/modules/one/app/controllers/HomeController.scala +++ b/modules/one/app/controllers/HomeController.scala @@ -9,7 +9,7 @@ import play.api.mvc._ * application's home page. */ @Singleton -class HomeController @Inject() extends Controller { +class HomeController @Inject()(cc: ControllerComponents) extends AbstractController(cc) { /** * Create an Action to render an HTML page with a welcome message. diff --git a/modules/two/app/controllers/HomeController.scala b/modules/two/app/controllers/HomeController.scala index efa4a2499..b9675907e 100644 --- a/modules/two/app/controllers/HomeController.scala +++ b/modules/two/app/controllers/HomeController.scala @@ -5,7 +5,7 @@ import play.api._ import play.api.mvc._ @Singleton -class HomeController @Inject() extends Controller { +class HomeController @Inject()(cc: ControllerComponents) extends AbstractController(cc) { def index = Action { Ok(views.html.two.index()) diff --git a/play b/play index 5295b4bbd..c7a5acf11 100755 --- a/play +++ b/play @@ -1,6 +1,6 @@ #!/bin/bash -ACTIVATOR=activator +SBT=sbt # Export the keystore password for use in ws.conf export KEY_PASSWORD=`cat scripts/password` @@ -59,4 +59,4 @@ JVM_OPTIONS="$JVM_OPTIONS -Dsun.security.ssl.allowLegacyHelloMessages=false" #JVM_OPTIONS="$JVM_OPTIONS -Djava.security.debug=certpath:x509:ocsp" # Run Play -$ACTIVATOR $JVM_OPTIONS $*; +$SBT $JVM_OPTIONS -Dkey.password=$KEY_PASSWORD $*; diff --git a/scripts/client.crt b/scripts/client.crt new file mode 100644 index 000000000..c6709ed8e --- /dev/null +++ b/scripts/client.crt @@ -0,0 +1,15 @@ +-----BEGIN CERTIFICATE----- +MIICRjCCAemgAwIBAgIEUuaIDjAMBggqhkjOPQQDAgUAMH0xCzAJBgNVBAYTAlVT +MRMwEQYDVQQIEwpDYWxpZm9ybmlhMRYwFAYDVQQHEw1TYW4gRnJhbmNpc2NvMRgw +FgYDVQQKEw9FeGFtcGxlIENvbXBhbnkxFDASBgNVBAsTC0V4YW1wbGUgT3JnMREw +DwYDVQQDEwhjbGllbnRjYTAeFw0xNzAyMjgyMjQzNTJaFw0xNzA1MjkyMjQzNTJa +MHsxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpDYWxpZm9ybmlhMRYwFAYDVQQHEw1T +YW4gRnJhbmNpc2NvMRgwFgYDVQQKEw9FeGFtcGxlIENvbXBhbnkxFDASBgNVBAsT +C0V4YW1wbGUgT3JnMQ8wDQYDVQQDEwZjbGllbnQwWTATBgcqhkjOPQIBBggqhkjO +PQMBBwNCAATU4DEAlfPWUt8ZxWkr7gX2dfWZ2bVYZr7xpSnuMbMzlrrwZ33hgn0s +y3Af7Zz3MchcB+I3+0JMSMkDF8K+p8Dgo1cwVTAfBgNVHSMEGDAWgBR8rEH7EEB+ +/ANuFJxkw10sgb2zAzATBgNVHSUEDDAKBggrBgEFBQcDAjAdBgNVHQ4EFgQUykKg +340VBk9CA8IKVKuoPaR5wl4wDAYIKoZIzj0EAwIFAANJADBGAiEApuSZvFIFl5Hb +N02c2HCtCvCVz81rvydpzgTMFH1O39wCIQCtwBwD9eFmyddU3I+QThgZwLMtn5lD +KiAp8qa7GLyQXQ== +-----END CERTIFICATE----- diff --git a/scripts/client.csr b/scripts/client.csr new file mode 100644 index 000000000..cdb05c5e7 --- /dev/null +++ b/scripts/client.csr @@ -0,0 +1,10 @@ +-----BEGIN NEW CERTIFICATE REQUEST----- +MIIBajCCAQ0CAQAwezELMAkGA1UEBhMCVVMxEzARBgNVBAgTCkNhbGlmb3JuaWEx +FjAUBgNVBAcTDVNhbiBGcmFuY2lzY28xGDAWBgNVBAoTD0V4YW1wbGUgQ29tcGFu +eTEUMBIGA1UECxMLRXhhbXBsZSBPcmcxDzANBgNVBAMTBmNsaWVudDBZMBMGByqG +SM49AgEGCCqGSM49AwEHA0IABNTgMQCV89ZS3xnFaSvuBfZ19ZnZtVhmvvGlKe4x +szOWuvBnfeGCfSzLcB/tnPcxyFwH4jf7QkxIyQMXwr6nwOCgMDAuBgkqhkiG9w0B +CQ4xITAfMB0GA1UdDgQWBBTKQqDfjRUGT0IDwgpUq6g9pHnCXjAMBggqhkjOPQQD +AgUAA0kAMEYCIQCpWSYpcJB6CGHMCxUCFCUQwx7cUNVETIzCpcndM9TRBAIhAJzc +mjywUYOq2qw0QuQCSQ3eBQE5IRuFW48ULk6eosiB +-----END NEW CERTIFICATE REQUEST----- diff --git a/scripts/client.jks b/scripts/client.jks new file mode 100644 index 0000000000000000000000000000000000000000..1222e2eab33a193028eacc1b27b9da0d317aaf65 GIT binary patch literal 2095 zcmezO_TO6u1_mZ5W@O+<&dE&8D@jgdU|@`Dd-B8^C{u4xYrx0GrOn33!l=b0$jHdb zz>+O>vO}qDqxwU;yTOKq?i|9!JlT0!R=q5a1xxn_{`x-EUTV^@nDpuAg_xE-6L9bl zZs-hq8ECxpkmmb?^BeB`IQJ`Q%C)y?6RLU&4%S#M7Te<2`gG2^T6gC+Z^L@kHgGRK zGP&Y-`SYYjB5hBAPGDqUjnFeSumn2Q%%F+M$e@Yw+5%=KMkXc}zjQ-810FUGtu~Ky zwk*s{tPBRVhTI06Y|No7Y{E>T!G^*Hf*=luFqd;;PG(wuQC?=Ep_qXPNRVBaH#jj* z!L2AUFFCU~Ip0viKnx_#CCu+yk(gVMld9mHpIeZaS7|6>AOw=(7UqV@_!p%c3L5Z( zM45%*A!i^b&TD9HU}R)rWMpD&Y7_bK{Zgm1mvocbpzmV0(vz0d>q^jw+DAki6D{9a4G$T6t@(jFk`yOQ^&)%~x(Z*N@v zU8PJc-|3}&2bX#7VkZL!aB#>9Gcx{XVKra|Qoy9c94gBX5&*^y6N`Z?h|k9&#v)R) z#__j+L){7iw;(7{^3lUG#_IpV?;_9FWcbO}rfXRLnEbvgs9U-jp#*5fzeg=9Twv>M<}*;gJIGEDt^E$F`F(M;`ktlvt%&b+xbB5mKtrJC;yHycme z^&!3XVNqw;bG{p%h+%(Z{@cmN<0P~Ap?%8_JXjoV5NaR~O1R1_z!IVXd(ssK zDNtqMG2mk30G5`ltnAE8NXh+_(}MfGqHO+7%!jx_R67SKqYGr$S{9>n0E4d$esQPeiD)g zHtWux>8z!o`Dxj1i9Hiy5s7NFz@)G|$DOQ(bAkEN|3$#bJ!f{Bec~2N^10zX^`wI= E0HuU_6aWAK literal 0 HcmV?d00001 diff --git a/scripts/client.p12 b/scripts/client.p12 new file mode 100644 index 0000000000000000000000000000000000000000..5e1b28d4764d2dd64170fce4df1b2eb56ff354b2 GIT binary patch literal 1101 zcmXqLV)0~RWHxAGVP@mhYV&CO&dbQoxS)yo3riF82ZJW&HwKN5kYyULuryvYXgp`o zc$$qHs)2`#k!eAhL5YC|8y8FnXr>g4$k7QmO+KZF=yP_hkIfX_s3OSq$&ZPNg@MJx zAroZ1CV+N*Urv};zc%) z7v(pa-H=%L=4kwjY?1#REfeibdPP89Y-nQI&{p;NOWb{n8Siv7+s>U#-`aJ)@}^&p z!xfhb<3)V07tYIZZ831)xWC-g>dnciid?}j*O>5itgq3&@uBRc>4{m6>Jp)o-JS=n zkb3&$*`oQjX4=hF%InSw@8vq#GRxg;!}d*UqRReH>=wQt&-&qVY?Z{_C*G4@WRx`> zO;X7A%wbGujK1bqGRt~)iFjX@S|Lr;X%i=hw!hC={%{w{XRC@3R$ODi67dYv1{I^PBej*Y|^} zrH}t~J$K;by(m6|U20F6wtZ7pYFhh6eY2X$^sN$t|I^w&cNDW|+=;G{G>$ubvCC-v z$D|F5n59xp-j;{5Wrjv_Y>jUFYps}YApC=vVe_uom%KkxiZc#v`m}Dxk|}IEq&bR~ zUd$=6_E=+F%CzZy1N*$)ZF$j0)g~^q`6ZwB`{=%?ROT&>p|KirrFH-Rzcu%Drnvd6y3Tig{itvVOXvZ?%Rn>E4m^P>H0_uuOKcB=T9n%{)m>|2<2 zi{DvnwjiLCxpIYR&+261u#3wl6g|0Ld+Tq?=I;0ZCSNscQ4P(zK)mcGv8IbY5iamQTN;EMB3zMM?M%|X1D77vY%OClg{Gf z7b7e0=B#ax`@Q0r&-CU?rbqL38O-@v;klaYLgUhkshZ)QapxrZeYRcOv9msT;*V2i zx980Lb^ObXpr{U){>L8owz$;?Gci9gzbhVPU~8agz{$p{&Bx3n#mc}U(h)N8QCG0f s!)Z;GM-JNCAG;&6$CX87huFS-C10+`@I6t~UA0{GNjS^Kx1b~s0FuDwfB*mh literal 0 HcmV?d00001 diff --git a/scripts/clientca.crt b/scripts/clientca.crt new file mode 100644 index 000000000..ecef6fc4b --- /dev/null +++ b/scripts/clientca.crt @@ -0,0 +1,14 @@ +-----BEGIN CERTIFICATE----- +MIICMjCCAdagAwIBAgIETmcxPjAMBggqhkjOPQQDAgUAMH0xCzAJBgNVBAYTAlVT +MRMwEQYDVQQIEwpDYWxpZm9ybmlhMRYwFAYDVQQHEw1TYW4gRnJhbmNpc2NvMRgw +FgYDVQQKEw9FeGFtcGxlIENvbXBhbnkxFDASBgNVBAsTC0V4YW1wbGUgT3JnMREw +DwYDVQQDEwhjbGllbnRjYTAeFw0xNzAyMjgyMjQzNTJaFw0xODAyMjgyMjQzNTJa +MH0xCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpDYWxpZm9ybmlhMRYwFAYDVQQHEw1T +YW4gRnJhbmNpc2NvMRgwFgYDVQQKEw9FeGFtcGxlIENvbXBhbnkxFDASBgNVBAsT +C0V4YW1wbGUgT3JnMREwDwYDVQQDEwhjbGllbnRjYTBZMBMGByqGSM49AgEGCCqG +SM49AwEHA0IABIJbZqvtzgIT2umzZfxiXQubhn8S4EdnbRxpUhWY1E7rGehsMH/0 +h1AZTakN2Trf9fvbsav3JHYWb0LpP4gKN22jQjBAMA8GA1UdEwEB/wQFMAMBAf8w +DgYDVR0PAQH/BAQDAgIEMB0GA1UdDgQWBBR8rEH7EEB+/ANuFJxkw10sgb2zAzAM +BggqhkjOPQQDAgUAA0gAMEUCIQDpmKZDBpR20016RAbrV6sHJdnEZqlD+SSqozsq +OLpNZgIgD0YoaJX/6nXlxPn+kV0NU2FBt/mAhe6LRnIyc05zo60= +-----END CERTIFICATE----- diff --git a/scripts/clientca.jks b/scripts/clientca.jks new file mode 100644 index 0000000000000000000000000000000000000000..4beaa2b3cd530af182531a0a16a718133cbdb37b GIT binary patch literal 631 zcmezO_TO6u1_mY|W(3n5$vK&+c_qn-K!K>XCokL?SR?dI4J?6b%nX{Cj0~C>uPtC^ zVq{`s@k=+fGvHz4&}#EIXUoFO#L8e$YshWD$;KSY!Y0fV8f++RAPC}c2y;0n=47Vj z7v*Ip8j2Z+fCSlvd4m)46x@mu^O7@*lk*KF48%aV+P-r{~IK28qtN;`dteMUFxJ zm-YZj-<7;Kt?qyQeS72T?i zNB|f+Oe_YnAU+?97>h{F8pq!P4t0N+^F-#P9FEm#+`E|>H7c1s7z|vQ6d7L5Smw+& zrR=hAl?&VJ@YU?9H;<&PbpENbYO%GJ#V+48CIx;sjf|=PUzI*R^7G%sSYV_&ZvWZP k`mWop$f($_c=6h2|GOTDE!)3GBli#M%SdkHcR$!m0bEqJTL1t6 literal 0 HcmV?d00001 diff --git a/scripts/example.com.crt b/scripts/example.com.crt new file mode 100644 index 000000000..3be4a6ca4 --- /dev/null +++ b/scripts/example.com.crt @@ -0,0 +1,16 @@ +-----BEGIN CERTIFICATE----- +MIICdDCCAhigAwIBAgIEHb7/hTAMBggqhkjOPQQDAgUAMH4xCzAJBgNVBAYTAlVT +MRMwEQYDVQQIEwpDYWxpZm9ybmlhMRYwFAYDVQQHEw1TYW4gRnJhbmNpc2NvMRgw +FgYDVQQKEw9FeGFtcGxlIENvbXBhbnkxFDASBgNVBAsTC0V4YW1wbGUgT3JnMRIw +EAYDVQQDEwlleGFtcGxlQ0EwHhcNMTcwMjI4MjI0MzUzWhcNMTcwNTI5MjI0MzUz +WjCBgDELMAkGA1UEBhMCVVMxEzARBgNVBAgTCkNhbGlmb3JuaWExFjAUBgNVBAcT +DVNhbiBGcmFuY2lzY28xGDAWBgNVBAoTD0V4YW1wbGUgQ29tcGFueTEUMBIGA1UE +CxMLRXhhbXBsZSBPcmcxFDASBgNVBAMTC2V4YW1wbGUuY29tMFkwEwYHKoZIzj0C +AQYIKoZIzj0DAQcDQgAEgkS809VXcPuYK/vyigcJk9MChmHUs4L20ca0p1Ag4yAG +T7Qq4ifAmo9QI4UWujst76LUMZaoisc6j5OKHCEmNqN/MH0wHwYDVR0jBBgwFoAU +n5szvZjetSdYVfTLHovZZHH6VSswEwYDVR0lBAwwCgYIKwYBBQUHAwEwDgYDVR0P +AQH/BAQDAgWgMBYGA1UdEQQPMA2CC2V4YW1wbGUuY29tMB0GA1UdDgQWBBSK1EjW +tdm2w5vsKaNx1WcLEAdUHTAMBggqhkjOPQQDAgUAA0gAMEUCIGEPSLZsSKnHcUZJ +Rev0ygGm0sqqUGSna4TxATI+gjNaAiEAjKXwPKtaAZiULhqEzHSd770d/9kLMXqx +zAhzew2qmHk= +-----END CERTIFICATE----- diff --git a/scripts/example.com.csr b/scripts/example.com.csr new file mode 100644 index 000000000..926047fa5 --- /dev/null +++ b/scripts/example.com.csr @@ -0,0 +1,10 @@ +-----BEGIN NEW CERTIFICATE REQUEST----- +MIIBbzCCARMCAQAwgYAxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpDYWxpZm9ybmlh +MRYwFAYDVQQHEw1TYW4gRnJhbmNpc2NvMRgwFgYDVQQKEw9FeGFtcGxlIENvbXBh +bnkxFDASBgNVBAsTC0V4YW1wbGUgT3JnMRQwEgYDVQQDEwtleGFtcGxlLmNvbTBZ +MBMGByqGSM49AgEGCCqGSM49AwEHA0IABIJEvNPVV3D7mCv78ooHCZPTAoZh1LOC +9tHGtKdQIOMgBk+0KuInwJqPUCOFFro7Le+i1DGWqIrHOo+TihwhJjagMDAuBgkq +hkiG9w0BCQ4xITAfMB0GA1UdDgQWBBSK1EjWtdm2w5vsKaNx1WcLEAdUHTAMBggq +hkjOPQQDAgUAA0gAMEUCIAEqF/xfWjrdPkAhVkKfI9UNJxQ1F6aKT5vpbbm7Sv1P +AiEAwLL6Vo5dWvy3wXyKflVE4T5uHGSBfenCTp78iQmm2xI= +-----END NEW CERTIFICATE REQUEST----- diff --git a/scripts/example.com.jks b/scripts/example.com.jks new file mode 100644 index 0000000000000000000000000000000000000000..f9832101e4a0b9ae94020abe31f9254870065bf9 GIT binary patch literal 6174 zcmezO_TO6u1_mY|W(8tK29fg2oRs9mq7=Qa!#dDz;UaWcc#{y?tIG|dCF$v87{?7 z|GXWz1w$&Ye=l3JrtAsBjw^e9{Jwa9q28soP@%s`N|$B*rf)7w6kVbHXR@Vk)1LOw z&-Q!Yacuc+=o?XUQP!zR`KPRf%I)69nPA7VM(CLuSOT4$Y|z9M55!Chn3))vm{^MR zD|ife*f_M>JkHs&Ff*|-7}ObZ8*s8QhqABjhgSS2c|S*gC@os(A4JJaUmPk+Ci4u41uZ5#Kged&=j2745J3zeYg{v zC9iyZe!%Y&=bHXl=iRBRt-K;>Un?!tdm%nFhtFgErYiURJwF6K7@fI!XnCZ>g!b>o z!TPN|m*h@nTd1G>S@UGElYxT)KPZU^gOUuZ0W*+7O+!p9NNEUbIz%ZtnB5r+T$mI* zxfX>@+tPczQSEu-$!ls)4nB&X_0aU6)Xy6&I^HYp-e*#yyYggN? z?fdQ@>3+$7e%t$s@>gaISHT4Bi*KF0qa#@+WOA5g#iJTk#W@=v?-O}rZaDRzCV%<; zqJDqheGiN$tX=qg=Z3}NO@|+ESQl#izV|@*)yn>dOWam#25&|!Pb+{ayab3PpebB- z-~ZM@ox+V#%TwbhgT@9rmZ#8afLRzhcJY*^O)h&bUkxw#JwyBVr!IER$(Nbh60dA- z`gZZymgNBoj}_Sbw`e_5KQOC5K)F?Hm$mNuMOO@`t>`*#)jzpQMp4adF{t{bPH76N z*<=M-_zifQP#ljaWxK9;T-$nc+u_-7G#3|MP3IP150OPp49p%32ChsBiTobhay(WZ zFLd*Cef{MWC?$4KKl+g?CZI;eD&!i%l)VA zsrmimrpd~EZZj^hJv#q)O5>xqrEZ*`-4o6>?EW<;=UR?`BL`#Sl|{4UPz%~-U?E!% z#7fYDHu}&(bJV;w;8ith!_@?}pfv#&v@LWjXrV1}W?}Rg##7h^PBVU}`pVOA!er+# zriVv=DlITNV4?DIJHz9gfV=Nk`YqAeU~oy>^6*}P=YcAda;MdA(3^8D&E@Ku#(Q6s z3ol<@+}L8!*hr<~Rti$w0=pkg7+ydWxqL!`v+v8OfBNFRrz`gFteR~isd@A8MD-2v9UnqjKd+pxbQ@UaE=qAp5J>J?A{vp-ldyN+ zp_Hi|t2S#NiFqJYucvRN>oZ#Bj+VI;H*A?0V13=>L`Z4->i1~E8ckRfCoDz={*v;1 z%*y=zAzYRD|Fst~?Cm!n{Z{YI?7A_2w#y%%d#CQs`!wy#0kaz~#m;MJzFU@2TI|%; z?(XB(8gb~zbfpyS=esAp7MSpS)sZGvDU)C8SW`~ki&oRQ`Q6NByQ=(oiOIjB`jg*W zTetn0_rZjf7qYYF7w_+8>_V-~n}8L09a3dp6Q3J~T56A0=E%cjh{_x-hVfM9O@d4Q za^;_&VY9kMa=($mOpn7Cr-s$!on9AnzPjzfZ}X3)s&>wLH#BCc?>n$$uDM|EE-$?W zSG$b#c=@i#*gp@WS!Isy1w>^&af)9_bhyCYsi$Ahnz54eVaby_KT(qfr2nMI(6Bx- zJoBdf>x#2)1vgtr39mhzH=QfUvhCJ9X72V0b6S}cisDY3W#(GEmZPlrb(#I)TTD$S vTebdf^%R-1E-ieMF#BkcJ6hyYR^-0;lJ)atz%=>RYF6pg1L~d=3XD?#oQh7> literal 0 HcmV?d00001 diff --git a/scripts/exampleca.crt b/scripts/exampleca.crt new file mode 100644 index 000000000..1bc748765 --- /dev/null +++ b/scripts/exampleca.crt @@ -0,0 +1,14 @@ +-----BEGIN CERTIFICATE----- +MIICMzCCAdigAwIBAgIETYjQazAMBggqhkjOPQQDAgUAMH4xCzAJBgNVBAYTAlVT +MRMwEQYDVQQIEwpDYWxpZm9ybmlhMRYwFAYDVQQHEw1TYW4gRnJhbmNpc2NvMRgw +FgYDVQQKEw9FeGFtcGxlIENvbXBhbnkxFDASBgNVBAsTC0V4YW1wbGUgT3JnMRIw +EAYDVQQDEwlleGFtcGxlQ0EwHhcNMTcwMjI4MjI0MzUxWhcNNDQwNzE1MjI0MzUx +WjB+MQswCQYDVQQGEwJVUzETMBEGA1UECBMKQ2FsaWZvcm5pYTEWMBQGA1UEBxMN +U2FuIEZyYW5jaXNjbzEYMBYGA1UEChMPRXhhbXBsZSBDb21wYW55MRQwEgYDVQQL +EwtFeGFtcGxlIE9yZzESMBAGA1UEAxMJZXhhbXBsZUNBMFkwEwYHKoZIzj0CAQYI +KoZIzj0DAQcDQgAEOQ0fX29Q+8jOgvw7btx+fXnUGT99GxKN0F9VbA5Ir7J6R2+8 ++BDwMszZwqdZGJCH9zNTL4WM0h7Jazgnyfl85KNCMEAwDwYDVR0TAQH/BAUwAwEB +/zAOBgNVHQ8BAf8EBAMCAgQwHQYDVR0OBBYEFJ+bM72Y3rUnWFX0yx6L2WRx+lUr +MAwGCCqGSM49BAMCBQADRwAwRAIgSQqiVpa0jdeBJueBydYm5MHiX5rhNf4a+diE +LEuo3d8CID4mqFvs9rRAMYAMjztFPbWHvt/Ei+kPz7bveHfqNgDV +-----END CERTIFICATE----- diff --git a/scripts/exampleca.jks b/scripts/exampleca.jks new file mode 100644 index 0000000000000000000000000000000000000000..042fa6fd54597baa8046319390075662c1dc9641 GIT binary patch literal 768 zcmezO_TO6u1_mY|W&~r-)QZI1f}GUkM4(7i+mpu@K;e3WS_3{dE^RhO7Dg>5K}JSa z2A1rJ#lj9(_wk1w=T`Y5ao}gAW=8T2-dxT(jph%WS(>WnEV>SOC;z8+7nl&^jAy27H@^mk6L=FTOGyYD|+{x)as=EeV8k{>#3F>+_- z@9f?1sfZ;*G{*J<*k!B{dZq@JK)0G3G%*<)G%?;-z|6$R#Khv;aUt7)hmAw4&EuRc z3o{cdgF&4kw*e;`b0`a&FjHu-p|F7$mn?k~^7gp?>mb&6CAW1`Y=NzyOgIW@P-&!fL<_q=1PBD8LUA0LBj!i-9bN&&MLh zA~Jur@!lEtwyH;jemO1IeKV!-SEx2>WHP%m7`QMgcycWYo3^F*dZXI&#*^37o*aA> zKkK3CKdGNLT6DZu+`Z4FV5hbs`pvg34u%ap{noCwTif^DKhph@|NOT173HtY7_JJ} Y^lBUpd38APeAfF{x(@|>|73>%0FavX-T(jq literal 0 HcmV?d00001 diff --git a/scripts/exampletrust.jks b/scripts/exampletrust.jks new file mode 100644 index 0000000000000000000000000000000000000000..daea7d39ffcf68cbf2280e3f96d42a304af026e7 GIT binary patch literal 633 zcmezO_TO6u1_mY|W(3omsTGO21v#n7i9nI4wkMx_7+53pObsl7ip&j~n2ZgY7;h|K zW@2PwV)5;`kZr)j#-Y{ban6>7nTeIbpw5unfRl|ml!Z;0DKywn*gz1(;SlC>PRz+n z%P-2yOf(cT5CI9Y3-bmi<|()pCFUh(7ANN$N*IWN#JPm|T_J8zaL&&yNX)A=6fqD2 z$#4sE!({x6(hY?S1VEz9!Z0^GI~vG|^BS5P7#Ud@8JQTH8b*opnwS`v8=6A71Ma>^ z17S9HaCk8>LIaMOk)7FzfyI(nK0ZI-_la{&f2{NF)YVpAk+iRs7V5naADYAGv3^sP zd;Xpu0w0Xd+&r{AQer~;cjI9F)}BjpC$lZoPyVcVve?PM!GIqaAhN=YjQ?3!4VZzH z0UtIOYikYwdai|uc + + private var privateApp: Application = _ + + /** + * Implicit method that returns the `Application` instance for the current test. + */ + implicit final def app: Application = synchronized { privateApp } + + /** + * Creates new instance of `Application` with parameters set to their defaults. Override this method if you + * need an `Application` created with non-default parameter values. + */ + def newAppForTest(testData: TestData): Application = fakeApplication() + + /** + * The port used by the `TestServer`. By default this will be set to the result returned from + * `Helpers.testServerPort`. You can override this to provide a different port number. + */ + lazy val port: Int = Helpers.testServerPort + + implicit val portNumber: PortNumber = PortNumber(port) + + /** + * Creates new `Application` and running `TestServer` instances before executing each test, and + * ensures they are cleaned up after the test completes. You can access the `Application` from + * your tests as `app` and the `TestServer`'s port number as `port`. + * + * @param test the no-arg test function to run with a fixture + * @return the `Outcome` of the test execution + */ + abstract override def withFixture(test: NoArgTest) = { + synchronized { privateApp = newAppForTest(test) } + + val testServer = new TestServer( + ServerConfig(port = None, sslPort = Some(port), mode = Mode.Test, rootDir = app.path), + app, + None + ) + + Helpers.running(testServer) { + super.withFixture(test) + } + } + + def createServer(context: ServerProvider.Context) = + new AkkaHttpServer(context.config, context.appProvider, context.actorSystem, context.materializer, + context.stopHook) + +} diff --git a/test/integration/HowsMySSLSpec.scala b/test/integration/HowsMySSLSpec.scala deleted file mode 100644 index da0587694..000000000 --- a/test/integration/HowsMySSLSpec.scala +++ /dev/null @@ -1,44 +0,0 @@ -package integration - -import akka.actor.ActorSystem -import akka.stream.ActorMaterializer -import com.typesafe.config.ConfigFactory -import org.junit.runner._ -import org.specs2.runner._ -import play.api.Mode -import play.api.libs.json.{JsValue, Json} -import play.api.test._ - -import scala.concurrent.duration._ - -@RunWith(classOf[JUnitRunner]) -class HowsMySSLSpec extends PlaySpecification with https.ClientMethods { - - "WS" should { - - "connect to a remote server " in { - val input = """play.ws.ssl { - | //enabledProtocols = [ TLSv1.2 ] - |} - """.stripMargin - val config = play.api.Configuration(ConfigFactory.parseString(input).withFallback(ConfigFactory.defaultReference())) - val environment = play.api.Environment.simple(new java.io.File("./conf"), Mode.Dev) - - val name = "testing" - val system = ActorSystem(name) - implicit val materializer = ActorMaterializer(namePrefix = Some(name))(system) - - val client = createClient(config, environment) - - val response = await(client.url("https://www.howsmyssl.com/a/check").get())(2 seconds) - val jsonOutput = response.json - - system.terminate() - client.close() - - val tlsVersion = (jsonOutput \ "tls_version").as[String] - tlsVersion must contain("TLS 1.2") - } - } - -} diff --git a/test/integration/ServerSpec.scala b/test/integration/ServerSpec.scala new file mode 100644 index 000000000..ba2fca0ed --- /dev/null +++ b/test/integration/ServerSpec.scala @@ -0,0 +1,36 @@ +package integration + +import akka.actor.ActorSystem +import akka.stream.ActorMaterializer +import com.typesafe.config.ConfigFactory +import org.scalatest.BeforeAndAfterAll +import org.scalatest.concurrent.ScalaFutures +import org.scalatestplus.play._ +import play.api.libs.ws.ahc.{AhcWSClient, AhcWSClientConfigFactory} + +/** + * Test the server comes up with given settings + */ +class ServerSpec extends PlaySpec with GuiceOneHttpsServerPerTest with ScalaFutures with BeforeAndAfterAll { + + val name = "testing" + val system = ActorSystem(name) + implicit val materializer = ActorMaterializer(namePrefix = Some(name))(system) + + val config = ConfigFactory.load("ws").withFallback(ConfigFactory.defaultReference()) + val wsConfig = AhcWSClientConfigFactory.forConfig(config) + val client = AhcWSClient(wsConfig) + + "Server" should { + "work fine over https" in pendingUntilFixed { + whenReady(client.url(s"https://example.com:$port/").get()) { result => + result.body must include("This is the page") + } + } + } + + override protected def afterAll(): Unit = { + client.close() + system.terminate() + } +} From fd0fbd0ac585e649dc892c21b2beec102ebe40c9 Mon Sep 17 00:00:00 2001 From: Will Sargent Date: Thu, 16 Mar 2017 16:14:06 -0700 Subject: [PATCH 20/53] Updated with template-control on 2017-03-08T05:19:14.932Z (#20) /LICENSE: wrote /LICENSE --- conf/application.conf | 2 +- scripts/client.crt | 24 ++++++++++++------------ scripts/client.csr | 14 +++++++------- scripts/clientca.crt | 22 +++++++++++----------- scripts/example.com.crt | 26 +++++++++++++------------- scripts/example.com.csr | 14 +++++++------- scripts/exampleca.crt | 22 +++++++++++----------- scripts/one.example.com.crt | 26 +++++++++++++------------- scripts/one.example.com.csr | 14 +++++++------- scripts/two.example.com.crt | 26 +++++++++++++------------- scripts/two.example.com.csr | 14 +++++++------- scripts/wildcard.example.com.crt | 24 ++++++++++++------------ scripts/wildcard.example.com.csr | 14 +++++++------- 13 files changed, 121 insertions(+), 121 deletions(-) diff --git a/conf/application.conf b/conf/application.conf index eb19dfec5..439598422 100644 --- a/conf/application.conf +++ b/conf/application.conf @@ -4,4 +4,4 @@ play.http.secret.key=${?APPLICATION_SECRET} play.http.requestHandler = "router.MultiSiteRequestHandler" -play.server.https.engineProvider=https.CustomSSLEngineProvider \ No newline at end of file +play.server.https.engineProvider=https.CustomSSLEngineProvider diff --git a/scripts/client.crt b/scripts/client.crt index c6709ed8e..1b854090d 100644 --- a/scripts/client.crt +++ b/scripts/client.crt @@ -1,15 +1,15 @@ -----BEGIN CERTIFICATE----- -MIICRjCCAemgAwIBAgIEUuaIDjAMBggqhkjOPQQDAgUAMH0xCzAJBgNVBAYTAlVT -MRMwEQYDVQQIEwpDYWxpZm9ybmlhMRYwFAYDVQQHEw1TYW4gRnJhbmNpc2NvMRgw -FgYDVQQKEw9FeGFtcGxlIENvbXBhbnkxFDASBgNVBAsTC0V4YW1wbGUgT3JnMREw -DwYDVQQDEwhjbGllbnRjYTAeFw0xNzAyMjgyMjQzNTJaFw0xNzA1MjkyMjQzNTJa -MHsxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpDYWxpZm9ybmlhMRYwFAYDVQQHEw1T -YW4gRnJhbmNpc2NvMRgwFgYDVQQKEw9FeGFtcGxlIENvbXBhbnkxFDASBgNVBAsT -C0V4YW1wbGUgT3JnMQ8wDQYDVQQDEwZjbGllbnQwWTATBgcqhkjOPQIBBggqhkjO -PQMBBwNCAATU4DEAlfPWUt8ZxWkr7gX2dfWZ2bVYZr7xpSnuMbMzlrrwZ33hgn0s -y3Af7Zz3MchcB+I3+0JMSMkDF8K+p8Dgo1cwVTAfBgNVHSMEGDAWgBR8rEH7EEB+ -/ANuFJxkw10sgb2zAzATBgNVHSUEDDAKBggrBgEFBQcDAjAdBgNVHQ4EFgQUykKg -340VBk9CA8IKVKuoPaR5wl4wDAYIKoZIzj0EAwIFAANJADBGAiEApuSZvFIFl5Hb -N02c2HCtCvCVz81rvydpzgTMFH1O39wCIQCtwBwD9eFmyddU3I+QThgZwLMtn5lD +MIICRjCCAemgAwIBAgIEUuaIDjAMBggqhkjOPQQDAgUAMH0xCzAJBgNVBAYTAlVT +MRMwEQYDVQQIEwpDYWxpZm9ybmlhMRYwFAYDVQQHEw1TYW4gRnJhbmNpc2NvMRgw +FgYDVQQKEw9FeGFtcGxlIENvbXBhbnkxFDASBgNVBAsTC0V4YW1wbGUgT3JnMREw +DwYDVQQDEwhjbGllbnRjYTAeFw0xNzAyMjgyMjQzNTJaFw0xNzA1MjkyMjQzNTJa +MHsxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpDYWxpZm9ybmlhMRYwFAYDVQQHEw1T +YW4gRnJhbmNpc2NvMRgwFgYDVQQKEw9FeGFtcGxlIENvbXBhbnkxFDASBgNVBAsT +C0V4YW1wbGUgT3JnMQ8wDQYDVQQDEwZjbGllbnQwWTATBgcqhkjOPQIBBggqhkjO +PQMBBwNCAATU4DEAlfPWUt8ZxWkr7gX2dfWZ2bVYZr7xpSnuMbMzlrrwZ33hgn0s +y3Af7Zz3MchcB+I3+0JMSMkDF8K+p8Dgo1cwVTAfBgNVHSMEGDAWgBR8rEH7EEB+ +/ANuFJxkw10sgb2zAzATBgNVHSUEDDAKBggrBgEFBQcDAjAdBgNVHQ4EFgQUykKg +340VBk9CA8IKVKuoPaR5wl4wDAYIKoZIzj0EAwIFAANJADBGAiEApuSZvFIFl5Hb +N02c2HCtCvCVz81rvydpzgTMFH1O39wCIQCtwBwD9eFmyddU3I+QThgZwLMtn5lD KiAp8qa7GLyQXQ== -----END CERTIFICATE----- diff --git a/scripts/client.csr b/scripts/client.csr index cdb05c5e7..1eb22f699 100644 --- a/scripts/client.csr +++ b/scripts/client.csr @@ -1,10 +1,10 @@ -----BEGIN NEW CERTIFICATE REQUEST----- -MIIBajCCAQ0CAQAwezELMAkGA1UEBhMCVVMxEzARBgNVBAgTCkNhbGlmb3JuaWEx -FjAUBgNVBAcTDVNhbiBGcmFuY2lzY28xGDAWBgNVBAoTD0V4YW1wbGUgQ29tcGFu -eTEUMBIGA1UECxMLRXhhbXBsZSBPcmcxDzANBgNVBAMTBmNsaWVudDBZMBMGByqG -SM49AgEGCCqGSM49AwEHA0IABNTgMQCV89ZS3xnFaSvuBfZ19ZnZtVhmvvGlKe4x -szOWuvBnfeGCfSzLcB/tnPcxyFwH4jf7QkxIyQMXwr6nwOCgMDAuBgkqhkiG9w0B -CQ4xITAfMB0GA1UdDgQWBBTKQqDfjRUGT0IDwgpUq6g9pHnCXjAMBggqhkjOPQQD -AgUAA0kAMEYCIQCpWSYpcJB6CGHMCxUCFCUQwx7cUNVETIzCpcndM9TRBAIhAJzc +MIIBajCCAQ0CAQAwezELMAkGA1UEBhMCVVMxEzARBgNVBAgTCkNhbGlmb3JuaWEx +FjAUBgNVBAcTDVNhbiBGcmFuY2lzY28xGDAWBgNVBAoTD0V4YW1wbGUgQ29tcGFu +eTEUMBIGA1UECxMLRXhhbXBsZSBPcmcxDzANBgNVBAMTBmNsaWVudDBZMBMGByqG +SM49AgEGCCqGSM49AwEHA0IABNTgMQCV89ZS3xnFaSvuBfZ19ZnZtVhmvvGlKe4x +szOWuvBnfeGCfSzLcB/tnPcxyFwH4jf7QkxIyQMXwr6nwOCgMDAuBgkqhkiG9w0B +CQ4xITAfMB0GA1UdDgQWBBTKQqDfjRUGT0IDwgpUq6g9pHnCXjAMBggqhkjOPQQD +AgUAA0kAMEYCIQCpWSYpcJB6CGHMCxUCFCUQwx7cUNVETIzCpcndM9TRBAIhAJzc mjywUYOq2qw0QuQCSQ3eBQE5IRuFW48ULk6eosiB -----END NEW CERTIFICATE REQUEST----- diff --git a/scripts/clientca.crt b/scripts/clientca.crt index ecef6fc4b..5a5fbda94 100644 --- a/scripts/clientca.crt +++ b/scripts/clientca.crt @@ -1,14 +1,14 @@ -----BEGIN CERTIFICATE----- -MIICMjCCAdagAwIBAgIETmcxPjAMBggqhkjOPQQDAgUAMH0xCzAJBgNVBAYTAlVT -MRMwEQYDVQQIEwpDYWxpZm9ybmlhMRYwFAYDVQQHEw1TYW4gRnJhbmNpc2NvMRgw -FgYDVQQKEw9FeGFtcGxlIENvbXBhbnkxFDASBgNVBAsTC0V4YW1wbGUgT3JnMREw -DwYDVQQDEwhjbGllbnRjYTAeFw0xNzAyMjgyMjQzNTJaFw0xODAyMjgyMjQzNTJa -MH0xCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpDYWxpZm9ybmlhMRYwFAYDVQQHEw1T -YW4gRnJhbmNpc2NvMRgwFgYDVQQKEw9FeGFtcGxlIENvbXBhbnkxFDASBgNVBAsT -C0V4YW1wbGUgT3JnMREwDwYDVQQDEwhjbGllbnRjYTBZMBMGByqGSM49AgEGCCqG -SM49AwEHA0IABIJbZqvtzgIT2umzZfxiXQubhn8S4EdnbRxpUhWY1E7rGehsMH/0 -h1AZTakN2Trf9fvbsav3JHYWb0LpP4gKN22jQjBAMA8GA1UdEwEB/wQFMAMBAf8w -DgYDVR0PAQH/BAQDAgIEMB0GA1UdDgQWBBR8rEH7EEB+/ANuFJxkw10sgb2zAzAM -BggqhkjOPQQDAgUAA0gAMEUCIQDpmKZDBpR20016RAbrV6sHJdnEZqlD+SSqozsq +MIICMjCCAdagAwIBAgIETmcxPjAMBggqhkjOPQQDAgUAMH0xCzAJBgNVBAYTAlVT +MRMwEQYDVQQIEwpDYWxpZm9ybmlhMRYwFAYDVQQHEw1TYW4gRnJhbmNpc2NvMRgw +FgYDVQQKEw9FeGFtcGxlIENvbXBhbnkxFDASBgNVBAsTC0V4YW1wbGUgT3JnMREw +DwYDVQQDEwhjbGllbnRjYTAeFw0xNzAyMjgyMjQzNTJaFw0xODAyMjgyMjQzNTJa +MH0xCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpDYWxpZm9ybmlhMRYwFAYDVQQHEw1T +YW4gRnJhbmNpc2NvMRgwFgYDVQQKEw9FeGFtcGxlIENvbXBhbnkxFDASBgNVBAsT +C0V4YW1wbGUgT3JnMREwDwYDVQQDEwhjbGllbnRjYTBZMBMGByqGSM49AgEGCCqG +SM49AwEHA0IABIJbZqvtzgIT2umzZfxiXQubhn8S4EdnbRxpUhWY1E7rGehsMH/0 +h1AZTakN2Trf9fvbsav3JHYWb0LpP4gKN22jQjBAMA8GA1UdEwEB/wQFMAMBAf8w +DgYDVR0PAQH/BAQDAgIEMB0GA1UdDgQWBBR8rEH7EEB+/ANuFJxkw10sgb2zAzAM +BggqhkjOPQQDAgUAA0gAMEUCIQDpmKZDBpR20016RAbrV6sHJdnEZqlD+SSqozsq OLpNZgIgD0YoaJX/6nXlxPn+kV0NU2FBt/mAhe6LRnIyc05zo60= -----END CERTIFICATE----- diff --git a/scripts/example.com.crt b/scripts/example.com.crt index 3be4a6ca4..c9efa5b14 100644 --- a/scripts/example.com.crt +++ b/scripts/example.com.crt @@ -1,16 +1,16 @@ -----BEGIN CERTIFICATE----- -MIICdDCCAhigAwIBAgIEHb7/hTAMBggqhkjOPQQDAgUAMH4xCzAJBgNVBAYTAlVT -MRMwEQYDVQQIEwpDYWxpZm9ybmlhMRYwFAYDVQQHEw1TYW4gRnJhbmNpc2NvMRgw -FgYDVQQKEw9FeGFtcGxlIENvbXBhbnkxFDASBgNVBAsTC0V4YW1wbGUgT3JnMRIw -EAYDVQQDEwlleGFtcGxlQ0EwHhcNMTcwMjI4MjI0MzUzWhcNMTcwNTI5MjI0MzUz -WjCBgDELMAkGA1UEBhMCVVMxEzARBgNVBAgTCkNhbGlmb3JuaWExFjAUBgNVBAcT -DVNhbiBGcmFuY2lzY28xGDAWBgNVBAoTD0V4YW1wbGUgQ29tcGFueTEUMBIGA1UE -CxMLRXhhbXBsZSBPcmcxFDASBgNVBAMTC2V4YW1wbGUuY29tMFkwEwYHKoZIzj0C -AQYIKoZIzj0DAQcDQgAEgkS809VXcPuYK/vyigcJk9MChmHUs4L20ca0p1Ag4yAG -T7Qq4ifAmo9QI4UWujst76LUMZaoisc6j5OKHCEmNqN/MH0wHwYDVR0jBBgwFoAU -n5szvZjetSdYVfTLHovZZHH6VSswEwYDVR0lBAwwCgYIKwYBBQUHAwEwDgYDVR0P -AQH/BAQDAgWgMBYGA1UdEQQPMA2CC2V4YW1wbGUuY29tMB0GA1UdDgQWBBSK1EjW -tdm2w5vsKaNx1WcLEAdUHTAMBggqhkjOPQQDAgUAA0gAMEUCIGEPSLZsSKnHcUZJ -Rev0ygGm0sqqUGSna4TxATI+gjNaAiEAjKXwPKtaAZiULhqEzHSd770d/9kLMXqx +MIICdDCCAhigAwIBAgIEHb7/hTAMBggqhkjOPQQDAgUAMH4xCzAJBgNVBAYTAlVT +MRMwEQYDVQQIEwpDYWxpZm9ybmlhMRYwFAYDVQQHEw1TYW4gRnJhbmNpc2NvMRgw +FgYDVQQKEw9FeGFtcGxlIENvbXBhbnkxFDASBgNVBAsTC0V4YW1wbGUgT3JnMRIw +EAYDVQQDEwlleGFtcGxlQ0EwHhcNMTcwMjI4MjI0MzUzWhcNMTcwNTI5MjI0MzUz +WjCBgDELMAkGA1UEBhMCVVMxEzARBgNVBAgTCkNhbGlmb3JuaWExFjAUBgNVBAcT +DVNhbiBGcmFuY2lzY28xGDAWBgNVBAoTD0V4YW1wbGUgQ29tcGFueTEUMBIGA1UE +CxMLRXhhbXBsZSBPcmcxFDASBgNVBAMTC2V4YW1wbGUuY29tMFkwEwYHKoZIzj0C +AQYIKoZIzj0DAQcDQgAEgkS809VXcPuYK/vyigcJk9MChmHUs4L20ca0p1Ag4yAG +T7Qq4ifAmo9QI4UWujst76LUMZaoisc6j5OKHCEmNqN/MH0wHwYDVR0jBBgwFoAU +n5szvZjetSdYVfTLHovZZHH6VSswEwYDVR0lBAwwCgYIKwYBBQUHAwEwDgYDVR0P +AQH/BAQDAgWgMBYGA1UdEQQPMA2CC2V4YW1wbGUuY29tMB0GA1UdDgQWBBSK1EjW +tdm2w5vsKaNx1WcLEAdUHTAMBggqhkjOPQQDAgUAA0gAMEUCIGEPSLZsSKnHcUZJ +Rev0ygGm0sqqUGSna4TxATI+gjNaAiEAjKXwPKtaAZiULhqEzHSd770d/9kLMXqx zAhzew2qmHk= -----END CERTIFICATE----- diff --git a/scripts/example.com.csr b/scripts/example.com.csr index 926047fa5..470641077 100644 --- a/scripts/example.com.csr +++ b/scripts/example.com.csr @@ -1,10 +1,10 @@ -----BEGIN NEW CERTIFICATE REQUEST----- -MIIBbzCCARMCAQAwgYAxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpDYWxpZm9ybmlh -MRYwFAYDVQQHEw1TYW4gRnJhbmNpc2NvMRgwFgYDVQQKEw9FeGFtcGxlIENvbXBh -bnkxFDASBgNVBAsTC0V4YW1wbGUgT3JnMRQwEgYDVQQDEwtleGFtcGxlLmNvbTBZ -MBMGByqGSM49AgEGCCqGSM49AwEHA0IABIJEvNPVV3D7mCv78ooHCZPTAoZh1LOC -9tHGtKdQIOMgBk+0KuInwJqPUCOFFro7Le+i1DGWqIrHOo+TihwhJjagMDAuBgkq -hkiG9w0BCQ4xITAfMB0GA1UdDgQWBBSK1EjWtdm2w5vsKaNx1WcLEAdUHTAMBggq -hkjOPQQDAgUAA0gAMEUCIAEqF/xfWjrdPkAhVkKfI9UNJxQ1F6aKT5vpbbm7Sv1P +MIIBbzCCARMCAQAwgYAxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpDYWxpZm9ybmlh +MRYwFAYDVQQHEw1TYW4gRnJhbmNpc2NvMRgwFgYDVQQKEw9FeGFtcGxlIENvbXBh +bnkxFDASBgNVBAsTC0V4YW1wbGUgT3JnMRQwEgYDVQQDEwtleGFtcGxlLmNvbTBZ +MBMGByqGSM49AgEGCCqGSM49AwEHA0IABIJEvNPVV3D7mCv78ooHCZPTAoZh1LOC +9tHGtKdQIOMgBk+0KuInwJqPUCOFFro7Le+i1DGWqIrHOo+TihwhJjagMDAuBgkq +hkiG9w0BCQ4xITAfMB0GA1UdDgQWBBSK1EjWtdm2w5vsKaNx1WcLEAdUHTAMBggq +hkjOPQQDAgUAA0gAMEUCIAEqF/xfWjrdPkAhVkKfI9UNJxQ1F6aKT5vpbbm7Sv1P AiEAwLL6Vo5dWvy3wXyKflVE4T5uHGSBfenCTp78iQmm2xI= -----END NEW CERTIFICATE REQUEST----- diff --git a/scripts/exampleca.crt b/scripts/exampleca.crt index 1bc748765..c01eed0cb 100644 --- a/scripts/exampleca.crt +++ b/scripts/exampleca.crt @@ -1,14 +1,14 @@ -----BEGIN CERTIFICATE----- -MIICMzCCAdigAwIBAgIETYjQazAMBggqhkjOPQQDAgUAMH4xCzAJBgNVBAYTAlVT -MRMwEQYDVQQIEwpDYWxpZm9ybmlhMRYwFAYDVQQHEw1TYW4gRnJhbmNpc2NvMRgw -FgYDVQQKEw9FeGFtcGxlIENvbXBhbnkxFDASBgNVBAsTC0V4YW1wbGUgT3JnMRIw -EAYDVQQDEwlleGFtcGxlQ0EwHhcNMTcwMjI4MjI0MzUxWhcNNDQwNzE1MjI0MzUx -WjB+MQswCQYDVQQGEwJVUzETMBEGA1UECBMKQ2FsaWZvcm5pYTEWMBQGA1UEBxMN -U2FuIEZyYW5jaXNjbzEYMBYGA1UEChMPRXhhbXBsZSBDb21wYW55MRQwEgYDVQQL -EwtFeGFtcGxlIE9yZzESMBAGA1UEAxMJZXhhbXBsZUNBMFkwEwYHKoZIzj0CAQYI -KoZIzj0DAQcDQgAEOQ0fX29Q+8jOgvw7btx+fXnUGT99GxKN0F9VbA5Ir7J6R2+8 -+BDwMszZwqdZGJCH9zNTL4WM0h7Jazgnyfl85KNCMEAwDwYDVR0TAQH/BAUwAwEB -/zAOBgNVHQ8BAf8EBAMCAgQwHQYDVR0OBBYEFJ+bM72Y3rUnWFX0yx6L2WRx+lUr -MAwGCCqGSM49BAMCBQADRwAwRAIgSQqiVpa0jdeBJueBydYm5MHiX5rhNf4a+diE +MIICMzCCAdigAwIBAgIETYjQazAMBggqhkjOPQQDAgUAMH4xCzAJBgNVBAYTAlVT +MRMwEQYDVQQIEwpDYWxpZm9ybmlhMRYwFAYDVQQHEw1TYW4gRnJhbmNpc2NvMRgw +FgYDVQQKEw9FeGFtcGxlIENvbXBhbnkxFDASBgNVBAsTC0V4YW1wbGUgT3JnMRIw +EAYDVQQDEwlleGFtcGxlQ0EwHhcNMTcwMjI4MjI0MzUxWhcNNDQwNzE1MjI0MzUx +WjB+MQswCQYDVQQGEwJVUzETMBEGA1UECBMKQ2FsaWZvcm5pYTEWMBQGA1UEBxMN +U2FuIEZyYW5jaXNjbzEYMBYGA1UEChMPRXhhbXBsZSBDb21wYW55MRQwEgYDVQQL +EwtFeGFtcGxlIE9yZzESMBAGA1UEAxMJZXhhbXBsZUNBMFkwEwYHKoZIzj0CAQYI +KoZIzj0DAQcDQgAEOQ0fX29Q+8jOgvw7btx+fXnUGT99GxKN0F9VbA5Ir7J6R2+8 ++BDwMszZwqdZGJCH9zNTL4WM0h7Jazgnyfl85KNCMEAwDwYDVR0TAQH/BAUwAwEB +/zAOBgNVHQ8BAf8EBAMCAgQwHQYDVR0OBBYEFJ+bM72Y3rUnWFX0yx6L2WRx+lUr +MAwGCCqGSM49BAMCBQADRwAwRAIgSQqiVpa0jdeBJueBydYm5MHiX5rhNf4a+diE LEuo3d8CID4mqFvs9rRAMYAMjztFPbWHvt/Ei+kPz7bveHfqNgDV -----END CERTIFICATE----- diff --git a/scripts/one.example.com.crt b/scripts/one.example.com.crt index d7cec67bb..8bf3ea089 100644 --- a/scripts/one.example.com.crt +++ b/scripts/one.example.com.crt @@ -1,16 +1,16 @@ -----BEGIN CERTIFICATE----- -MIICfzCCAiKgAwIBAgIEW8LBNzAMBggqhkjOPQQDAgUAMH4xCzAJBgNVBAYTAlVT -MRMwEQYDVQQIEwpDYWxpZm9ybmlhMRYwFAYDVQQHEw1TYW4gRnJhbmNpc2NvMRgw -FgYDVQQKEw9FeGFtcGxlIENvbXBhbnkxFDASBgNVBAsTC0V4YW1wbGUgT3JnMRIw -EAYDVQQDEwlleGFtcGxlQ0EwHhcNMTcwMjI4MjI0MzU0WhcNMTcwNTI5MjI0MzU0 -WjCBhDELMAkGA1UEBhMCVVMxEzARBgNVBAgTCkNhbGlmb3JuaWExFjAUBgNVBAcT -DVNhbiBGcmFuY2lzY28xGDAWBgNVBAoTD0V4YW1wbGUgQ29tcGFueTEUMBIGA1UE -CxMLRXhhbXBsZSBPcmcxGDAWBgNVBAMTD29uZS5leGFtcGxlLmNvbTBZMBMGByqG -SM49AgEGCCqGSM49AwEHA0IABFGWM+El6kkxkJNDVgLhxfkioDLAOCTptwDjbFDd -76lOpCiwMNIrOcO9EOdRJJJtln+wLpzWZkTVzIHe9CNx09OjgYQwgYEwHwYDVR0j -BBgwFoAUn5szvZjetSdYVfTLHovZZHH6VSswEwYDVR0lBAwwCgYIKwYBBQUHAwEw -DgYDVR0PAQH/BAQDAgWgMBoGA1UdEQQTMBGCD29uZS5leGFtcGxlLmNvbTAdBgNV -HQ4EFgQUDhIRm98cJ/L0S7yKXf2afLb4WUIwDAYIKoZIzj0EAwIFAANJADBGAiEA -5zx7/xP6tkodjSgEOcHdzHzs4ch72Be48FUF86mfItsCIQCiZERgEGOKpBVYZwxg +MIICfzCCAiKgAwIBAgIEW8LBNzAMBggqhkjOPQQDAgUAMH4xCzAJBgNVBAYTAlVT +MRMwEQYDVQQIEwpDYWxpZm9ybmlhMRYwFAYDVQQHEw1TYW4gRnJhbmNpc2NvMRgw +FgYDVQQKEw9FeGFtcGxlIENvbXBhbnkxFDASBgNVBAsTC0V4YW1wbGUgT3JnMRIw +EAYDVQQDEwlleGFtcGxlQ0EwHhcNMTcwMjI4MjI0MzU0WhcNMTcwNTI5MjI0MzU0 +WjCBhDELMAkGA1UEBhMCVVMxEzARBgNVBAgTCkNhbGlmb3JuaWExFjAUBgNVBAcT +DVNhbiBGcmFuY2lzY28xGDAWBgNVBAoTD0V4YW1wbGUgQ29tcGFueTEUMBIGA1UE +CxMLRXhhbXBsZSBPcmcxGDAWBgNVBAMTD29uZS5leGFtcGxlLmNvbTBZMBMGByqG +SM49AgEGCCqGSM49AwEHA0IABFGWM+El6kkxkJNDVgLhxfkioDLAOCTptwDjbFDd +76lOpCiwMNIrOcO9EOdRJJJtln+wLpzWZkTVzIHe9CNx09OjgYQwgYEwHwYDVR0j +BBgwFoAUn5szvZjetSdYVfTLHovZZHH6VSswEwYDVR0lBAwwCgYIKwYBBQUHAwEw +DgYDVR0PAQH/BAQDAgWgMBoGA1UdEQQTMBGCD29uZS5leGFtcGxlLmNvbTAdBgNV +HQ4EFgQUDhIRm98cJ/L0S7yKXf2afLb4WUIwDAYIKoZIzj0EAwIFAANJADBGAiEA +5zx7/xP6tkodjSgEOcHdzHzs4ch72Be48FUF86mfItsCIQCiZERgEGOKpBVYZwxg vb7CZJWIqrMrxFzgEn8uLzotTA== -----END CERTIFICATE----- diff --git a/scripts/one.example.com.csr b/scripts/one.example.com.csr index 4c9da9552..423beefae 100644 --- a/scripts/one.example.com.csr +++ b/scripts/one.example.com.csr @@ -1,10 +1,10 @@ -----BEGIN NEW CERTIFICATE REQUEST----- -MIIBczCCARcCAQAwgYQxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpDYWxpZm9ybmlh -MRYwFAYDVQQHEw1TYW4gRnJhbmNpc2NvMRgwFgYDVQQKEw9FeGFtcGxlIENvbXBh -bnkxFDASBgNVBAsTC0V4YW1wbGUgT3JnMRgwFgYDVQQDEw9vbmUuZXhhbXBsZS5j -b20wWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAARRljPhJepJMZCTQ1YC4cX5IqAy -wDgk6bcA42xQ3e+pTqQosDDSKznDvRDnUSSSbZZ/sC6c1mZE1cyB3vQjcdPToDAw -LgYJKoZIhvcNAQkOMSEwHzAdBgNVHQ4EFgQUDhIRm98cJ/L0S7yKXf2afLb4WUIw -DAYIKoZIzj0EAwIFAANIADBFAiBUe+0G9zii3QJZGPfzV6qfKuCUghrpPc8AC2ZE +MIIBczCCARcCAQAwgYQxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpDYWxpZm9ybmlh +MRYwFAYDVQQHEw1TYW4gRnJhbmNpc2NvMRgwFgYDVQQKEw9FeGFtcGxlIENvbXBh +bnkxFDASBgNVBAsTC0V4YW1wbGUgT3JnMRgwFgYDVQQDEw9vbmUuZXhhbXBsZS5j +b20wWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAARRljPhJepJMZCTQ1YC4cX5IqAy +wDgk6bcA42xQ3e+pTqQosDDSKznDvRDnUSSSbZZ/sC6c1mZE1cyB3vQjcdPToDAw +LgYJKoZIhvcNAQkOMSEwHzAdBgNVHQ4EFgQUDhIRm98cJ/L0S7yKXf2afLb4WUIw +DAYIKoZIzj0EAwIFAANIADBFAiBUe+0G9zii3QJZGPfzV6qfKuCUghrpPc8AC2ZE GlP1jQIhAO6PD2UvGVmWDUEFCgo0xm1myfY7zEdmLNKoZRkqh6wt -----END NEW CERTIFICATE REQUEST----- diff --git a/scripts/two.example.com.crt b/scripts/two.example.com.crt index bf35fc009..a57f2514f 100644 --- a/scripts/two.example.com.crt +++ b/scripts/two.example.com.crt @@ -1,16 +1,16 @@ -----BEGIN CERTIFICATE----- -MIICfjCCAiKgAwIBAgIEfF9tVjAMBggqhkjOPQQDAgUAMH4xCzAJBgNVBAYTAlVT -MRMwEQYDVQQIEwpDYWxpZm9ybmlhMRYwFAYDVQQHEw1TYW4gRnJhbmNpc2NvMRgw -FgYDVQQKEw9FeGFtcGxlIENvbXBhbnkxFDASBgNVBAsTC0V4YW1wbGUgT3JnMRIw -EAYDVQQDEwlleGFtcGxlQ0EwHhcNMTcwMjI4MjI0MzU0WhcNMTcwNTI5MjI0MzU0 -WjCBhDELMAkGA1UEBhMCVVMxEzARBgNVBAgTCkNhbGlmb3JuaWExFjAUBgNVBAcT -DVNhbiBGcmFuY2lzY28xGDAWBgNVBAoTD0V4YW1wbGUgQ29tcGFueTEUMBIGA1UE -CxMLRXhhbXBsZSBPcmcxGDAWBgNVBAMTD3R3by5leGFtcGxlLmNvbTBZMBMGByqG -SM49AgEGCCqGSM49AwEHA0IABIIRpP0Kb8+YPKt8Gb8yMJlIw9GVVnxuy65cz3uG -4Ps38TUlPkMu2CiaJ77ApJ03EY26Si6g1YoyLg0O1Bw/51ajgYQwgYEwHwYDVR0j -BBgwFoAUn5szvZjetSdYVfTLHovZZHH6VSswEwYDVR0lBAwwCgYIKwYBBQUHAwEw -DgYDVR0PAQH/BAQDAgWgMBoGA1UdEQQTMBGCD3R3by5leGFtcGxlLmNvbTAdBgNV -HQ4EFgQUkZROdFtXEL2Vy+uamKkJ4XTk3PkwDAYIKoZIzj0EAwIFAANIADBFAiEA -gK9ZV2nZH+t4ze0RszgaE63DbpcKUjmG2p4DC4eQnIUCIHJeyM0DCqOtCHZz63Y/ +MIICfjCCAiKgAwIBAgIEfF9tVjAMBggqhkjOPQQDAgUAMH4xCzAJBgNVBAYTAlVT +MRMwEQYDVQQIEwpDYWxpZm9ybmlhMRYwFAYDVQQHEw1TYW4gRnJhbmNpc2NvMRgw +FgYDVQQKEw9FeGFtcGxlIENvbXBhbnkxFDASBgNVBAsTC0V4YW1wbGUgT3JnMRIw +EAYDVQQDEwlleGFtcGxlQ0EwHhcNMTcwMjI4MjI0MzU0WhcNMTcwNTI5MjI0MzU0 +WjCBhDELMAkGA1UEBhMCVVMxEzARBgNVBAgTCkNhbGlmb3JuaWExFjAUBgNVBAcT +DVNhbiBGcmFuY2lzY28xGDAWBgNVBAoTD0V4YW1wbGUgQ29tcGFueTEUMBIGA1UE +CxMLRXhhbXBsZSBPcmcxGDAWBgNVBAMTD3R3by5leGFtcGxlLmNvbTBZMBMGByqG +SM49AgEGCCqGSM49AwEHA0IABIIRpP0Kb8+YPKt8Gb8yMJlIw9GVVnxuy65cz3uG +4Ps38TUlPkMu2CiaJ77ApJ03EY26Si6g1YoyLg0O1Bw/51ajgYQwgYEwHwYDVR0j +BBgwFoAUn5szvZjetSdYVfTLHovZZHH6VSswEwYDVR0lBAwwCgYIKwYBBQUHAwEw +DgYDVR0PAQH/BAQDAgWgMBoGA1UdEQQTMBGCD3R3by5leGFtcGxlLmNvbTAdBgNV +HQ4EFgQUkZROdFtXEL2Vy+uamKkJ4XTk3PkwDAYIKoZIzj0EAwIFAANIADBFAiEA +gK9ZV2nZH+t4ze0RszgaE63DbpcKUjmG2p4DC4eQnIUCIHJeyM0DCqOtCHZz63Y/ w9oCgsmFKv21SRSUrmZXshMH -----END CERTIFICATE----- diff --git a/scripts/two.example.com.csr b/scripts/two.example.com.csr index 6e1bb4a7e..f90ac5597 100644 --- a/scripts/two.example.com.csr +++ b/scripts/two.example.com.csr @@ -1,10 +1,10 @@ -----BEGIN NEW CERTIFICATE REQUEST----- -MIIBczCCARcCAQAwgYQxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpDYWxpZm9ybmlh -MRYwFAYDVQQHEw1TYW4gRnJhbmNpc2NvMRgwFgYDVQQKEw9FeGFtcGxlIENvbXBh -bnkxFDASBgNVBAsTC0V4YW1wbGUgT3JnMRgwFgYDVQQDEw90d28uZXhhbXBsZS5j -b20wWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAASCEaT9Cm/PmDyrfBm/MjCZSMPR -lVZ8bsuuXM97huD7N/E1JT5DLtgomie+wKSdNxGNukouoNWKMi4NDtQcP+dWoDAw -LgYJKoZIhvcNAQkOMSEwHzAdBgNVHQ4EFgQUkZROdFtXEL2Vy+uamKkJ4XTk3Pkw -DAYIKoZIzj0EAwIFAANIADBFAiEAvqtgt3TpsiJlGtIHMT5AtPurdANHCPTNNANU +MIIBczCCARcCAQAwgYQxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpDYWxpZm9ybmlh +MRYwFAYDVQQHEw1TYW4gRnJhbmNpc2NvMRgwFgYDVQQKEw9FeGFtcGxlIENvbXBh +bnkxFDASBgNVBAsTC0V4YW1wbGUgT3JnMRgwFgYDVQQDEw90d28uZXhhbXBsZS5j +b20wWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAASCEaT9Cm/PmDyrfBm/MjCZSMPR +lVZ8bsuuXM97huD7N/E1JT5DLtgomie+wKSdNxGNukouoNWKMi4NDtQcP+dWoDAw +LgYJKoZIhvcNAQkOMSEwHzAdBgNVHQ4EFgQUkZROdFtXEL2Vy+uamKkJ4XTk3Pkw +DAYIKoZIzj0EAwIFAANIADBFAiEAvqtgt3TpsiJlGtIHMT5AtPurdANHCPTNNANU cP28bC8CIF+FTnyds+aLqnlAqa5bdnsAys+7AaYfv/ifNyU1brzX -----END NEW CERTIFICATE REQUEST----- diff --git a/scripts/wildcard.example.com.crt b/scripts/wildcard.example.com.crt index ca26c77fb..5fb67190a 100644 --- a/scripts/wildcard.example.com.crt +++ b/scripts/wildcard.example.com.crt @@ -1,15 +1,15 @@ -----BEGIN CERTIFICATE----- -MIICXzCCAgKgAwIBAgIEci94DDAMBggqhkjOPQQDAgUAMH4xCzAJBgNVBAYTAlVT -MRMwEQYDVQQIEwpDYWxpZm9ybmlhMRYwFAYDVQQHEw1TYW4gRnJhbmNpc2NvMRgw -FgYDVQQKEw9FeGFtcGxlIENvbXBhbnkxFDASBgNVBAsTC0V4YW1wbGUgT3JnMRIw -EAYDVQQDEwlleGFtcGxlQ0EwHhcNMTcwMjI4MjI0MzU1WhcNMTcwNTI5MjI0MzU1 -WjCBgjELMAkGA1UEBhMCVVMxEzARBgNVBAgTCkNhbGlmb3JuaWExFjAUBgNVBAcT -DVNhbiBGcmFuY2lzY28xGDAWBgNVBAoTD0V4YW1wbGUgQ29tcGFueTEUMBIGA1UE -CxMLRXhhbXBsZSBPcmcxFjAUBgNVBAMMDSouZXhhbXBsZS5jb20wWTATBgcqhkjO -PQIBBggqhkjOPQMBBwNCAASTGa3jaDXb3Gi5KNWwVwWkcXIVXtt5xu84gE7TUSfE -WDAxutPya8HmNZywkTaNGmKDCGeuA7tRGCv7RAhtWEByo2cwZTAfBgNVHSMEGDAW -gBSfmzO9mN61J1hV9Msei9lkcfpVKzATBgNVHSUEDDAKBggrBgEFBQcDATAOBgNV -HQ8BAf8EBAMCBaAwHQYDVR0OBBYEFKCcpFCFulPF/G9Ug1a5AJQSzpcBMAwGCCqG -SM49BAMCBQADSQAwRgIhAJTal/9hrcen9LQykuXKJPVZzzntMXAv8aji+NQwQA5o +MIICXzCCAgKgAwIBAgIEci94DDAMBggqhkjOPQQDAgUAMH4xCzAJBgNVBAYTAlVT +MRMwEQYDVQQIEwpDYWxpZm9ybmlhMRYwFAYDVQQHEw1TYW4gRnJhbmNpc2NvMRgw +FgYDVQQKEw9FeGFtcGxlIENvbXBhbnkxFDASBgNVBAsTC0V4YW1wbGUgT3JnMRIw +EAYDVQQDEwlleGFtcGxlQ0EwHhcNMTcwMjI4MjI0MzU1WhcNMTcwNTI5MjI0MzU1 +WjCBgjELMAkGA1UEBhMCVVMxEzARBgNVBAgTCkNhbGlmb3JuaWExFjAUBgNVBAcT +DVNhbiBGcmFuY2lzY28xGDAWBgNVBAoTD0V4YW1wbGUgQ29tcGFueTEUMBIGA1UE +CxMLRXhhbXBsZSBPcmcxFjAUBgNVBAMMDSouZXhhbXBsZS5jb20wWTATBgcqhkjO +PQIBBggqhkjOPQMBBwNCAASTGa3jaDXb3Gi5KNWwVwWkcXIVXtt5xu84gE7TUSfE +WDAxutPya8HmNZywkTaNGmKDCGeuA7tRGCv7RAhtWEByo2cwZTAfBgNVHSMEGDAW +gBSfmzO9mN61J1hV9Msei9lkcfpVKzATBgNVHSUEDDAKBggrBgEFBQcDATAOBgNV +HQ8BAf8EBAMCBaAwHQYDVR0OBBYEFKCcpFCFulPF/G9Ug1a5AJQSzpcBMAwGCCqG +SM49BAMCBQADSQAwRgIhAJTal/9hrcen9LQykuXKJPVZzzntMXAv8aji+NQwQA5o AiEA4p7Gg6rLjt+OwqhENoZRXNTTPkTJ372pTxar/Q1t5z4= -----END CERTIFICATE----- diff --git a/scripts/wildcard.example.com.csr b/scripts/wildcard.example.com.csr index 479954353..be3b5a132 100644 --- a/scripts/wildcard.example.com.csr +++ b/scripts/wildcard.example.com.csr @@ -1,10 +1,10 @@ -----BEGIN NEW CERTIFICATE REQUEST----- -MIIBcDCCARUCAQAwgYIxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpDYWxpZm9ybmlh -MRYwFAYDVQQHEw1TYW4gRnJhbmNpc2NvMRgwFgYDVQQKEw9FeGFtcGxlIENvbXBh -bnkxFDASBgNVBAsTC0V4YW1wbGUgT3JnMRYwFAYDVQQDDA0qLmV4YW1wbGUuY29t -MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEkxmt42g129xouSjVsFcFpHFyFV7b -ecbvOIBO01EnxFgwMbrT8mvB5jWcsJE2jRpigwhnrgO7URgr+0QIbVhAcqAwMC4G -CSqGSIb3DQEJDjEhMB8wHQYDVR0OBBYEFKCcpFCFulPF/G9Ug1a5AJQSzpcBMAwG -CCqGSM49BAMCBQADRwAwRAIgeECb69mQ/aT3FITqEE/9ERb94KzCHocE4zkYdSrQ +MIIBcDCCARUCAQAwgYIxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpDYWxpZm9ybmlh +MRYwFAYDVQQHEw1TYW4gRnJhbmNpc2NvMRgwFgYDVQQKEw9FeGFtcGxlIENvbXBh +bnkxFDASBgNVBAsTC0V4YW1wbGUgT3JnMRYwFAYDVQQDDA0qLmV4YW1wbGUuY29t +MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEkxmt42g129xouSjVsFcFpHFyFV7b +ecbvOIBO01EnxFgwMbrT8mvB5jWcsJE2jRpigwhnrgO7URgr+0QIbVhAcqAwMC4G +CSqGSIb3DQEJDjEhMB8wHQYDVR0OBBYEFKCcpFCFulPF/G9Ug1a5AJQSzpcBMAwG +CCqGSM49BAMCBQADRwAwRAIgeECb69mQ/aT3FITqEE/9ERb94KzCHocE4zkYdSrQ zRACIEEslQ1Z1n2N7lJGtHk79aEDnm71lp1Jh73HIcK6Z7h+ -----END NEW CERTIFICATE REQUEST----- From acf4529a62fbe29dd3d8c5eb96a809927a90f252 Mon Sep 17 00:00:00 2001 From: Will Sargent Date: Tue, 18 Apr 2017 12:35:48 -0700 Subject: [PATCH 21/53] Updated with template-control on 2017-03-28T20:57:27.983Z (#22) /LICENSE: wrote /LICENSE **/build.sbt: libraryDependencies += "org.scalatestplus.play" %% "scalatestplus-play" % "3.0.0-M2" % Test **/plugins.sbt: addSbtPlugin("com.typesafe.play" % "sbt-plugin" % "2.6.0-M3") --- build.sbt | 2 +- project/plugins.sbt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/build.sbt b/build.sbt index c35f8ee53..97ccc3814 100644 --- a/build.sbt +++ b/build.sbt @@ -13,7 +13,7 @@ lazy val root = (project in file(".")).enablePlugins(PlayScala) scalaVersion := "2.12.1" libraryDependencies += ws -libraryDependencies += "org.scalatestplus.play" %% "scalatestplus-play" % "2.0.0-M2" % Test +libraryDependencies += "org.scalatestplus.play" %% "scalatestplus-play" % "3.0.0-M2" % Test fork in run := true diff --git a/project/plugins.sbt b/project/plugins.sbt index 1c0f2e2cd..0f16cca01 100644 --- a/project/plugins.sbt +++ b/project/plugins.sbt @@ -1,5 +1,5 @@ resolvers += "Typesafe repository" at "http://repo.typesafe.com/typesafe/releases/" // The Play plugin -addSbtPlugin("com.typesafe.play" % "sbt-plugin" % "2.6.0-M1") +addSbtPlugin("com.typesafe.play" % "sbt-plugin" % "2.6.0-M3") From 6824626d0ea4b712718c55554603d948f9c46034 Mon Sep 17 00:00:00 2001 From: Will Sargent Date: Tue, 18 Apr 2017 13:50:45 -0700 Subject: [PATCH 22/53] Updated with template-control on 2017-04-18T20:11:56.276Z (#27) /LICENSE: wrote /LICENSE **/build.sbt: scalaVersion := "2.12.2" **/build.sbt: libraryDependencies += "org.scalatestplus.play" %% "scalatestplus-play" % "3.0.0-M3" % Test **/build.sbt: scalaVersion := "2.12.2" **/build.sbt: scalaVersion := "2.12.2" **/build.properties: sbt.version=0.13.15 **/build.properties: sbt.version=0.13.15 **/build.properties: sbt.version=0.13.15 **/plugins.sbt: addSbtPlugin("com.typesafe.play" % "sbt-plugin" % "2.6.0-M4") --- build.sbt | 4 ++-- modules/one/build.sbt | 2 +- modules/one/project/build.properties | 2 +- modules/two/build.sbt | 2 +- modules/two/project/build.properties | 2 +- project/build.properties | 2 +- project/plugins.sbt | 2 +- 7 files changed, 8 insertions(+), 8 deletions(-) diff --git a/build.sbt b/build.sbt index 97ccc3814..3b4b2da1e 100644 --- a/build.sbt +++ b/build.sbt @@ -10,10 +10,10 @@ lazy val root = (project in file(".")).enablePlugins(PlayScala) .aggregate(one, two) .dependsOn(one, two) -scalaVersion := "2.12.1" +scalaVersion := "2.12.2" libraryDependencies += ws -libraryDependencies += "org.scalatestplus.play" %% "scalatestplus-play" % "3.0.0-M2" % Test +libraryDependencies += "org.scalatestplus.play" %% "scalatestplus-play" % "3.0.0-M3" % Test fork in run := true diff --git a/modules/one/build.sbt b/modules/one/build.sbt index 7a5e11a9b..bf7c2d3a0 100644 --- a/modules/one/build.sbt +++ b/modules/one/build.sbt @@ -1,2 +1,2 @@ -scalaVersion := "2.12.1" +scalaVersion := "2.12.2" diff --git a/modules/one/project/build.properties b/modules/one/project/build.properties index e8ed0c8e4..2b112b751 100644 --- a/modules/one/project/build.properties +++ b/modules/one/project/build.properties @@ -1,4 +1,4 @@ #Activator-generated Properties #Fri Jul 08 22:56:54 PDT 2016 template.uuid=f57599cf-a4f5-4333-9ff1-55d48fd49891 -sbt.version=0.13.13 +sbt.version=0.13.15 diff --git a/modules/two/build.sbt b/modules/two/build.sbt index 7a5e11a9b..bf7c2d3a0 100644 --- a/modules/two/build.sbt +++ b/modules/two/build.sbt @@ -1,2 +1,2 @@ -scalaVersion := "2.12.1" +scalaVersion := "2.12.2" diff --git a/modules/two/project/build.properties b/modules/two/project/build.properties index 27e88aa11..64317fdae 100644 --- a/modules/two/project/build.properties +++ b/modules/two/project/build.properties @@ -1 +1 @@ -sbt.version=0.13.13 +sbt.version=0.13.15 diff --git a/project/build.properties b/project/build.properties index 6bd264564..59875ef19 100644 --- a/project/build.properties +++ b/project/build.properties @@ -1,4 +1,4 @@ #Activator-generated Properties #Sun Jul 06 17:54:30 PDT 2014 template.uuid=af582966-096a-43df-a504-5ddae8d4ebf1 -sbt.version=0.13.13 +sbt.version=0.13.15 diff --git a/project/plugins.sbt b/project/plugins.sbt index 0f16cca01..5a4c19dd0 100644 --- a/project/plugins.sbt +++ b/project/plugins.sbt @@ -1,5 +1,5 @@ resolvers += "Typesafe repository" at "http://repo.typesafe.com/typesafe/releases/" // The Play plugin -addSbtPlugin("com.typesafe.play" % "sbt-plugin" % "2.6.0-M3") +addSbtPlugin("com.typesafe.play" % "sbt-plugin" % "2.6.0-M4") From 13c651ecadc475a6a6c3adb95ec68fcfb7d44b7c Mon Sep 17 00:00:00 2001 From: Will Sargent Date: Thu, 11 May 2017 12:43:49 -0700 Subject: [PATCH 23/53] Updated with template-control on 2017-04-28T01:46:59.333Z (#28) /LICENSE: wrote /LICENSE **/plugins.sbt: addSbtPlugin("com.typesafe.play" % "sbt-plugin" % "2.6.0-M5") --- project/plugins.sbt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/project/plugins.sbt b/project/plugins.sbt index 5a4c19dd0..d87690a00 100644 --- a/project/plugins.sbt +++ b/project/plugins.sbt @@ -1,5 +1,5 @@ resolvers += "Typesafe repository" at "http://repo.typesafe.com/typesafe/releases/" // The Play plugin -addSbtPlugin("com.typesafe.play" % "sbt-plugin" % "2.6.0-M4") +addSbtPlugin("com.typesafe.play" % "sbt-plugin" % "2.6.0-M5") From 386281739fa9761fb86540fa1b5186367252c280 Mon Sep 17 00:00:00 2001 From: Greg Methvin Date: Mon, 19 Jun 2017 15:31:51 -0700 Subject: [PATCH 24/53] Changes for HTTP/2 support (#30) --- app/https/CustomSSLEngineProvider.scala | 10 +++++++-- build.sbt | 4 +++- conf/application.conf | 8 ++++++- conf/generated.keystore | Bin 0 -> 3174 bytes play | 12 ++++++++-- project/plugins.sbt | 2 +- scripts/client.crt | 26 +++++++++++----------- scripts/client.csr | 16 +++++++------- scripts/client.jks | Bin 2095 -> 2095 bytes scripts/client.p12 | Bin 1101 -> 1101 bytes scripts/clientca.crt | 24 ++++++++++---------- scripts/clientca.jks | Bin 631 -> 632 bytes scripts/example.com.crt | 28 ++++++++++++------------ scripts/example.com.csr | 16 +++++++------- scripts/example.com.jks | Bin 6174 -> 6175 bytes scripts/exampleca.crt | 24 ++++++++++---------- scripts/exampleca.jks | Bin 768 -> 768 bytes scripts/exampletrust.jks | Bin 633 -> 633 bytes scripts/one.example.com.crt | 28 ++++++++++++------------ scripts/one.example.com.csr | 16 +++++++------- scripts/password | 2 +- scripts/two.example.com.crt | 28 ++++++++++++------------ scripts/two.example.com.csr | 16 +++++++------- scripts/wildcard.example.com.crt | 26 +++++++++++----------- scripts/wildcard.example.com.csr | 16 +++++++------- 25 files changed, 162 insertions(+), 140 deletions(-) create mode 100644 conf/generated.keystore diff --git a/app/https/CustomSSLEngineProvider.scala b/app/https/CustomSSLEngineProvider.scala index 58189c843..2f489c17a 100644 --- a/app/https/CustomSSLEngineProvider.scala +++ b/app/https/CustomSSLEngineProvider.scala @@ -6,10 +6,16 @@ import javax.net.ssl._ import play.core.ApplicationProvider import play.server.api._ +import play.core.server._ -class CustomSSLEngineProvider(appProvider: ApplicationProvider) extends SSLEngineProvider { +class CustomSSLEngineProvider( + serverConfig: ServerConfig, + appProvider: ApplicationProvider +) extends SSLEngineProvider { - val certificateDirectory: String = "scripts" + val certificateDirectory: String = + serverConfig.configuration.getOptional[String]("certificateDirectory").getOrElse( + s"${System.getProperty("user.home")}/.certificates") def readPassword(): Array[Char] = { val passwordPath = FileSystems.getDefault.getPath(certificateDirectory, "password") diff --git a/build.sbt b/build.sbt index 3b4b2da1e..fc578aa5b 100644 --- a/build.sbt +++ b/build.sbt @@ -6,13 +6,15 @@ lazy val one = (project in file("modules/one")).enablePlugins(PlayScala) lazy val two = (project in file("modules/two")).enablePlugins(PlayScala) -lazy val root = (project in file(".")).enablePlugins(PlayScala) +lazy val root = (project in file(".")) + .enablePlugins(PlayScala, PlayAkkaHttp2Support) .aggregate(one, two) .dependsOn(one, two) scalaVersion := "2.12.2" libraryDependencies += ws +libraryDependencies += guice libraryDependencies += "org.scalatestplus.play" %% "scalatestplus-play" % "3.0.0-M3" % Test fork in run := true diff --git a/conf/application.conf b/conf/application.conf index 439598422..b1c0317bf 100644 --- a/conf/application.conf +++ b/conf/application.conf @@ -1,7 +1,13 @@ # See http://www.playframework.com/documentation/latest/ApplicationSecret for more details. -play.http.secret.key="changeme" +play.http.secret.key="my super secret secret" play.http.secret.key=${?APPLICATION_SECRET} play.http.requestHandler = "router.MultiSiteRequestHandler" play.server.https.engineProvider=https.CustomSSLEngineProvider + +play.server.https.port = 9443 + +// Allow example.com and subdomains +play.filters.hosts.allowed = [".example.com"] + diff --git a/conf/generated.keystore b/conf/generated.keystore new file mode 100644 index 0000000000000000000000000000000000000000..93dd45f4b262f6094f4f814106ea796db17928d1 GIT binary patch literal 3174 zcmeH}X*ASrAIE2mVP@>ct}>cLDE}FI_9ZD)7(%iS4Z~o_S}}=`3R%+F%i5wymK!a& zn+auSBqXwjEMpswo^wCXxu3VsdCqy>^x`_#xjyH5@jKu1{r=9EHP4y{fk15kK0^LP z*Dx= zKJm1A1K{C+%g36=uJeGwTu=}Yg5d(-91t6J4kVkAJq8H~{CdEU2%|7Jd?4B1)g6x! z0tA0SP9&EFiR6bebS2|a7>ppm|BE7!a0}PV_&|cY4;dp2Ab&9~B)5$pAqa)TlY%VyWgE>MvF{H>Oo(?InT z+@XSy!^rfKcUo%Ev@wTBLzy%c%?agZ? zQ>uK9-Gpaew$vqlg!k?@8=8GtX)|SiCg4B~Jp*ny%TIJcdgVBMfEtzQh?pouigWAb z5pvI+S8HzZj8?{^0=)Q|_oFjWBG<{Mob?k6)Pq8fpX8~^PLaOTd1ZI@%bc$R_|ayR zM43O-E#(sQH9RG5EQWzIZ;;zdDHz1_9|`>{noJM~3I-_bI{+^SLV*L!4wh#V0Pi`A zox(ny-Pjgx&Nq;^oo4t)yxDe+gPm^>E0n6&Y^PByW?o)UbPwrtO{28c7NVSqL%=cz zQ=d)7@Mo9l7&Wfw@$4F*v0X`Htm(u326XAS^v4Xp*B%Hv+iYadO4HoD30AK@*FSR-G9tD; zzu6WmkU=fpEDCh4dP-2+B|*z^p$8SmK36&qD}r+=s){=g?~88DGuryLJTNztdvBX3 z?$mjiXNWsw084_L;^Fi`=lQhyj3VZ(eyXJUlQ}g`@0bbZiEa0Y=%Eo7mD@vQV#~j< zs}Hsj3hZ`hG`4s;Ji4px>C0TDeJ>0d;VZi`dI;s@%fVlPTb-cK5ImuQ^cz2qw3RW< zzQ*On4I0KJt?8?rJ#}hMB&)^x`u?Aa=?gU*QK#*WCOIiAi&u5BfA%qVBo|+C3NeAs ze{~b*?-|J}b*Bq6c>-ucvR1+ZZ5ENrR>XNUyyAf4N!bs5L@{_ri}IN%w-m*a*|LE& z7bs)P+OOAvsumY@7^e|Y!fBm9mCJ_^$n)}5S(m=wkY4hNhw&^^`w@ZuMl`&*Skj3R zVzT&iwoZcMBqEP;=wha{ocHHo1NG_E_=a=UAcDg8(-QpU`U2DDWC(Ii#DwHfzxXh{ zzH9r%5;y80_LHgZ`+WSs%yLf3PoduAwehT}(x5nW^eHq!vsgmln5QK$s34t3y?@(Q zOFs)ywc6iJNlLbnv>TwH7%OUZV@EeJs7c)M&iz;~qv*HqGz%_=JYQHjlHyeup+H={ zgKIv)QOqS*(lh<1b=?)rg)+@yl7Y;ik8whCyI3qFiWAKP9e&T{j(v3#SZ4_8cgH*F z&nZ+Ii@#4ylG)UYtO@6mAo$T`vPfY$R;H6w%A>JmK6|$Cqi@r*6Ud zoroy^=;aZ4f1_?6t<8NQQJwsP#;oj z`G(r9Hz6qX?iH&ms`&Y}i)jY=NiEJ+`c`Eh?e8(=z%WWg{=uDwub;U)j>;6Uhk8wCNFVEDn0Pj3uD zfJ;^Fl@8NrvFFM@ScZkVx0I>8&f1>YrP{d-<*zMbYhPHWIB#?<%R zj)&IP25JCz8T95;|AYk>X-KE!T%voIXH-ktPHDlHxrA&lVnjpwRTLwQPjb?Q>BVfi zkYJ>CJ5iNcub9YS(G5Cw7Q5G;MkUWB)HY>p)?B3N7j>-PW$4-HCW0#v6l@{lC`Z(# z+tupE$73wJAE#*y_+C99`fTOnNZPG0`w}!Z_+ZU`(KeW@$_ui3^n%_-2Q=Bb+Zu$z zy-^H@X-AT@ZMofQHY#!4A@_8Z{JL|5mk3WD=(_5ednh#+38uiBn5-E@E5hKhkJJ30 zhSz_56MT-VRFD1Ve*E20{ulM>cSrf%QU0rrqH}uO@!JRiO9+uoh2g*7-ad_i{R28X BK2iVx literal 0 HcmV?d00001 diff --git a/play b/play index c7a5acf11..b6cc9ebfb 100755 --- a/play +++ b/play @@ -2,6 +2,8 @@ SBT=sbt +DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" + # Export the keystore password for use in ws.conf export KEY_PASSWORD=`cat scripts/password` @@ -58,5 +60,11 @@ JVM_OPTIONS="$JVM_OPTIONS -Dsun.security.ssl.allowLegacyHelloMessages=false" # http://docs.oracle.com/javase/8/docs/technotes/guides/security/troubleshooting-security.html #JVM_OPTIONS="$JVM_OPTIONS -Djava.security.debug=certpath:x509:ocsp" -# Run Play -$SBT $JVM_OPTIONS -Dkey.password=$KEY_PASSWORD $*; +JVM_OPTIONS="$JVM_OPTIONS -Dkey.password=$KEY_PASSWORD" +JVM_OPTIONS="$JVM_OPTIONS -DcertificateDirectory=$DIR/scripts" + +AGENT=$DIR/target/universal/stage/jetty-alpn-agent/jetty-alpn-agent-2.0.6.jar + + +# Run Play (this should work for both run and start). +SBT_OPTS=-javaagent:$AGENT $SBT $JVM_OPTIONS "$* $JVM_OPTIONS"; diff --git a/project/plugins.sbt b/project/plugins.sbt index d87690a00..fa74539dd 100644 --- a/project/plugins.sbt +++ b/project/plugins.sbt @@ -1,5 +1,5 @@ resolvers += "Typesafe repository" at "http://repo.typesafe.com/typesafe/releases/" // The Play plugin -addSbtPlugin("com.typesafe.play" % "sbt-plugin" % "2.6.0-M5") +addSbtPlugin("com.typesafe.play" % "sbt-plugin" % "2.6.0-RC2") diff --git a/scripts/client.crt b/scripts/client.crt index 1b854090d..7f4c6449f 100644 --- a/scripts/client.crt +++ b/scripts/client.crt @@ -1,15 +1,15 @@ -----BEGIN CERTIFICATE----- -MIICRjCCAemgAwIBAgIEUuaIDjAMBggqhkjOPQQDAgUAMH0xCzAJBgNVBAYTAlVT -MRMwEQYDVQQIEwpDYWxpZm9ybmlhMRYwFAYDVQQHEw1TYW4gRnJhbmNpc2NvMRgw -FgYDVQQKEw9FeGFtcGxlIENvbXBhbnkxFDASBgNVBAsTC0V4YW1wbGUgT3JnMREw -DwYDVQQDEwhjbGllbnRjYTAeFw0xNzAyMjgyMjQzNTJaFw0xNzA1MjkyMjQzNTJa -MHsxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpDYWxpZm9ybmlhMRYwFAYDVQQHEw1T -YW4gRnJhbmNpc2NvMRgwFgYDVQQKEw9FeGFtcGxlIENvbXBhbnkxFDASBgNVBAsT -C0V4YW1wbGUgT3JnMQ8wDQYDVQQDEwZjbGllbnQwWTATBgcqhkjOPQIBBggqhkjO -PQMBBwNCAATU4DEAlfPWUt8ZxWkr7gX2dfWZ2bVYZr7xpSnuMbMzlrrwZ33hgn0s -y3Af7Zz3MchcB+I3+0JMSMkDF8K+p8Dgo1cwVTAfBgNVHSMEGDAWgBR8rEH7EEB+ -/ANuFJxkw10sgb2zAzATBgNVHSUEDDAKBggrBgEFBQcDAjAdBgNVHQ4EFgQUykKg -340VBk9CA8IKVKuoPaR5wl4wDAYIKoZIzj0EAwIFAANJADBGAiEApuSZvFIFl5Hb -N02c2HCtCvCVz81rvydpzgTMFH1O39wCIQCtwBwD9eFmyddU3I+QThgZwLMtn5lD -KiAp8qa7GLyQXQ== +MIICRDCCAemgAwIBAgIEVqbcQDAMBggqhkjOPQQDAgUAMH0xCzAJBgNVBAYTAlVT +MRMwEQYDVQQIEwpDYWxpZm9ybmlhMRYwFAYDVQQHEw1TYW4gRnJhbmNpc2NvMRgw +FgYDVQQKEw9FeGFtcGxlIENvbXBhbnkxFDASBgNVBAsTC0V4YW1wbGUgT3JnMREw +DwYDVQQDEwhjbGllbnRjYTAeFw0xNzA1MTUyMjM3NDdaFw0xNzA4MTMyMjM3NDda +MHsxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpDYWxpZm9ybmlhMRYwFAYDVQQHEw1T +YW4gRnJhbmNpc2NvMRgwFgYDVQQKEw9FeGFtcGxlIENvbXBhbnkxFDASBgNVBAsT +C0V4YW1wbGUgT3JnMQ8wDQYDVQQDEwZjbGllbnQwWTATBgcqhkjOPQIBBggqhkjO +PQMBBwNCAARh71b26sowwQlM/QCtf4Y5BToNK6n30S1svC7ioWJ+AAFboXCRYDEf ++BZGp6dQS1etQ/vOR2TzzmFZG+MKjg01o1cwVTAfBgNVHSMEGDAWgBThwmvBKWRp +WYoNKq81VlbKQsXimjATBgNVHSUEDDAKBggrBgEFBQcDAjAdBgNVHQ4EFgQU7gPg +IgBDQ/MjwXu7n0OHyy/8O1owDAYIKoZIzj0EAwIFAANHADBEAiAdOv9CXQmlFXk7 +lvWadUZREpYXoGI9Wv+0f2xosNBoOgIgBrtFjU1C/+WzemVkq3Zd6iGDqu2nYh15 +DCwZX+6a+xU= -----END CERTIFICATE----- diff --git a/scripts/client.csr b/scripts/client.csr index 1eb22f699..26e24a411 100644 --- a/scripts/client.csr +++ b/scripts/client.csr @@ -1,10 +1,10 @@ -----BEGIN NEW CERTIFICATE REQUEST----- -MIIBajCCAQ0CAQAwezELMAkGA1UEBhMCVVMxEzARBgNVBAgTCkNhbGlmb3JuaWEx -FjAUBgNVBAcTDVNhbiBGcmFuY2lzY28xGDAWBgNVBAoTD0V4YW1wbGUgQ29tcGFu -eTEUMBIGA1UECxMLRXhhbXBsZSBPcmcxDzANBgNVBAMTBmNsaWVudDBZMBMGByqG -SM49AgEGCCqGSM49AwEHA0IABNTgMQCV89ZS3xnFaSvuBfZ19ZnZtVhmvvGlKe4x -szOWuvBnfeGCfSzLcB/tnPcxyFwH4jf7QkxIyQMXwr6nwOCgMDAuBgkqhkiG9w0B -CQ4xITAfMB0GA1UdDgQWBBTKQqDfjRUGT0IDwgpUq6g9pHnCXjAMBggqhkjOPQQD -AgUAA0kAMEYCIQCpWSYpcJB6CGHMCxUCFCUQwx7cUNVETIzCpcndM9TRBAIhAJzc -mjywUYOq2qw0QuQCSQ3eBQE5IRuFW48ULk6eosiB +MIIBaTCCAQ0CAQAwezELMAkGA1UEBhMCVVMxEzARBgNVBAgTCkNhbGlmb3JuaWEx +FjAUBgNVBAcTDVNhbiBGcmFuY2lzY28xGDAWBgNVBAoTD0V4YW1wbGUgQ29tcGFu +eTEUMBIGA1UECxMLRXhhbXBsZSBPcmcxDzANBgNVBAMTBmNsaWVudDBZMBMGByqG +SM49AgEGCCqGSM49AwEHA0IABGHvVvbqyjDBCUz9AK1/hjkFOg0rqffRLWy8LuKh +Yn4AAVuhcJFgMR/4Fkanp1BLV61D+85HZPPOYVkb4wqODTWgMDAuBgkqhkiG9w0B +CQ4xITAfMB0GA1UdDgQWBBTuA+AiAEND8yPBe7ufQ4fLL/w7WjAMBggqhkjOPQQD +AgUAA0gAMEUCIQD9vno2Zg4yLOnkOQSL9t6tmiDfMibsKqOci0eZnCmMDAIgQ2Dq +fIMR+S8e8i2FTE1hnarbjWkcJVoo9u1jgK9EdCo= -----END NEW CERTIFICATE REQUEST----- diff --git a/scripts/client.jks b/scripts/client.jks index 1222e2eab33a193028eacc1b27b9da0d317aaf65..3f20d5c98c2cd97b81280fb15bd19c8cfa9d5336 100644 GIT binary patch literal 2095 zcmezO_TO6u1_mZ5W@O+<&dE&8D@jgdU|@{lbDF;oC{u4xYrx0GrOn33!l=b0$jHdb zz>*z$^WCb2FI3Cq{C(Y}iqy_FE7?cM?z}BmR_&R*ESjq+x7GOMgWnpx%zI<+Zc3?2 z4Y-%S(#pc%Sh8)xTh^GxLRK?QBwNWyY{>Ioa=E8E$jPCT|8t1X(o41r_b#-UI7KA+ zOwN^wBKTsATqJFmPj1WSEih*1pr~Zi|`RwO2Q7T$m5;xpQuM z{tAAlr@yW5>~RbODp|_2VS=pCVm-sdOoy9|4l($gtX>>`Zq5EVPN7VJ)*M3MRKx~J z-jKw-q#IY_{`tmb!xpQyg35>5<#`5gq#FhM&n{jq^uXHYKy1ZO=ewV$SQcYV$-kG^%{y_?$lQ(DVp zEOzr|alAXm@c8}SH^Tl~RsfyAgh<>Tz{KqWOx!P_i92lB9S7798R*o5nz+qDiQC-3 z!q6C;*3F{~s_B^b_zid=c@G+`2Dp=U;`^{~uTB{p+O>vO}qDqxwU;yTOKq?i|9!JlT0!R=q5a1xxn_{`x-EUTV^@nDpuAg_xE-6L9bl zZs-hq8ECxpkmmb?^BeB`IQJ`Q%C)y?6RLU&4%S#M7Te<2`gG2^T6gC+Z^L@kHgGRK zGP&Y-`SYYjB5hBAPGDqUjnFeSumn2Q%%F+M$e@Yw+5%=KMkXc}zjQ-810FUGtu~Ky zwk*s{tPBRVhTI06Y|No7Y{E>T!G^*Hf*=luFqd;;PG(wuQC?=Ep_qXPNRVBaH#jj* z!L2AUFFCU~Ip0viKnx_#CCu+yk(gVMld9mHpIeZaS7|6>AOw=(7UqV@_!p%c3L5Z( zM45%*A!i^b&TD9HU}R)rWMpD&Y7_bK{Zgm1mvocbpzmV0(vz0d>q^jw+DAki6D{9a4G$T6t@(jFk`yOQ^&)%~x(Z*N@v zU8PJc-|3}&2bX#7VkZL!aB#>9Gcx{XVKra|Qoy9c94gBX5&*^y6N`Z?h|k9&#v)R) z#__j+L){7iw;(7{^3lUG#_IpV?;_9FWcbO}rfXRLnEbvgs9U-jp#*5fzeg=9Twv>M<}*;gJIGEDt^E$F`F(M;`ktlvt%&b+xbB5mKtrJC;yHycme z^&!3XVNqw;bG{p%h+%(Z{@cmN<0P~Ap?%8_JXjoV5NaR~O1R1_z!IVXd(ssK zDNtqMG2mk30G5`ltnAE8NXh+_(}MfGqHO+7%!jx_R67SKqYGr$S{9>n0E4d$esQPeiD)g zHtWux>8z!o`Dxj1i9Hiy5s7NFz@)G|$DOQ(bAkEN|3$#bJ!f{Bec~2N^10zX^`wI= E0HuU_6aWAK diff --git a/scripts/client.p12 b/scripts/client.p12 index 5e1b28d4764d2dd64170fce4df1b2eb56ff354b2..d2249a973079f22f47ef6b2b6a1d5da0bc59ed9e 100644 GIT binary patch delta 910 zcmV;919AM#2+atPUt+)(xjL17chrL+`PjL;p(1I<5&4jQ<h64?0B z=6#_b!pVv8Umz^a2)~Go3&Y0I3AjSBlTz2-)sRF2vq9o~BRQw34}#4e{nE8-cmRff z{y-~--K>`{VkQm-*}X4*u>j{c{Ekx*%KBmzEqVX8U{}XNn7DuS*EFfn5~Yf*k6>;KYPp&3^>l@(TRD`4vORigG~q$ zwY~1;M>p>8eZ=o9?75e+^AFM7LvPsKvdC;7#gKD)!Fn%v%szX4FCcg8A%U|?X*idEIsLem zw5cC2uqb%?cOoB3f{Xh|I9JE8ug~2xr$>wfH>Py`Hwi1t#S_3>D#pt&^ghn6F!VlF zOhAaao9|3;IznJ5h+s{6AjE8=Qrk$ zh*{+WcU@?es@w=n5)mS!_=!E?r~;MT96K*=7ltGb@EC+*muuFelhtrS!^ve0KFqjJ zai+*q(+cfA+xK+*U#!wwz!i9_9!xI^jW{#4|FaTj`zfO&PROzjVwIJD*Eq75CQX>H zKU++e%HiT8vykh_8Gr*zk7gHOQJlCm2epxvaDKv zcK?x!6VM+8@Y7v-7~SMclIUo5g2iGWYe{SYV1ZlKPIQ_(n_1nZtr0Y@EnTFQwq$n; z;|pjrx#9~%(GZ-1^sCkLdk}>I%=4h@4hVzoUYf7`T;7=}8;9b0uxVn$JKz$il3ghU z!rD!-ss2Hh|Kd>x!xZPh)BtgYsekH!vNYD>mQibU%Q7FEZ+%>3AaJeTp{VCe&3N>A z!bTS>-2U12EAQ*yQhOW6`9;pa$=+HHFuEq?0=D)eB7&{-C$lCrm$euX|7M2sh;sxe z+*^DZGhV~diZZY9Vz8nE8f7%?cU1;yRapqNTZa8RAz;8)@D?$Hx?SlF_+)c`Xu`7c zuDGO>2Dlpta;4F1bUR3_Gj#&8?|=uMyM}IC#U_!VJo+DI`^COmWdpQ=MZ6_i6OnMHbx89{(S>!1wx*@A*TrY1s z<>7)J!+6S^P<14zuJ!W%5&x>PLSIN zv;w;q+@m(2P;~=&s5OkMV-r@ZL|OyQP-dBnj# kKgQe?yhQ{QxE8*?boAE|Tn^+REvly_0J!eA?f?J) diff --git a/scripts/clientca.crt b/scripts/clientca.crt index 5a5fbda94..cc72d62f2 100644 --- a/scripts/clientca.crt +++ b/scripts/clientca.crt @@ -1,14 +1,14 @@ -----BEGIN CERTIFICATE----- -MIICMjCCAdagAwIBAgIETmcxPjAMBggqhkjOPQQDAgUAMH0xCzAJBgNVBAYTAlVT -MRMwEQYDVQQIEwpDYWxpZm9ybmlhMRYwFAYDVQQHEw1TYW4gRnJhbmNpc2NvMRgw -FgYDVQQKEw9FeGFtcGxlIENvbXBhbnkxFDASBgNVBAsTC0V4YW1wbGUgT3JnMREw -DwYDVQQDEwhjbGllbnRjYTAeFw0xNzAyMjgyMjQzNTJaFw0xODAyMjgyMjQzNTJa -MH0xCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpDYWxpZm9ybmlhMRYwFAYDVQQHEw1T -YW4gRnJhbmNpc2NvMRgwFgYDVQQKEw9FeGFtcGxlIENvbXBhbnkxFDASBgNVBAsT -C0V4YW1wbGUgT3JnMREwDwYDVQQDEwhjbGllbnRjYTBZMBMGByqGSM49AgEGCCqG -SM49AwEHA0IABIJbZqvtzgIT2umzZfxiXQubhn8S4EdnbRxpUhWY1E7rGehsMH/0 -h1AZTakN2Trf9fvbsav3JHYWb0LpP4gKN22jQjBAMA8GA1UdEwEB/wQFMAMBAf8w -DgYDVR0PAQH/BAQDAgIEMB0GA1UdDgQWBBR8rEH7EEB+/ANuFJxkw10sgb2zAzAM -BggqhkjOPQQDAgUAA0gAMEUCIQDpmKZDBpR20016RAbrV6sHJdnEZqlD+SSqozsq -OLpNZgIgD0YoaJX/6nXlxPn+kV0NU2FBt/mAhe6LRnIyc05zo60= +MIICMzCCAdagAwIBAgIETDDZTTAMBggqhkjOPQQDAgUAMH0xCzAJBgNVBAYTAlVT +MRMwEQYDVQQIEwpDYWxpZm9ybmlhMRYwFAYDVQQHEw1TYW4gRnJhbmNpc2NvMRgw +FgYDVQQKEw9FeGFtcGxlIENvbXBhbnkxFDASBgNVBAsTC0V4YW1wbGUgT3JnMREw +DwYDVQQDEwhjbGllbnRjYTAeFw0xNzA1MTUyMjM3NDZaFw0xODA1MTUyMjM3NDZa +MH0xCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpDYWxpZm9ybmlhMRYwFAYDVQQHEw1T +YW4gRnJhbmNpc2NvMRgwFgYDVQQKEw9FeGFtcGxlIENvbXBhbnkxFDASBgNVBAsT +C0V4YW1wbGUgT3JnMREwDwYDVQQDEwhjbGllbnRjYTBZMBMGByqGSM49AgEGCCqG +SM49AwEHA0IABJM+XXbDImvSMpxwx0Dwr9rR6BvEFHYRahuKlIa5HxC3WGT27wzH +XWO9HtCBHYyxfz1NnJRQIAQ9/yQ5o7oj+aGjQjBAMA8GA1UdEwEB/wQFMAMBAf8w +DgYDVR0PAQH/BAQDAgIEMB0GA1UdDgQWBBThwmvBKWRpWYoNKq81VlbKQsXimjAM +BggqhkjOPQQDAgUAA0kAMEYCIQCYaO0/iTrdhDYe1urZPEQDwbzczpdvqA9C5fs7 +3LxBVgIhAKUMsJAdEqMuMcMCw4MywgBMyXujV86sv5xCVQJROwgS -----END CERTIFICATE----- diff --git a/scripts/clientca.jks b/scripts/clientca.jks index 4beaa2b3cd530af182531a0a16a718133cbdb37b..f305399bb304742177dd1bc3f0de7f68d71c4eb6 100644 GIT binary patch delta 278 zcmey)@`Gi9ta1#W)3W~ztPy&q29^vAOy&knOvVOHjMo-0GchtTvG^F=^quH1MbgyJ z)X2!#+{7$OoY&C80KuK;*DyJkQOaSmU2NH5rR+;aa|(_-d{}?$;tS~`B4vVE(p^*9 zcFGHEk4X9Up67UM@?Nur7KObJk6vHh=NxpEs@z%c6>TZjf+_hIXZCscS z?zwYrdj1N2r>DQI@9c3511ed{vtfd)&|*Eq!%T;pjSeyRoUC3Pes0bFIZmNWfz}*C atikRx(u(wqSKD;;-z_Kz{rKZWNqk!(A+ay|V)_3Fhv3(0O^>fLk5&~(@lCr z2J2U=2PN6WW~oE@B&wr3Dmc1LW&$7&Mkr{N|LS$+#QFY_T@6!VLAUvUh3<<+ax!yH bbEB>1|BB!iroX%>ZTto4Sqn4n_y+-XtqpBU diff --git a/scripts/example.com.crt b/scripts/example.com.crt index c9efa5b14..494fd89b4 100644 --- a/scripts/example.com.crt +++ b/scripts/example.com.crt @@ -1,16 +1,16 @@ -----BEGIN CERTIFICATE----- -MIICdDCCAhigAwIBAgIEHb7/hTAMBggqhkjOPQQDAgUAMH4xCzAJBgNVBAYTAlVT -MRMwEQYDVQQIEwpDYWxpZm9ybmlhMRYwFAYDVQQHEw1TYW4gRnJhbmNpc2NvMRgw -FgYDVQQKEw9FeGFtcGxlIENvbXBhbnkxFDASBgNVBAsTC0V4YW1wbGUgT3JnMRIw -EAYDVQQDEwlleGFtcGxlQ0EwHhcNMTcwMjI4MjI0MzUzWhcNMTcwNTI5MjI0MzUz -WjCBgDELMAkGA1UEBhMCVVMxEzARBgNVBAgTCkNhbGlmb3JuaWExFjAUBgNVBAcT -DVNhbiBGcmFuY2lzY28xGDAWBgNVBAoTD0V4YW1wbGUgQ29tcGFueTEUMBIGA1UE -CxMLRXhhbXBsZSBPcmcxFDASBgNVBAMTC2V4YW1wbGUuY29tMFkwEwYHKoZIzj0C -AQYIKoZIzj0DAQcDQgAEgkS809VXcPuYK/vyigcJk9MChmHUs4L20ca0p1Ag4yAG -T7Qq4ifAmo9QI4UWujst76LUMZaoisc6j5OKHCEmNqN/MH0wHwYDVR0jBBgwFoAU -n5szvZjetSdYVfTLHovZZHH6VSswEwYDVR0lBAwwCgYIKwYBBQUHAwEwDgYDVR0P -AQH/BAQDAgWgMBYGA1UdEQQPMA2CC2V4YW1wbGUuY29tMB0GA1UdDgQWBBSK1EjW -tdm2w5vsKaNx1WcLEAdUHTAMBggqhkjOPQQDAgUAA0gAMEUCIGEPSLZsSKnHcUZJ -Rev0ygGm0sqqUGSna4TxATI+gjNaAiEAjKXwPKtaAZiULhqEzHSd770d/9kLMXqx -zAhzew2qmHk= +MIICdTCCAhigAwIBAgIEOJ/28jAMBggqhkjOPQQDAgUAMH4xCzAJBgNVBAYTAlVT +MRMwEQYDVQQIEwpDYWxpZm9ybmlhMRYwFAYDVQQHEw1TYW4gRnJhbmNpc2NvMRgw +FgYDVQQKEw9FeGFtcGxlIENvbXBhbnkxFDASBgNVBAsTC0V4YW1wbGUgT3JnMRIw +EAYDVQQDEwlleGFtcGxlQ0EwHhcNMTcwNTE1MjIzNzQ5WhcNMTcwODEzMjIzNzQ5 +WjCBgDELMAkGA1UEBhMCVVMxEzARBgNVBAgTCkNhbGlmb3JuaWExFjAUBgNVBAcT +DVNhbiBGcmFuY2lzY28xGDAWBgNVBAoTD0V4YW1wbGUgQ29tcGFueTEUMBIGA1UE +CxMLRXhhbXBsZSBPcmcxFDASBgNVBAMTC2V4YW1wbGUuY29tMFkwEwYHKoZIzj0C +AQYIKoZIzj0DAQcDQgAE7PPEtVsncwXW+yNlmZCAvrNTE7bMubT343EALhsPmMdA +13BJDQzWS7zz0T0MDXMo17DihVnNmdgWPy9i0TWbFqN/MH0wHwYDVR0jBBgwFoAU +g1rizzgfrwDupFcJWbVJIQoCXpcwEwYDVR0lBAwwCgYIKwYBBQUHAwEwDgYDVR0P +AQH/BAQDAgWgMBYGA1UdEQQPMA2CC2V4YW1wbGUuY29tMB0GA1UdDgQWBBSn33o8 +3YeRft+b6U+PDFoL36RHxTAMBggqhkjOPQQDAgUAA0kAMEYCIQDFC/Wxt++NbUIf +AvRzObu7/o3hujEEPgh2z5lJN4y/dgIhAJDFCDLiONEt7W3KhOst6mMcC6RoU/Ud +iK2xvfVg9jDY -----END CERTIFICATE----- diff --git a/scripts/example.com.csr b/scripts/example.com.csr index 470641077..93aa4a099 100644 --- a/scripts/example.com.csr +++ b/scripts/example.com.csr @@ -1,10 +1,10 @@ -----BEGIN NEW CERTIFICATE REQUEST----- -MIIBbzCCARMCAQAwgYAxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpDYWxpZm9ybmlh -MRYwFAYDVQQHEw1TYW4gRnJhbmNpc2NvMRgwFgYDVQQKEw9FeGFtcGxlIENvbXBh -bnkxFDASBgNVBAsTC0V4YW1wbGUgT3JnMRQwEgYDVQQDEwtleGFtcGxlLmNvbTBZ -MBMGByqGSM49AgEGCCqGSM49AwEHA0IABIJEvNPVV3D7mCv78ooHCZPTAoZh1LOC -9tHGtKdQIOMgBk+0KuInwJqPUCOFFro7Le+i1DGWqIrHOo+TihwhJjagMDAuBgkq -hkiG9w0BCQ4xITAfMB0GA1UdDgQWBBSK1EjWtdm2w5vsKaNx1WcLEAdUHTAMBggq -hkjOPQQDAgUAA0gAMEUCIAEqF/xfWjrdPkAhVkKfI9UNJxQ1F6aKT5vpbbm7Sv1P -AiEAwLL6Vo5dWvy3wXyKflVE4T5uHGSBfenCTp78iQmm2xI= +MIIBbzCCARMCAQAwgYAxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpDYWxpZm9ybmlh +MRYwFAYDVQQHEw1TYW4gRnJhbmNpc2NvMRgwFgYDVQQKEw9FeGFtcGxlIENvbXBh +bnkxFDASBgNVBAsTC0V4YW1wbGUgT3JnMRQwEgYDVQQDEwtleGFtcGxlLmNvbTBZ +MBMGByqGSM49AgEGCCqGSM49AwEHA0IABOzzxLVbJ3MF1vsjZZmQgL6zUxO2zLm0 +9+NxAC4bD5jHQNdwSQ0M1ku889E9DA1zKNew4oVZzZnYFj8vYtE1mxagMDAuBgkq +hkiG9w0BCQ4xITAfMB0GA1UdDgQWBBSn33o83YeRft+b6U+PDFoL36RHxTAMBggq +hkjOPQQDAgUAA0gAMEUCIQDbXG6NC9EXlqhwKaPojo18HCHW8yzAIIkr3mtBXkMg +NwIgZIA0rW1olt0f/9loAc1Oatr1uHZ70qKbeJuTyAqBPuM= -----END NEW CERTIFICATE REQUEST----- diff --git a/scripts/example.com.jks b/scripts/example.com.jks index f9832101e4a0b9ae94020abe31f9254870065bf9..ae1c520221dbeedd42eb8a870c1ec43f543d8218 100644 GIT binary patch literal 6175 zcmeH~dpMNa9>-_i8Dkh@m~qCP!KR%y)?jiiw{qDbZH-$@O+!%((YUlF_c|^$q9TQ} zQ@Xk3vfV;WN*)UBP^r*mhaEyWskGlIotirJPo3&{jz88j&syt!o_DR^`poCM-kFCp z4-p6i1UDhLArVqxe*WGpX0W%mPdGCm$lphs6&L_dc#2zAkHJrD16zSOMsxuNiAHKd zl1QWw0=*GqpawZtt=2nQ?7wd?ke6fXAnTVuLln~xSD4qbM3uQ2T2+7(zNvR+@r&j^ zC4J9&swW*TD|tk#wjgMf+?l+YN!jmsYhJ&17ZtAnske z?+d2yZ#_ZB#^qSQTC9+pHVqiT%U%m&AqL!_JQRe4AT&{i6AQ#JSj|M+ON-DbNC*L< zs5l^kLDA6|5=3{Vl7J+?gC&VtG5!741qQSIm{c;5;tvXw@XkyYDX8DD%0;w{9 z%pVse5thC#2E{5cAc)D1ph^KEe+Eawy_s1ayq-z~68upVNo2NoRu(`>8c#IZ^>+z~` z!&9dxr#kSa^j<>8}hJ*MX*uFo(#apiG) ze4>HG_@VW{2Pnf;QB*_2<&2h!^BA~ns9cN~$#)fTudq`Qg&6zbx5E#pqs4$I1`DGl zBqWSN!kEE>1SIk$ntzgcK#|`UN0ZS~81hV=jo~HMnSOd43ka?+Z448VsAhJ}}ZX;==}a zzxnz;&RKS_S2>lL1{}n?4bD(SxU0ok1oYHxm`-ObU3Hi%z1XZ>B z_P@TIahYLFil0uMe>&WEVSH|jtS~C0w$aTHowXANUW04p>g?LoSD<>z)o9t_lYVknp6#!D)UEN@wtaxWwF;IKc) zOK%sEo5TcPu9vf;4{^-ZM|Mui%`k@tC>aU4o-RWP;Uc7S_8MBWdQfSt=x|Bn0p=NF z9|&hVcCV(A!q7;U|vY2#qaZiAcZtZ7$TjZ6#vxxRT;3tn7-fN5y}Hf{V@H0|t7 z97THngg;?h1+G#I&(px9R--oAMk3p~dn2L$R+sYzv(Y2{FFGowvTvk?YBV2z*=K$y zY>}^vr`zpBtD(+|bOgP52vMrJvY4-Jd-Cuc zSaV=~HdsgmVRKmEhhbjP{;@C*UNHU~a1n(hCjIY!d@*lz4S1^Bzb$D>W@FN*6iGm4TOyB47GwI z39h^Kfn-F_qYIs0qveBVc)YPw{~lTK=`bfEe#j8C_IDQMRKYN(ezP!t?}R@Q=FVd) zD%>k`=_b=Fw~bN?y5&=b%h*%M9%WUEZj$TK$Ql!5o=2<2)=~;~#G-Ii>a0uUSn5L! za>T;w=4JQlv;Jpc{{9x;hI!+Yb#C+5R?SEWxz1TZEZ&6qX;bl|kUgC= z4-*PZ`X3OpM)&`-SP9SDo2t|1v1e~19OkjkD>DbfWMAa>i3_C|@7#V$CP$p7-7K9p ne9-CSC7Xgd=gv9z^PEcy-d*=VjXdgAJ935G(xMa5)b{*up%e4H literal 6174 zcmezO_TO6u1_mY|W(8tK29fg2oRs9mq7=Qa!#dDz;UaWcc#{y?tIG|dCF$v87{?7 z|GXWz1w$&Ye=l3JrtAsBjw^e9{Jwa9q28soP@%s`N|$B*rf)7w6kVbHXR@Vk)1LOw z&-Q!Yacuc+=o?XUQP!zR`KPRf%I)69nPA7VM(CLuSOT4$Y|z9M55!Chn3))vm{^MR zD|ife*f_M>JkHs&Ff*|-7}ObZ8*s8QhqABjhgSS2c|S*gC@os(A4JJaUmPk+Ci4u41uZ5#Kged&=j2745J3zeYg{v zC9iyZe!%Y&=bHXl=iRBRt-K;>Un?!tdm%nFhtFgErYiURJwF6K7@fI!XnCZ>g!b>o z!TPN|m*h@nTd1G>S@UGElYxT)KPZU^gOUuZ0W*+7O+!p9NNEUbIz%ZtnB5r+T$mI* zxfX>@+tPczQSEu-$!ls)4nB&X_0aU6)Xy6&I^HYp-e*#yyYggN? z?fdQ@>3+$7e%t$s@>gaISHT4Bi*KF0qa#@+WOA5g#iJTk#W@=v?-O}rZaDRzCV%<; zqJDqheGiN$tX=qg=Z3}NO@|+ESQl#izV|@*)yn>dOWam#25&|!Pb+{ayab3PpebB- z-~ZM@ox+V#%TwbhgT@9rmZ#8afLRzhcJY*^O)h&bUkxw#JwyBVr!IER$(Nbh60dA- z`gZZymgNBoj}_Sbw`e_5KQOC5K)F?Hm$mNuMOO@`t>`*#)jzpQMp4adF{t{bPH76N z*<=M-_zifQP#ljaWxK9;T-$nc+u_-7G#3|MP3IP150OPp49p%32ChsBiTobhay(WZ zFLd*Cef{MWC?$4KKl+g?CZI;eD&!i%l)VA zsrmimrpd~EZZj^hJv#q)O5>xqrEZ*`-4o6>?EW<;=UR?`BL`#Sl|{4UPz%~-U?E!% z#7fYDHu}&(bJV;w;8ith!_@?}pfv#&v@LWjXrV1}W?}Rg##7h^PBVU}`pVOA!er+# zriVv=DlITNV4?DIJHz9gfV=Nk`YqAeU~oy>^6*}P=YcAda;MdA(3^8D&E@Ku#(Q6s z3ol<@+}L8!*hr<~Rti$w0=pkg7+ydWxqL!`v+v8OfBNFRrz`gFteR~isd@A8MD-2v9UnqjKd+pxbQ@UaE=qAp5J>J?A{vp-ldyN+ zp_Hi|t2S#NiFqJYucvRN>oZ#Bj+VI;H*A?0V13=>L`Z4->i1~E8ckRfCoDz={*v;1 z%*y=zAzYRD|Fst~?Cm!n{Z{YI?7A_2w#y%%d#CQs`!wy#0kaz~#m;MJzFU@2TI|%; z?(XB(8gb~zbfpyS=esAp7MSpS)sZGvDU)C8SW`~ki&oRQ`Q6NByQ=(oiOIjB`jg*W zTetn0_rZjf7qYYF7w_+8>_V-~n}8L09a3dp6Q3J~T56A0=E%cjh{_x-hVfM9O@d4Q za^;_&VY9kMa=($mOpn7Cr-s$!on9AnzPjzfZ}X3)s&>wLH#BCc?>n$$uDM|EE-$?W zSG$b#c=@i#*gp@WS!Isy1w>^&af)9_bhyCYsi$Ahnz54eVaby_KT(qfr2nMI(6Bx- zJoBdf>x#2)1vgtr39mhzH=QfUvhCJ9X72V0b6S}cisDY3W#(GEmZPlrb(#I)TTD$S vTebdf^%R-1E-ieMF#BkcJ6hyYR^-0;lJ)atz%=>RYF6pg1L~d=3XD?#oQh7> diff --git a/scripts/exampleca.crt b/scripts/exampleca.crt index c01eed0cb..b6d934bda 100644 --- a/scripts/exampleca.crt +++ b/scripts/exampleca.crt @@ -1,14 +1,14 @@ -----BEGIN CERTIFICATE----- -MIICMzCCAdigAwIBAgIETYjQazAMBggqhkjOPQQDAgUAMH4xCzAJBgNVBAYTAlVT -MRMwEQYDVQQIEwpDYWxpZm9ybmlhMRYwFAYDVQQHEw1TYW4gRnJhbmNpc2NvMRgw -FgYDVQQKEw9FeGFtcGxlIENvbXBhbnkxFDASBgNVBAsTC0V4YW1wbGUgT3JnMRIw -EAYDVQQDEwlleGFtcGxlQ0EwHhcNMTcwMjI4MjI0MzUxWhcNNDQwNzE1MjI0MzUx -WjB+MQswCQYDVQQGEwJVUzETMBEGA1UECBMKQ2FsaWZvcm5pYTEWMBQGA1UEBxMN -U2FuIEZyYW5jaXNjbzEYMBYGA1UEChMPRXhhbXBsZSBDb21wYW55MRQwEgYDVQQL -EwtFeGFtcGxlIE9yZzESMBAGA1UEAxMJZXhhbXBsZUNBMFkwEwYHKoZIzj0CAQYI -KoZIzj0DAQcDQgAEOQ0fX29Q+8jOgvw7btx+fXnUGT99GxKN0F9VbA5Ir7J6R2+8 -+BDwMszZwqdZGJCH9zNTL4WM0h7Jazgnyfl85KNCMEAwDwYDVR0TAQH/BAUwAwEB -/zAOBgNVHQ8BAf8EBAMCAgQwHQYDVR0OBBYEFJ+bM72Y3rUnWFX0yx6L2WRx+lUr -MAwGCCqGSM49BAMCBQADRwAwRAIgSQqiVpa0jdeBJueBydYm5MHiX5rhNf4a+diE -LEuo3d8CID4mqFvs9rRAMYAMjztFPbWHvt/Ei+kPz7bveHfqNgDV +MIICMzCCAdigAwIBAgIEcuQ6yjAMBggqhkjOPQQDAgUAMH4xCzAJBgNVBAYTAlVT +MRMwEQYDVQQIEwpDYWxpZm9ybmlhMRYwFAYDVQQHEw1TYW4gRnJhbmNpc2NvMRgw +FgYDVQQKEw9FeGFtcGxlIENvbXBhbnkxFDASBgNVBAsTC0V4YW1wbGUgT3JnMRIw +EAYDVQQDEwlleGFtcGxlQ0EwHhcNMTcwNTE1MjIzNzQ1WhcNNDQwOTI5MjIzNzQ1 +WjB+MQswCQYDVQQGEwJVUzETMBEGA1UECBMKQ2FsaWZvcm5pYTEWMBQGA1UEBxMN +U2FuIEZyYW5jaXNjbzEYMBYGA1UEChMPRXhhbXBsZSBDb21wYW55MRQwEgYDVQQL +EwtFeGFtcGxlIE9yZzESMBAGA1UEAxMJZXhhbXBsZUNBMFkwEwYHKoZIzj0CAQYI +KoZIzj0DAQcDQgAEm3IRkgOLuTi7TZmQOtwY61xLZHQtd6v8nFafk1cV6SAvP3yR +v31JSGrfCYY+jXytuE3NA34cKTlm6rwaGeoP2KNCMEAwDwYDVR0TAQH/BAUwAwEB +/zAOBgNVHQ8BAf8EBAMCAgQwHQYDVR0OBBYEFINa4s84H68A7qRXCVm1SSEKAl6X +MAwGCCqGSM49BAMCBQADRwAwRAIgH2sJj9qZGZ3BUe8cKRfrsdNvOQ1DNcZEG18Y +euKKXYoCIDZGDC98nCQilG5lhm3QYdwUNy1W4NmFv9o7pDRbdaaV -----END CERTIFICATE----- diff --git a/scripts/exampleca.jks b/scripts/exampleca.jks index 042fa6fd54597baa8046319390075662c1dc9641..533b8026e6c027957690dc5d371b99a30886662c 100644 GIT binary patch delta 381 zcmV-@0fPR327m^T9)Da8LY?sd004h5eJ~CN3M&Qy1OX}n5di@O00e7hq}Fvgd`~mD zN{RGG{41IqM~W6%t`Z_QYIL4&5)~o}z|W}c$@SZ3T&@AXs5xv+Nbw?!DKm5Y*YElhX9QSdnmLEBMFfb(`OB~6}C8$rXB=x zxJ}IiejF(|X6n2e8R`$%lTiXN ze}h`$&p02i0Pdt$30bvCAqoOsmoN+l2r7n1&OHPJ0tEmAM*uKH0w5o236I*D8J)pV z?;I%?>#@^sISoTK#zY%m7<%H0U5WxAHbx9De4HdAlx}5)ZO~!d6gMqa;Ms-0+B>8) bTXm+D>nnv#UQ$jkoeEjDT+|{xhE8q6vnrJ1 delta 381 zcmV-@0fPR327m^T9)DVfv%YgHT!IhDY>K}yWi%g?QEU1qyL0s;Xt%9M*|OujR~;was+4_i%-O=HSs0Lq_cK#3g^bc3$!j<#$@zTblTiXN zf1jH(y_nv$CsNWt?6MT&*#Z>CUVb5ys>Mh|AP5f(A;LN8p diff --git a/scripts/exampletrust.jks b/scripts/exampletrust.jks index daea7d39ffcf68cbf2280e3f96d42a304af026e7..92af08f68ea345b325871c677b7d9faa56adf93b 100644 GIT binary patch delta 270 zcmV+p0rCF%1o;Gz9wS^1Lb~1n1z0XMFgXAK0yi*%0y8jz0ob4e0s#U71ajm$%8@~p z7&S39GBPtaG&Ncm4Ky?`IWjpiGBYs(7@bS-zQ z{G3*wlUEh#ATK|Bk-vRONNV2+hCYpat+-9i1AZJSIcDm-8X4*j*ptcuFn@zu;?FoA zuK@0(R|#3QNg)aXUY9To1_&yKNX|V30|EsA14jTbL;@fmYYC6qnHinIQSTfn7wfUp zZ#fM^HO536Ul@Agid~8VAT~w}FMOONB9v}rhHcPc+!Qx0R^Zu%zuG&bG+TA1mA;L& U3OmANMlPl%LiwFyr3pkf=}+({cRd@VE_OC diff --git a/scripts/one.example.com.crt b/scripts/one.example.com.crt index 8bf3ea089..de2138e10 100644 --- a/scripts/one.example.com.crt +++ b/scripts/one.example.com.crt @@ -1,16 +1,16 @@ -----BEGIN CERTIFICATE----- -MIICfzCCAiKgAwIBAgIEW8LBNzAMBggqhkjOPQQDAgUAMH4xCzAJBgNVBAYTAlVT -MRMwEQYDVQQIEwpDYWxpZm9ybmlhMRYwFAYDVQQHEw1TYW4gRnJhbmNpc2NvMRgw -FgYDVQQKEw9FeGFtcGxlIENvbXBhbnkxFDASBgNVBAsTC0V4YW1wbGUgT3JnMRIw -EAYDVQQDEwlleGFtcGxlQ0EwHhcNMTcwMjI4MjI0MzU0WhcNMTcwNTI5MjI0MzU0 -WjCBhDELMAkGA1UEBhMCVVMxEzARBgNVBAgTCkNhbGlmb3JuaWExFjAUBgNVBAcT -DVNhbiBGcmFuY2lzY28xGDAWBgNVBAoTD0V4YW1wbGUgQ29tcGFueTEUMBIGA1UE -CxMLRXhhbXBsZSBPcmcxGDAWBgNVBAMTD29uZS5leGFtcGxlLmNvbTBZMBMGByqG -SM49AgEGCCqGSM49AwEHA0IABFGWM+El6kkxkJNDVgLhxfkioDLAOCTptwDjbFDd -76lOpCiwMNIrOcO9EOdRJJJtln+wLpzWZkTVzIHe9CNx09OjgYQwgYEwHwYDVR0j -BBgwFoAUn5szvZjetSdYVfTLHovZZHH6VSswEwYDVR0lBAwwCgYIKwYBBQUHAwEw -DgYDVR0PAQH/BAQDAgWgMBoGA1UdEQQTMBGCD29uZS5leGFtcGxlLmNvbTAdBgNV -HQ4EFgQUDhIRm98cJ/L0S7yKXf2afLb4WUIwDAYIKoZIzj0EAwIFAANJADBGAiEA -5zx7/xP6tkodjSgEOcHdzHzs4ch72Be48FUF86mfItsCIQCiZERgEGOKpBVYZwxg -vb7CZJWIqrMrxFzgEn8uLzotTA== +MIICfzCCAiKgAwIBAgIEVEPu+jAMBggqhkjOPQQDAgUAMH4xCzAJBgNVBAYTAlVT +MRMwEQYDVQQIEwpDYWxpZm9ybmlhMRYwFAYDVQQHEw1TYW4gRnJhbmNpc2NvMRgw +FgYDVQQKEw9FeGFtcGxlIENvbXBhbnkxFDASBgNVBAsTC0V4YW1wbGUgT3JnMRIw +EAYDVQQDEwlleGFtcGxlQ0EwHhcNMTcwNTE1MjIzNzUwWhcNMTcwODEzMjIzNzUw +WjCBhDELMAkGA1UEBhMCVVMxEzARBgNVBAgTCkNhbGlmb3JuaWExFjAUBgNVBAcT +DVNhbiBGcmFuY2lzY28xGDAWBgNVBAoTD0V4YW1wbGUgQ29tcGFueTEUMBIGA1UE +CxMLRXhhbXBsZSBPcmcxGDAWBgNVBAMTD29uZS5leGFtcGxlLmNvbTBZMBMGByqG +SM49AgEGCCqGSM49AwEHA0IABByQHoHDXDc7uya7i0cQm0bXaw/h3tZTaj/vpuH9 +0bX3m9uRdibIqv/gQON3PWhWXF0M2YdZDxpKdXgleyFV9JOjgYQwgYEwHwYDVR0j +BBgwFoAUg1rizzgfrwDupFcJWbVJIQoCXpcwEwYDVR0lBAwwCgYIKwYBBQUHAwEw +DgYDVR0PAQH/BAQDAgWgMBoGA1UdEQQTMBGCD29uZS5leGFtcGxlLmNvbTAdBgNV +HQ4EFgQUTtBHIl8+4VW9F5rOyRNXUCEf5yEwDAYIKoZIzj0EAwIFAANJADBGAiEA +3iJeFFDFOj1d+VJD8nWDGa6OUiZO0KLpNgoNehCuyUwCIQCMeUga2tXwxmMzbW6P +8bxOCaCQ3VUwu2AX24DWnOSxCA== -----END CERTIFICATE----- diff --git a/scripts/one.example.com.csr b/scripts/one.example.com.csr index 423beefae..2b781ebb0 100644 --- a/scripts/one.example.com.csr +++ b/scripts/one.example.com.csr @@ -1,10 +1,10 @@ -----BEGIN NEW CERTIFICATE REQUEST----- -MIIBczCCARcCAQAwgYQxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpDYWxpZm9ybmlh -MRYwFAYDVQQHEw1TYW4gRnJhbmNpc2NvMRgwFgYDVQQKEw9FeGFtcGxlIENvbXBh -bnkxFDASBgNVBAsTC0V4YW1wbGUgT3JnMRgwFgYDVQQDEw9vbmUuZXhhbXBsZS5j -b20wWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAARRljPhJepJMZCTQ1YC4cX5IqAy -wDgk6bcA42xQ3e+pTqQosDDSKznDvRDnUSSSbZZ/sC6c1mZE1cyB3vQjcdPToDAw -LgYJKoZIhvcNAQkOMSEwHzAdBgNVHQ4EFgQUDhIRm98cJ/L0S7yKXf2afLb4WUIw -DAYIKoZIzj0EAwIFAANIADBFAiBUe+0G9zii3QJZGPfzV6qfKuCUghrpPc8AC2ZE -GlP1jQIhAO6PD2UvGVmWDUEFCgo0xm1myfY7zEdmLNKoZRkqh6wt +MIIBczCCARcCAQAwgYQxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpDYWxpZm9ybmlh +MRYwFAYDVQQHEw1TYW4gRnJhbmNpc2NvMRgwFgYDVQQKEw9FeGFtcGxlIENvbXBh +bnkxFDASBgNVBAsTC0V4YW1wbGUgT3JnMRgwFgYDVQQDEw9vbmUuZXhhbXBsZS5j +b20wWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAAQckB6Bw1w3O7smu4tHEJtG12sP +4d7WU2o/76bh/dG195vbkXYmyKr/4EDjdz1oVlxdDNmHWQ8aSnV4JXshVfSToDAw +LgYJKoZIhvcNAQkOMSEwHzAdBgNVHQ4EFgQUTtBHIl8+4VW9F5rOyRNXUCEf5yEw +DAYIKoZIzj0EAwIFAANIADBFAiBH5kqEJHnRsiCcF7rMNFuJxbDgGYWWXsSmdkzj +btdd1wIhAJCfCe133nKwo8yGlfoeU++zzEqQ4zqaTI8iao4lyrsX -----END NEW CERTIFICATE REQUEST----- diff --git a/scripts/password b/scripts/password index 70d898132..6aab25301 100644 --- a/scripts/password +++ b/scripts/password @@ -1 +1 @@ -J9qYXN9vpj +ceHBtkmln5 diff --git a/scripts/two.example.com.crt b/scripts/two.example.com.crt index a57f2514f..aeb44983a 100644 --- a/scripts/two.example.com.crt +++ b/scripts/two.example.com.crt @@ -1,16 +1,16 @@ -----BEGIN CERTIFICATE----- -MIICfjCCAiKgAwIBAgIEfF9tVjAMBggqhkjOPQQDAgUAMH4xCzAJBgNVBAYTAlVT -MRMwEQYDVQQIEwpDYWxpZm9ybmlhMRYwFAYDVQQHEw1TYW4gRnJhbmNpc2NvMRgw -FgYDVQQKEw9FeGFtcGxlIENvbXBhbnkxFDASBgNVBAsTC0V4YW1wbGUgT3JnMRIw -EAYDVQQDEwlleGFtcGxlQ0EwHhcNMTcwMjI4MjI0MzU0WhcNMTcwNTI5MjI0MzU0 -WjCBhDELMAkGA1UEBhMCVVMxEzARBgNVBAgTCkNhbGlmb3JuaWExFjAUBgNVBAcT -DVNhbiBGcmFuY2lzY28xGDAWBgNVBAoTD0V4YW1wbGUgQ29tcGFueTEUMBIGA1UE -CxMLRXhhbXBsZSBPcmcxGDAWBgNVBAMTD3R3by5leGFtcGxlLmNvbTBZMBMGByqG -SM49AgEGCCqGSM49AwEHA0IABIIRpP0Kb8+YPKt8Gb8yMJlIw9GVVnxuy65cz3uG -4Ps38TUlPkMu2CiaJ77ApJ03EY26Si6g1YoyLg0O1Bw/51ajgYQwgYEwHwYDVR0j -BBgwFoAUn5szvZjetSdYVfTLHovZZHH6VSswEwYDVR0lBAwwCgYIKwYBBQUHAwEw -DgYDVR0PAQH/BAQDAgWgMBoGA1UdEQQTMBGCD3R3by5leGFtcGxlLmNvbTAdBgNV -HQ4EFgQUkZROdFtXEL2Vy+uamKkJ4XTk3PkwDAYIKoZIzj0EAwIFAANIADBFAiEA -gK9ZV2nZH+t4ze0RszgaE63DbpcKUjmG2p4DC4eQnIUCIHJeyM0DCqOtCHZz63Y/ -w9oCgsmFKv21SRSUrmZXshMH +MIICfzCCAiKgAwIBAgIEEgAklDAMBggqhkjOPQQDAgUAMH4xCzAJBgNVBAYTAlVT +MRMwEQYDVQQIEwpDYWxpZm9ybmlhMRYwFAYDVQQHEw1TYW4gRnJhbmNpc2NvMRgw +FgYDVQQKEw9FeGFtcGxlIENvbXBhbnkxFDASBgNVBAsTC0V4YW1wbGUgT3JnMRIw +EAYDVQQDEwlleGFtcGxlQ0EwHhcNMTcwNTE1MjIzNzUxWhcNMTcwODEzMjIzNzUx +WjCBhDELMAkGA1UEBhMCVVMxEzARBgNVBAgTCkNhbGlmb3JuaWExFjAUBgNVBAcT +DVNhbiBGcmFuY2lzY28xGDAWBgNVBAoTD0V4YW1wbGUgQ29tcGFueTEUMBIGA1UE +CxMLRXhhbXBsZSBPcmcxGDAWBgNVBAMTD3R3by5leGFtcGxlLmNvbTBZMBMGByqG +SM49AgEGCCqGSM49AwEHA0IABFPwUbVZtp9VO/pUf+8gp9cbjOuzbvcB2B8iIDKK +V6h8ujsBoFrMQX2xIAjuQa3vFMJWtvCN7SYWeTa5yEvlvpmjgYQwgYEwHwYDVR0j +BBgwFoAUg1rizzgfrwDupFcJWbVJIQoCXpcwEwYDVR0lBAwwCgYIKwYBBQUHAwEw +DgYDVR0PAQH/BAQDAgWgMBoGA1UdEQQTMBGCD3R3by5leGFtcGxlLmNvbTAdBgNV +HQ4EFgQUwPZmWCliuCdnkV7hwr+Ii3BPL8IwDAYIKoZIzj0EAwIFAANJADBGAiEA +vTwOqAJMVRMnBnYwO+HoEpnvmomvHg3Dlo0vzVqVlsACIQCCU1SY6XcZ/aTgDgWM +Oo6HshieDsMuyBeR651QrM5Hpw== -----END CERTIFICATE----- diff --git a/scripts/two.example.com.csr b/scripts/two.example.com.csr index f90ac5597..d6760a87b 100644 --- a/scripts/two.example.com.csr +++ b/scripts/two.example.com.csr @@ -1,10 +1,10 @@ -----BEGIN NEW CERTIFICATE REQUEST----- -MIIBczCCARcCAQAwgYQxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpDYWxpZm9ybmlh -MRYwFAYDVQQHEw1TYW4gRnJhbmNpc2NvMRgwFgYDVQQKEw9FeGFtcGxlIENvbXBh -bnkxFDASBgNVBAsTC0V4YW1wbGUgT3JnMRgwFgYDVQQDEw90d28uZXhhbXBsZS5j -b20wWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAASCEaT9Cm/PmDyrfBm/MjCZSMPR -lVZ8bsuuXM97huD7N/E1JT5DLtgomie+wKSdNxGNukouoNWKMi4NDtQcP+dWoDAw -LgYJKoZIhvcNAQkOMSEwHzAdBgNVHQ4EFgQUkZROdFtXEL2Vy+uamKkJ4XTk3Pkw -DAYIKoZIzj0EAwIFAANIADBFAiEAvqtgt3TpsiJlGtIHMT5AtPurdANHCPTNNANU -cP28bC8CIF+FTnyds+aLqnlAqa5bdnsAys+7AaYfv/ifNyU1brzX +MIIBczCCARcCAQAwgYQxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpDYWxpZm9ybmlh +MRYwFAYDVQQHEw1TYW4gRnJhbmNpc2NvMRgwFgYDVQQKEw9FeGFtcGxlIENvbXBh +bnkxFDASBgNVBAsTC0V4YW1wbGUgT3JnMRgwFgYDVQQDEw90d28uZXhhbXBsZS5j +b20wWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAART8FG1WbafVTv6VH/vIKfXG4zr +s273AdgfIiAyileofLo7AaBazEF9sSAI7kGt7xTCVrbwje0mFnk2uchL5b6ZoDAw +LgYJKoZIhvcNAQkOMSEwHzAdBgNVHQ4EFgQUwPZmWCliuCdnkV7hwr+Ii3BPL8Iw +DAYIKoZIzj0EAwIFAANIADBFAiBpJh9nzYELwoY3AcZNz+W4srKnVHj7gAjgLB56 +lCvbGgIhAPUzOvj1fifVT7hUxPfDE7fknvdXTlJP66r5NOWJnjOJ -----END NEW CERTIFICATE REQUEST----- diff --git a/scripts/wildcard.example.com.crt b/scripts/wildcard.example.com.crt index 5fb67190a..961901c7a 100644 --- a/scripts/wildcard.example.com.crt +++ b/scripts/wildcard.example.com.crt @@ -1,15 +1,15 @@ -----BEGIN CERTIFICATE----- -MIICXzCCAgKgAwIBAgIEci94DDAMBggqhkjOPQQDAgUAMH4xCzAJBgNVBAYTAlVT -MRMwEQYDVQQIEwpDYWxpZm9ybmlhMRYwFAYDVQQHEw1TYW4gRnJhbmNpc2NvMRgw -FgYDVQQKEw9FeGFtcGxlIENvbXBhbnkxFDASBgNVBAsTC0V4YW1wbGUgT3JnMRIw -EAYDVQQDEwlleGFtcGxlQ0EwHhcNMTcwMjI4MjI0MzU1WhcNMTcwNTI5MjI0MzU1 -WjCBgjELMAkGA1UEBhMCVVMxEzARBgNVBAgTCkNhbGlmb3JuaWExFjAUBgNVBAcT -DVNhbiBGcmFuY2lzY28xGDAWBgNVBAoTD0V4YW1wbGUgQ29tcGFueTEUMBIGA1UE -CxMLRXhhbXBsZSBPcmcxFjAUBgNVBAMMDSouZXhhbXBsZS5jb20wWTATBgcqhkjO -PQIBBggqhkjOPQMBBwNCAASTGa3jaDXb3Gi5KNWwVwWkcXIVXtt5xu84gE7TUSfE -WDAxutPya8HmNZywkTaNGmKDCGeuA7tRGCv7RAhtWEByo2cwZTAfBgNVHSMEGDAW -gBSfmzO9mN61J1hV9Msei9lkcfpVKzATBgNVHSUEDDAKBggrBgEFBQcDATAOBgNV -HQ8BAf8EBAMCBaAwHQYDVR0OBBYEFKCcpFCFulPF/G9Ug1a5AJQSzpcBMAwGCCqG -SM49BAMCBQADSQAwRgIhAJTal/9hrcen9LQykuXKJPVZzzntMXAv8aji+NQwQA5o -AiEA4p7Gg6rLjt+OwqhENoZRXNTTPkTJ372pTxar/Q1t5z4= +MIICXjCCAgKgAwIBAgIEEhh1gjAMBggqhkjOPQQDAgUAMH4xCzAJBgNVBAYTAlVT +MRMwEQYDVQQIEwpDYWxpZm9ybmlhMRYwFAYDVQQHEw1TYW4gRnJhbmNpc2NvMRgw +FgYDVQQKEw9FeGFtcGxlIENvbXBhbnkxFDASBgNVBAsTC0V4YW1wbGUgT3JnMRIw +EAYDVQQDEwlleGFtcGxlQ0EwHhcNMTcwNTE1MjIzNzUyWhcNMTcwODEzMjIzNzUy +WjCBgjELMAkGA1UEBhMCVVMxEzARBgNVBAgTCkNhbGlmb3JuaWExFjAUBgNVBAcT +DVNhbiBGcmFuY2lzY28xGDAWBgNVBAoTD0V4YW1wbGUgQ29tcGFueTEUMBIGA1UE +CxMLRXhhbXBsZSBPcmcxFjAUBgNVBAMMDSouZXhhbXBsZS5jb20wWTATBgcqhkjO +PQIBBggqhkjOPQMBBwNCAAQtCMiMQzBjtOv3vfT30Q08VdwPupTEwaSvbjKEflQ4 +LtDUmPywkzpOuUZ59Nbptp+pM1AONF4/q9P10ISGNxDyo2cwZTAfBgNVHSMEGDAW +gBSDWuLPOB+vAO6kVwlZtUkhCgJelzATBgNVHSUEDDAKBggrBgEFBQcDATAOBgNV +HQ8BAf8EBAMCBaAwHQYDVR0OBBYEFLRzzM2eM35A7IaWfMlZ3F6QKxIWMAwGCCqG +SM49BAMCBQADSAAwRQIgXghN4GCl2U3WgdKIp7hu00hZXoUWJXHDKmSVgjdYuqoC +IQDqBH56Jk1Rsy9F766iP0gASYt+bo04jEiau+uzHN5xXg== -----END CERTIFICATE----- diff --git a/scripts/wildcard.example.com.csr b/scripts/wildcard.example.com.csr index be3b5a132..69cbca420 100644 --- a/scripts/wildcard.example.com.csr +++ b/scripts/wildcard.example.com.csr @@ -1,10 +1,10 @@ -----BEGIN NEW CERTIFICATE REQUEST----- -MIIBcDCCARUCAQAwgYIxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpDYWxpZm9ybmlh -MRYwFAYDVQQHEw1TYW4gRnJhbmNpc2NvMRgwFgYDVQQKEw9FeGFtcGxlIENvbXBh -bnkxFDASBgNVBAsTC0V4YW1wbGUgT3JnMRYwFAYDVQQDDA0qLmV4YW1wbGUuY29t -MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEkxmt42g129xouSjVsFcFpHFyFV7b -ecbvOIBO01EnxFgwMbrT8mvB5jWcsJE2jRpigwhnrgO7URgr+0QIbVhAcqAwMC4G -CSqGSIb3DQEJDjEhMB8wHQYDVR0OBBYEFKCcpFCFulPF/G9Ug1a5AJQSzpcBMAwG -CCqGSM49BAMCBQADRwAwRAIgeECb69mQ/aT3FITqEE/9ERb94KzCHocE4zkYdSrQ -zRACIEEslQ1Z1n2N7lJGtHk79aEDnm71lp1Jh73HIcK6Z7h+ +MIIBcTCCARUCAQAwgYIxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpDYWxpZm9ybmlh +MRYwFAYDVQQHEw1TYW4gRnJhbmNpc2NvMRgwFgYDVQQKEw9FeGFtcGxlIENvbXBh +bnkxFDASBgNVBAsTC0V4YW1wbGUgT3JnMRYwFAYDVQQDDA0qLmV4YW1wbGUuY29t +MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAELQjIjEMwY7Tr973099ENPFXcD7qU +xMGkr24yhH5UOC7Q1Jj8sJM6TrlGefTW6bafqTNQDjReP6vT9dCEhjcQ8qAwMC4G +CSqGSIb3DQEJDjEhMB8wHQYDVR0OBBYEFLRzzM2eM35A7IaWfMlZ3F6QKxIWMAwG +CCqGSM49BAMCBQADSAAwRQIgJIYJ1RzkCjYdkmNbFBdYFf/Lq9+zrr/K0RjOz2fI +4UkCIQCDoNZC/swl9FTTHwZ3ouKJhNrWugRtCCH6zwH2V5WsJw== -----END NEW CERTIFICATE REQUEST----- From 292fd3f5c1c164841860aa33d2f23d9c3a104c5b Mon Sep 17 00:00:00 2001 From: Greg Methvin Date: Thu, 22 Jun 2017 19:28:33 -0700 Subject: [PATCH 25/53] Updated with template-control on 2017-06-23T02:18:41.822Z (#37) **/plugins.sbt: addSbtPlugin("com.typesafe.play" % "sbt-plugin" % "2.6.0") --- project/plugins.sbt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/project/plugins.sbt b/project/plugins.sbt index fa74539dd..6f132815b 100644 --- a/project/plugins.sbt +++ b/project/plugins.sbt @@ -1,5 +1,5 @@ resolvers += "Typesafe repository" at "http://repo.typesafe.com/typesafe/releases/" // The Play plugin -addSbtPlugin("com.typesafe.play" % "sbt-plugin" % "2.6.0-RC2") +addSbtPlugin("com.typesafe.play" % "sbt-plugin" % "2.6.0") From 30c038634ca6f575b1a5919c15404e3210298d2f Mon Sep 17 00:00:00 2001 From: Greg Methvin Date: Thu, 6 Jul 2017 20:28:47 -0700 Subject: [PATCH 26/53] Updated with template-control on 2017-07-07T00:45:50.235Z (#38) **/plugins.sbt: addSbtPlugin("com.typesafe.play" % "sbt-plugin" % "2.6.1") --- project/plugins.sbt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/project/plugins.sbt b/project/plugins.sbt index 6f132815b..3d45c07c4 100644 --- a/project/plugins.sbt +++ b/project/plugins.sbt @@ -1,5 +1,5 @@ resolvers += "Typesafe repository" at "http://repo.typesafe.com/typesafe/releases/" // The Play plugin -addSbtPlugin("com.typesafe.play" % "sbt-plugin" % "2.6.0") +addSbtPlugin("com.typesafe.play" % "sbt-plugin" % "2.6.1") From b44cc8c47fb27063b08840a16f7c158a1b24825e Mon Sep 17 00:00:00 2001 From: Marcos Pereira Date: Wed, 9 Aug 2017 20:17:58 -0300 Subject: [PATCH 27/53] Updated with template-control on 2017-07-20T01:10:16.824Z (#40) **/plugins.sbt: addSbtPlugin("com.typesafe.play" % "sbt-plugin" % "2.6.2") --- project/plugins.sbt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/project/plugins.sbt b/project/plugins.sbt index 3d45c07c4..8c5d681de 100644 --- a/project/plugins.sbt +++ b/project/plugins.sbt @@ -1,5 +1,5 @@ resolvers += "Typesafe repository" at "http://repo.typesafe.com/typesafe/releases/" // The Play plugin -addSbtPlugin("com.typesafe.play" % "sbt-plugin" % "2.6.1") +addSbtPlugin("com.typesafe.play" % "sbt-plugin" % "2.6.2") From 8d3a02edd23004ff9acb49106bb1e251c2c7e8c0 Mon Sep 17 00:00:00 2001 From: Rich Dougherty Date: Tue, 22 Aug 2017 07:50:08 +1200 Subject: [PATCH 28/53] Updated with template-control on 2017-08-12T02:43:28.188Z (#42) **/plugins.sbt: addSbtPlugin("com.typesafe.play" % "sbt-plugin" % "2.6.3") --- project/plugins.sbt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/project/plugins.sbt b/project/plugins.sbt index 8c5d681de..638802eec 100644 --- a/project/plugins.sbt +++ b/project/plugins.sbt @@ -1,5 +1,5 @@ resolvers += "Typesafe repository" at "http://repo.typesafe.com/typesafe/releases/" // The Play plugin -addSbtPlugin("com.typesafe.play" % "sbt-plugin" % "2.6.2") +addSbtPlugin("com.typesafe.play" % "sbt-plugin" % "2.6.3") From 8cae7da214ab1bc19d646cb49823565f6deba73d Mon Sep 17 00:00:00 2001 From: Greg Methvin Date: Fri, 22 Sep 2017 10:07:25 -0700 Subject: [PATCH 29/53] Updated with template-control on 2017-09-14T23:29:37.043Z (#43) **/plugins.sbt: addSbtPlugin("com.typesafe.play" % "sbt-plugin" % "2.6.5") --- project/plugins.sbt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/project/plugins.sbt b/project/plugins.sbt index 638802eec..58d869d07 100644 --- a/project/plugins.sbt +++ b/project/plugins.sbt @@ -1,5 +1,5 @@ resolvers += "Typesafe repository" at "http://repo.typesafe.com/typesafe/releases/" // The Play plugin -addSbtPlugin("com.typesafe.play" % "sbt-plugin" % "2.6.3") +addSbtPlugin("com.typesafe.play" % "sbt-plugin" % "2.6.5") From 4c960ae0069a5f3026d0916f166b2517757012e7 Mon Sep 17 00:00:00 2001 From: Greg Methvin Date: Fri, 3 Nov 2017 20:30:37 -0700 Subject: [PATCH 30/53] Updated with template-control on 2017-11-02T02:51:20.918Z (#45) **/build.sbt: scalaVersion := "2.12.4" **/build.sbt: scalaVersion := "2.12.4" **/build.properties: sbt.version=1.0.2 **/build.properties: sbt.version=1.0.2 **/build.properties: sbt.version=1.0.2 **/plugins.sbt: addSbtPlugin("com.typesafe.play" % "sbt-plugin" % "2.6.7") --- modules/one/build.sbt | 2 +- modules/one/project/build.properties | 2 +- modules/two/build.sbt | 2 +- modules/two/project/build.properties | 2 +- project/build.properties | 2 +- project/plugins.sbt | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) diff --git a/modules/one/build.sbt b/modules/one/build.sbt index bf7c2d3a0..98597746a 100644 --- a/modules/one/build.sbt +++ b/modules/one/build.sbt @@ -1,2 +1,2 @@ -scalaVersion := "2.12.2" +scalaVersion := "2.12.4" diff --git a/modules/one/project/build.properties b/modules/one/project/build.properties index 2b112b751..7eb4111f7 100644 --- a/modules/one/project/build.properties +++ b/modules/one/project/build.properties @@ -1,4 +1,4 @@ #Activator-generated Properties #Fri Jul 08 22:56:54 PDT 2016 template.uuid=f57599cf-a4f5-4333-9ff1-55d48fd49891 -sbt.version=0.13.15 +sbt.version=1.0.2 diff --git a/modules/two/build.sbt b/modules/two/build.sbt index bf7c2d3a0..98597746a 100644 --- a/modules/two/build.sbt +++ b/modules/two/build.sbt @@ -1,2 +1,2 @@ -scalaVersion := "2.12.2" +scalaVersion := "2.12.4" diff --git a/modules/two/project/build.properties b/modules/two/project/build.properties index 64317fdae..b7dd3cb2a 100644 --- a/modules/two/project/build.properties +++ b/modules/two/project/build.properties @@ -1 +1 @@ -sbt.version=0.13.15 +sbt.version=1.0.2 diff --git a/project/build.properties b/project/build.properties index 59875ef19..ae184614b 100644 --- a/project/build.properties +++ b/project/build.properties @@ -1,4 +1,4 @@ #Activator-generated Properties #Sun Jul 06 17:54:30 PDT 2014 template.uuid=af582966-096a-43df-a504-5ddae8d4ebf1 -sbt.version=0.13.15 +sbt.version=1.0.2 diff --git a/project/plugins.sbt b/project/plugins.sbt index 58d869d07..c4e128d09 100644 --- a/project/plugins.sbt +++ b/project/plugins.sbt @@ -1,5 +1,5 @@ resolvers += "Typesafe repository" at "http://repo.typesafe.com/typesafe/releases/" // The Play plugin -addSbtPlugin("com.typesafe.play" % "sbt-plugin" % "2.6.5") +addSbtPlugin("com.typesafe.play" % "sbt-plugin" % "2.6.7") From 8623b59672d8d293b0e01c515ad01936a58bc347 Mon Sep 17 00:00:00 2001 From: Greg Methvin Date: Fri, 8 Dec 2017 19:39:46 -0800 Subject: [PATCH 31/53] Updated with template-control on 2017-12-09T03:16:28.052Z (#47) **/plugins.sbt: addSbtPlugin("com.typesafe.play" % "sbt-plugin" % "2.6.9") --- project/plugins.sbt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/project/plugins.sbt b/project/plugins.sbt index c4e128d09..6b6e16146 100644 --- a/project/plugins.sbt +++ b/project/plugins.sbt @@ -1,5 +1,5 @@ resolvers += "Typesafe repository" at "http://repo.typesafe.com/typesafe/releases/" // The Play plugin -addSbtPlugin("com.typesafe.play" % "sbt-plugin" % "2.6.7") +addSbtPlugin("com.typesafe.play" % "sbt-plugin" % "2.6.9") From df134a0846c6a2c0d937ffd14e9e34bb5972b63f Mon Sep 17 00:00:00 2001 From: Marcos Pereira Date: Thu, 21 Dec 2017 18:24:24 -0200 Subject: [PATCH 32/53] Updated with template-control on 2017-12-21T19:35:21.937Z (#49) **/build.properties: sbt.version=1.0.4 **/build.properties: sbt.version=1.0.4 **/build.properties: sbt.version=1.0.4 --- modules/one/project/build.properties | 2 +- modules/two/project/build.properties | 2 +- project/build.properties | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/modules/one/project/build.properties b/modules/one/project/build.properties index 7eb4111f7..696ecdc78 100644 --- a/modules/one/project/build.properties +++ b/modules/one/project/build.properties @@ -1,4 +1,4 @@ #Activator-generated Properties #Fri Jul 08 22:56:54 PDT 2016 template.uuid=f57599cf-a4f5-4333-9ff1-55d48fd49891 -sbt.version=1.0.2 +sbt.version=1.0.4 diff --git a/modules/two/project/build.properties b/modules/two/project/build.properties index b7dd3cb2a..394cb75cf 100644 --- a/modules/two/project/build.properties +++ b/modules/two/project/build.properties @@ -1 +1 @@ -sbt.version=1.0.2 +sbt.version=1.0.4 diff --git a/project/build.properties b/project/build.properties index ae184614b..dfb91dd51 100644 --- a/project/build.properties +++ b/project/build.properties @@ -1,4 +1,4 @@ #Activator-generated Properties #Sun Jul 06 17:54:30 PDT 2014 template.uuid=af582966-096a-43df-a504-5ddae8d4ebf1 -sbt.version=1.0.2 +sbt.version=1.0.4 From fbed50221027632de260ada6c96c696d61a8f7a4 Mon Sep 17 00:00:00 2001 From: Marcos Pereira Date: Thu, 21 Dec 2017 18:24:44 -0200 Subject: [PATCH 33/53] Add Gradle configuration and Java 9 support (#48) --- .gitignore | 2 + .travis.yml | 23 ++- README.md | 26 ++-- app/Main.scala | 2 +- build.gradle | 49 +++++++ build.sbt | 4 +- gradle/wrapper/gradle-wrapper.jar | Bin 0 -> 54329 bytes gradle/wrapper/gradle-wrapper.properties | 5 + gradlew | 172 +++++++++++++++++++++++ gradlew.bat | 84 +++++++++++ modules/one/build.gradle | 21 +++ modules/two/build.gradle | 25 ++++ project/plugins.sbt | 2 - scripts/script-helper | 13 ++ scripts/test-gradle | 13 ++ scripts/test-sbt | 8 ++ settings.gradle | 4 + 17 files changed, 434 insertions(+), 19 deletions(-) create mode 100644 build.gradle create mode 100644 gradle/wrapper/gradle-wrapper.jar create mode 100644 gradle/wrapper/gradle-wrapper.properties create mode 100755 gradlew create mode 100644 gradlew.bat create mode 100644 modules/one/build.gradle create mode 100644 modules/two/build.gradle create mode 100644 scripts/script-helper create mode 100755 scripts/test-gradle create mode 100755 scripts/test-sbt create mode 100644 settings.gradle diff --git a/.gitignore b/.gitignore index 905203716..c28bf5538 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ +build logs project/project project/target @@ -6,6 +7,7 @@ tmp .history dist /.idea +/.gradle /*.iml /out /certs diff --git a/.travis.yml b/.travis.yml index 74486cdfd..981dece36 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,15 +1,36 @@ language: scala scala: -- 2.12.1 +# When updating Scala versions, also check the excludes +# in build matrix below. +- 2.11.12 +- 2.12.4 jdk: - oraclejdk8 +- oraclejdk9 +env: + matrix: + - SCRIPT=scripts/test-sbt + - SCRIPT=scripts/test-gradle +script: +- $SCRIPT cache: directories: - "$HOME/.ivy2/cache" + - "$HOME/.gradle/caches" before_cache: - rm -rf $HOME/.ivy2/cache/com.typesafe.play/* - rm -rf $HOME/.ivy2/cache/scala_*/sbt_*/com.typesafe.play/* - find $HOME/.ivy2/cache -name "ivydata-*.properties" -print0 | xargs -n10 -0 rm + +# Exclude some combinations from build matrix. See: +# https://docs.travis-ci.com/user/customizing-the-build/#Build-Matrix +matrix: + exclude: + - scala: 2.11.12 + jdk: oraclejdk9 + +# See https://blog.travis-ci.com/2014-03-13-slack-notifications/ +# created with travis encrypt command line tool notifications: slack: secure: K6HWTI6zJpQfxS7sH5ZQ1jEK5TkkUl5GtcGinNecHMBqvfS4IXAnU23lz/kLqCqMVPIFaRx1g6UwgJgMvR4XWeIhpzLOzAnOOcmv+kQzv7A8vEJBM20z1HNzDcxzvuNNO2BHn8EjXh5VD65vXMcA+lKzUxASey/Rs+CBReQWE7M= \ No newline at end of file diff --git a/README.md b/README.md index 2a96cb2e9..591a71af3 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@ # Example Play TLS Application This application shows how to use Play with SSL/TLS, using the Java Secure Socket Extension (JSSE) API. - + ## Requirements You must have JDK 1.8 installed on your machine to run this, to take advantage of the new [security enhancements in JSSE](http://blog.ivanristic.com/2014/03/ssl-tls-improvements-in-java-8.html). @@ -22,7 +22,7 @@ To use HTTPS, you must have X.509 certificates. Generating certificates can be To generate certificates, run: -``` +```bash cd scripts/ ./gencerts.sh ``` @@ -33,11 +33,11 @@ You may have noticed that the name on the generated certificates is `example.com Rather than setting up a DNS entry or a remote server, we'll modify `/etc/hosts` to point to the local directory. -``` +```bash $ sudo vi /etc/hosts ``` -``` +```bash 127.0.0.1 example.com one.example.com two.example.com three.example.com ``` @@ -49,7 +49,7 @@ This application is not run with `activator` -- you should run it with `./play` The `CustomSSLEngineProvider` is responsible for Play's HTTPS server. More details can be found in [Configuring HTTPS](http://www.playframework.com/documentation/2.5.x/ConfiguringHttps). -``` +```bash ./play run ``` @@ -69,14 +69,14 @@ Download SSLyze: And then run SSLyze against the play application: -``` +```bash cd sslyze-0_9-osx64 python sslyze.py --regular www.example.com:9443 ``` You should see results like: -``` +```bash REGISTERING AVAILABLE PLUGINS ----------------------------- @@ -170,13 +170,13 @@ exceptions.KeyError - 'exponent' Now that you've verified that the server is running and can speak HTTPS, go into `./play` script and uncomment the `play.ssl.needClientAuth` setting: -``` +```bash JVM_OPTIONS="$JVM_OPTIONS -Dplay.ssl.needClientAuth=true" ``` Then restart the server. You should see -``` +```bash ECDHE-ECDSA-RC4-SHA ClientCertificateRequested - Server requested a client certificate issued by one of the following CAs: '/C=US/ST=California/L=San Francisco/O=Example Company/OU=Example Org/CN=clientca'. ``` @@ -188,7 +188,7 @@ Fortunately, we happen to have [Play WS](http://www.playframework.com/documentat The `ws.conf` script looks like this: -``` +```HOCON ws.ssl { protocol = "TLSv1.2" @@ -224,14 +224,14 @@ Normally you would use [Play WS](http://www.playframework.com/documentation/2.3. Open up a new shell, and type: -``` +```bash $ ./play > runMain Main ``` You should see: -``` +```bash [info] Running Main header = (Content-Length,Buffer(106)) header = (Content-Type,Buffer(text/html; charset=utf-8)) @@ -246,7 +246,7 @@ body = Now, to verify that it's only working because of the client's key, comment out the keyManager section in `ws.conf` and rerun `Main` -- you will see that the WS client fails client authentication: -``` +```bash failure = java.net.ConnectException: Received fatal alert: bad_certificate to https://example.com:9443/ ``` diff --git a/app/Main.scala b/app/Main.scala index 76a835f4d..1fd571543 100644 --- a/app/Main.scala +++ b/app/Main.scala @@ -16,7 +16,7 @@ object Main { private val logger = org.slf4j.LoggerFactory.getLogger("application") def printResponse(response:WSResponse) = { - response.allHeaders.foreach { header => + response.headers.foreach { header => logger.info(s"header = $header") } val body = response.body diff --git a/build.gradle b/build.gradle new file mode 100644 index 000000000..dc07e4fd8 --- /dev/null +++ b/build.gradle @@ -0,0 +1,49 @@ +plugins { + id 'play' + id 'idea' +} + +def playVersion = '2.6.9' +def scalaVersion = System.getProperty("scala.binary.version", /* default = */ "2.12") + +model { + components { + play { + platform play: playVersion, scala: scalaVersion, java: '1.8' + injectedRoutesGenerator = true + + sources { + twirlTemplates { + defaultImports = TwirlImports.SCALA + } + } + } + } +} + +dependencies { + play "com.typesafe.play:play-guice_$scalaVersion:$playVersion" + play "com.typesafe.play:play-server_$scalaVersion:$playVersion" + play "com.typesafe.play:play-logback_$scalaVersion:$playVersion" + play "com.typesafe.play:play-ahc-ws_$scalaVersion:$playVersion" + + play project(":one") + play project(":two") + + playTest "org.scalatestplus.play:scalatestplus-play_$scalaVersion:3.1.2" +} + +allprojects { + repositories { + jcenter() + maven { + name "lightbend-maven-releases" + url "https://repo.lightbend.com/lightbend/maven-release" + } + ivy { + name "lightbend-ivy-release" + url "https://repo.lightbend.com/lightbend/ivy-releases" + layout "ivy" + } + } +} \ No newline at end of file diff --git a/build.sbt b/build.sbt index fc578aa5b..059f192eb 100644 --- a/build.sbt +++ b/build.sbt @@ -11,11 +11,11 @@ lazy val root = (project in file(".")) .aggregate(one, two) .dependsOn(one, two) -scalaVersion := "2.12.2" +scalaVersion := "2.12.4" libraryDependencies += ws libraryDependencies += guice -libraryDependencies += "org.scalatestplus.play" %% "scalatestplus-play" % "3.0.0-M3" % Test +libraryDependencies += "org.scalatestplus.play" %% "scalatestplus-play" % "3.1.2" % Test fork in run := true diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar new file mode 100644 index 0000000000000000000000000000000000000000..01b8bf6b1f99cad9213fc495b33ad5bbab8efd20 GIT binary patch literal 54329 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

<5G2M1WZP5 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 \(.*\)$'` + if expr "$link" : '/.*' > /dev/null; then + PRG="$link" + else + PRG=`dirname "$PRG"`"/$link" + fi +done +SAVED="`pwd`" +cd "`dirname \"$PRG\"`/" >/dev/null +APP_HOME="`pwd -P`" +cd "$SAVED" >/dev/null + +APP_NAME="Gradle" +APP_BASE_NAME=`basename "$0"` + +# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +DEFAULT_JVM_OPTS="" + +# Use the maximum available, or set MAX_FD != -1 to use that value. +MAX_FD="maximum" + +warn () { + echo "$*" +} + +die () { + echo + echo "$*" + echo + exit 1 +} + +# OS specific support (must be 'true' or 'false'). +cygwin=false +msys=false +darwin=false +nonstop=false +case "`uname`" in + CYGWIN* ) + cygwin=true + ;; + Darwin* ) + darwin=true + ;; + MINGW* ) + msys=true + ;; + NONSTOP* ) + nonstop=true + ;; +esac + +CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar + +# Determine the Java command to use to start the JVM. +if [ -n "$JAVA_HOME" ] ; then + if [ -x "$JAVA_HOME/jre/sh/java" ] ; then + # IBM's JDK on AIX uses strange locations for the executables + JAVACMD="$JAVA_HOME/jre/sh/java" + else + JAVACMD="$JAVA_HOME/bin/java" + fi + if [ ! -x "$JAVACMD" ] ; then + die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." + fi +else + JAVACMD="java" + which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." +fi + +# Increase the maximum file descriptors if we can. +if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then + MAX_FD_LIMIT=`ulimit -H -n` + if [ $? -eq 0 ] ; then + if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then + MAX_FD="$MAX_FD_LIMIT" + fi + ulimit -n $MAX_FD + if [ $? -ne 0 ] ; then + warn "Could not set maximum file descriptor limit: $MAX_FD" + fi + else + warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" + fi +fi + +# For Darwin, add options to specify how the application appears in the dock +if $darwin; then + GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" +fi + +# For Cygwin, switch paths to Windows format before running java +if $cygwin ; then + APP_HOME=`cygpath --path --mixed "$APP_HOME"` + CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` + JAVACMD=`cygpath --unix "$JAVACMD"` + + # We build the pattern for arguments to be converted via cygpath + ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` + SEP="" + for dir in $ROOTDIRSRAW ; do + ROOTDIRS="$ROOTDIRS$SEP$dir" + SEP="|" + done + OURCYGPATTERN="(^($ROOTDIRS))" + # Add a user-defined pattern to the cygpath arguments + if [ "$GRADLE_CYGPATTERN" != "" ] ; then + OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" + fi + # Now convert the arguments - kludge to limit ourselves to /bin/sh + i=0 + for arg in "$@" ; do + CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` + CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option + + if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition + eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` + else + eval `echo args$i`="\"$arg\"" + fi + i=$((i+1)) + done + case $i in + (0) set -- ;; + (1) set -- "$args0" ;; + (2) set -- "$args0" "$args1" ;; + (3) set -- "$args0" "$args1" "$args2" ;; + (4) set -- "$args0" "$args1" "$args2" "$args3" ;; + (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; + (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; + (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; + (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; + (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; + esac +fi + +# Escape application args +save () { + for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done + echo " " +} +APP_ARGS=$(save "$@") + +# Collect all arguments for the java command, following the shell quoting and substitution rules +eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS" + +# by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong +if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then + cd "$(dirname "$0")" +fi + +exec "$JAVACMD" "$@" diff --git a/gradlew.bat b/gradlew.bat new file mode 100644 index 000000000..e95643d6a --- /dev/null +++ b/gradlew.bat @@ -0,0 +1,84 @@ +@if "%DEBUG%" == "" @echo off +@rem ########################################################################## +@rem +@rem Gradle startup script for Windows +@rem +@rem ########################################################################## + +@rem Set local scope for the variables with windows NT shell +if "%OS%"=="Windows_NT" setlocal + +set DIRNAME=%~dp0 +if "%DIRNAME%" == "" set DIRNAME=. +set APP_BASE_NAME=%~n0 +set APP_HOME=%DIRNAME% + +@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +set DEFAULT_JVM_OPTS= + +@rem Find java.exe +if defined JAVA_HOME goto findJavaFromJavaHome + +set JAVA_EXE=java.exe +%JAVA_EXE% -version >NUL 2>&1 +if "%ERRORLEVEL%" == "0" goto init + +echo. +echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:findJavaFromJavaHome +set JAVA_HOME=%JAVA_HOME:"=% +set JAVA_EXE=%JAVA_HOME%/bin/java.exe + +if exist "%JAVA_EXE%" goto init + +echo. +echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:init +@rem Get command-line arguments, handling Windows variants + +if not "%OS%" == "Windows_NT" goto win9xME_args + +:win9xME_args +@rem Slurp the command line arguments. +set CMD_LINE_ARGS= +set _SKIP=2 + +:win9xME_args_slurp +if "x%~1" == "x" goto execute + +set CMD_LINE_ARGS=%* + +:execute +@rem Setup the command line + +set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar + +@rem Execute Gradle +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% + +:end +@rem End local scope for the variables with windows NT shell +if "%ERRORLEVEL%"=="0" goto mainEnd + +:fail +rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of +rem the _cmd.exe /c_ return code! +if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 +exit /b 1 + +:mainEnd +if "%OS%"=="Windows_NT" endlocal + +:omega diff --git a/modules/one/build.gradle b/modules/one/build.gradle new file mode 100644 index 000000000..9aa55bfc7 --- /dev/null +++ b/modules/one/build.gradle @@ -0,0 +1,21 @@ +plugins { + id 'play' +} + +def playVersion = '2.6.9' +def scalaVersion = System.getProperty("scala.binary.version", /* default = */ "2.12") + +model { + components { + play { + platform play: playVersion, scala: scalaVersion, java: '1.8' + injectedRoutesGenerator = true + + sources { + twirlTemplates { + defaultImports = TwirlImports.SCALA + } + } + } + } +} diff --git a/modules/two/build.gradle b/modules/two/build.gradle new file mode 100644 index 000000000..f623f489e --- /dev/null +++ b/modules/two/build.gradle @@ -0,0 +1,25 @@ +plugins { + id 'play' +} + +def playVersion = '2.6.9' +def scalaVersion = System.getProperty("scala.binary.version", /* default = */ "2.12") + +model { + components { + play { + platform play: playVersion, scala: scalaVersion, java: '1.8' + injectedRoutesGenerator = true + + sources { + twirlTemplates { + defaultImports = TwirlImports.SCALA + } + } + } + } +} + +dependencies { + play "com.typesafe.play:play-guice_$scalaVersion:$playVersion" +} diff --git a/project/plugins.sbt b/project/plugins.sbt index 6b6e16146..4fb584732 100644 --- a/project/plugins.sbt +++ b/project/plugins.sbt @@ -1,5 +1,3 @@ -resolvers += "Typesafe repository" at "http://repo.typesafe.com/typesafe/releases/" - // The Play plugin addSbtPlugin("com.typesafe.play" % "sbt-plugin" % "2.6.9") diff --git a/scripts/script-helper b/scripts/script-helper new file mode 100644 index 000000000..ac39d9a51 --- /dev/null +++ b/scripts/script-helper @@ -0,0 +1,13 @@ +#!/usr/bin/env bash + +set -e +set -o pipefail + +java_version=$(java -version 2>&1 | java -version 2>&1 | awk -F '"' '/version/ {print $2}') + +if [[ $java_version = 9* ]] ; then + echo "The build is using Java 9 ($java_version). We need additional JVM parameters" + export _JAVA_OPTIONS="$_JAVA_OPTIONS --add-modules=java.xml.bind" +else + echo "The build is NOT using Java 9 ($java_version). No addional JVM params needed." +fi diff --git a/scripts/test-gradle b/scripts/test-gradle new file mode 100755 index 000000000..298c7ebe1 --- /dev/null +++ b/scripts/test-gradle @@ -0,0 +1,13 @@ +#!/usr/bin/env bash + +. "$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )/script-helper" + +# Using cut because TRAVIS_SCALA_VERSION is the full Scala +# version (for example 2.12.4), but Gradle expects just the +# binary version (for example 2.12) +scala_binary_version=$(echo $TRAVIS_SCALA_VERSION | cut -c1-4) + +echo "+------------------------------+" +echo "| Executing tests using Gradle |" +echo "+------------------------------+" +./gradlew -Dscala.binary.version=$scala_binary_version test -i --stacktrace diff --git a/scripts/test-sbt b/scripts/test-sbt new file mode 100755 index 000000000..0425367b1 --- /dev/null +++ b/scripts/test-sbt @@ -0,0 +1,8 @@ +#!/usr/bin/env bash + +. "$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )/script-helper" + +echo "+----------------------------+" +echo "| Executing tests using sbt |" +echo "+----------------------------+" +sbt ++$TRAVIS_SCALA_VERSION test diff --git a/settings.gradle b/settings.gradle new file mode 100644 index 000000000..49f1ac7c3 --- /dev/null +++ b/settings.gradle @@ -0,0 +1,4 @@ +include 'one', 'two' + +project(':one').projectDir = new File(settingsDir, 'modules/one') +project(':two').projectDir = new File(settingsDir, 'modules/two') From 33dbd723d850ffab400179bc6b3c0b092a5f4041 Mon Sep 17 00:00:00 2001 From: Greg Methvin Date: Thu, 21 Dec 2017 17:23:25 -0800 Subject: [PATCH 34/53] Updated with template-control on 2017-12-21T20:59:17.421Z (#50) **/plugins.sbt: addSbtPlugin("com.typesafe.play" % "sbt-plugin" % "2.6.10") **/build.gradle: def playVersion = "2.6.10" **/build.gradle: def playVersion = "2.6.10" --- modules/one/build.gradle | 2 +- modules/two/build.gradle | 2 +- project/plugins.sbt | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/modules/one/build.gradle b/modules/one/build.gradle index 9aa55bfc7..4a1336eea 100644 --- a/modules/one/build.gradle +++ b/modules/one/build.gradle @@ -2,7 +2,7 @@ plugins { id 'play' } -def playVersion = '2.6.9' +def playVersion = "2.6.10" def scalaVersion = System.getProperty("scala.binary.version", /* default = */ "2.12") model { diff --git a/modules/two/build.gradle b/modules/two/build.gradle index f623f489e..ab7b00112 100644 --- a/modules/two/build.gradle +++ b/modules/two/build.gradle @@ -2,7 +2,7 @@ plugins { id 'play' } -def playVersion = '2.6.9' +def playVersion = "2.6.10" def scalaVersion = System.getProperty("scala.binary.version", /* default = */ "2.12") model { diff --git a/project/plugins.sbt b/project/plugins.sbt index 4fb584732..8b2aa417b 100644 --- a/project/plugins.sbt +++ b/project/plugins.sbt @@ -1,3 +1,3 @@ // The Play plugin -addSbtPlugin("com.typesafe.play" % "sbt-plugin" % "2.6.9") +addSbtPlugin("com.typesafe.play" % "sbt-plugin" % "2.6.10") From 83b934430270b6a72666e2ad6d342a0251ec2523 Mon Sep 17 00:00:00 2001 From: Marcos Pereira Date: Tue, 2 Jan 2018 17:12:36 -0200 Subject: [PATCH 35/53] Upgrade branch 2.6.x using TemplateControl (#51) * Updated with template-control on 2017-12-22T16:49:12.933Z **/test-gradle: ./gradlew -Dscala.binary.version=$scala_binary_version check -i --stacktrace * Add run permission to test-gradle script --- scripts/test-gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/test-gradle b/scripts/test-gradle index 298c7ebe1..84a051a20 100755 --- a/scripts/test-gradle +++ b/scripts/test-gradle @@ -10,4 +10,4 @@ scala_binary_version=$(echo $TRAVIS_SCALA_VERSION | cut -c1-4) echo "+------------------------------+" echo "| Executing tests using Gradle |" echo "+------------------------------+" -./gradlew -Dscala.binary.version=$scala_binary_version test -i --stacktrace +./gradlew -Dscala.binary.version=$scala_binary_version check -i --stacktrace From 9a210ab8cf494a900eb5108071b7e5cf7f7bef42 Mon Sep 17 00:00:00 2001 From: Marcos Pereira Date: Wed, 10 Jan 2018 07:30:23 -0200 Subject: [PATCH 36/53] Upgrade branch 2.6.x using TemplateControl (#53) * Updated with template-control on 2018-01-09T20:17:24.597Z **/build.properties: sbt.version=1.1.0 **/build.properties: sbt.version=1.1.0 **/build.properties: sbt.version=1.1.0 **build.gradle: def playVersion = "2.6.10" * test-gradle-permissions --- build.gradle | 4 ++-- modules/one/project/build.properties | 2 +- modules/two/project/build.properties | 2 +- project/build.properties | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/build.gradle b/build.gradle index dc07e4fd8..0cef47d66 100644 --- a/build.gradle +++ b/build.gradle @@ -3,7 +3,7 @@ plugins { id 'idea' } -def playVersion = '2.6.9' +def playVersion = "2.6.10" def scalaVersion = System.getProperty("scala.binary.version", /* default = */ "2.12") model { @@ -46,4 +46,4 @@ allprojects { layout "ivy" } } -} \ No newline at end of file +} diff --git a/modules/one/project/build.properties b/modules/one/project/build.properties index 696ecdc78..e0899f82b 100644 --- a/modules/one/project/build.properties +++ b/modules/one/project/build.properties @@ -1,4 +1,4 @@ #Activator-generated Properties #Fri Jul 08 22:56:54 PDT 2016 template.uuid=f57599cf-a4f5-4333-9ff1-55d48fd49891 -sbt.version=1.0.4 +sbt.version=1.1.0 diff --git a/modules/two/project/build.properties b/modules/two/project/build.properties index 394cb75cf..8b697bbb9 100644 --- a/modules/two/project/build.properties +++ b/modules/two/project/build.properties @@ -1 +1 @@ -sbt.version=1.0.4 +sbt.version=1.1.0 diff --git a/project/build.properties b/project/build.properties index dfb91dd51..b32ec7993 100644 --- a/project/build.properties +++ b/project/build.properties @@ -1,4 +1,4 @@ #Activator-generated Properties #Sun Jul 06 17:54:30 PDT 2014 template.uuid=af582966-096a-43df-a504-5ddae8d4ebf1 -sbt.version=1.0.4 +sbt.version=1.1.0 From 0f1227fb8bb4f9b3400bdc2bd655fbee2f3a5bcb Mon Sep 17 00:00:00 2001 From: Marcos Pereira Date: Thu, 11 Jan 2018 18:18:09 -0200 Subject: [PATCH 37/53] Fix cross build to sbt 1.1.0 (#54) --- build.sbt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/build.sbt b/build.sbt index 059f192eb..b1a5a7fb7 100644 --- a/build.sbt +++ b/build.sbt @@ -13,6 +13,8 @@ lazy val root = (project in file(".")) scalaVersion := "2.12.4" +crossScalaVersions := Seq("2.11.12", "2.12.4") + libraryDependencies += ws libraryDependencies += guice libraryDependencies += "org.scalatestplus.play" %% "scalatestplus-play" % "3.1.2" % Test From fe36bb884da7be92b963aa0fb66646424a5ccbf7 Mon Sep 17 00:00:00 2001 From: Marcos Pereira Date: Sat, 13 Jan 2018 00:27:22 -0200 Subject: [PATCH 38/53] Upgrade branch 2.6.x using TemplateControl (#55) * Updated with template-control on 2018-01-11T21:32:27.852Z **/plugins.sbt: addSbtPlugin("com.typesafe.play" % "sbt-plugin" % "2.6.11") **build.gradle: def playVersion = "2.6.11" **build.gradle: def playVersion = "2.6.11" **build.gradle: def playVersion = "2.6.11" * test-gradle-permissions --- build.gradle | 2 +- modules/one/build.gradle | 2 +- modules/two/build.gradle | 2 +- project/plugins.sbt | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/build.gradle b/build.gradle index 0cef47d66..4b40dbe3d 100644 --- a/build.gradle +++ b/build.gradle @@ -3,7 +3,7 @@ plugins { id 'idea' } -def playVersion = "2.6.10" +def playVersion = "2.6.11" def scalaVersion = System.getProperty("scala.binary.version", /* default = */ "2.12") model { diff --git a/modules/one/build.gradle b/modules/one/build.gradle index 4a1336eea..b37c863c5 100644 --- a/modules/one/build.gradle +++ b/modules/one/build.gradle @@ -2,7 +2,7 @@ plugins { id 'play' } -def playVersion = "2.6.10" +def playVersion = "2.6.11" def scalaVersion = System.getProperty("scala.binary.version", /* default = */ "2.12") model { diff --git a/modules/two/build.gradle b/modules/two/build.gradle index ab7b00112..8bcbefd65 100644 --- a/modules/two/build.gradle +++ b/modules/two/build.gradle @@ -2,7 +2,7 @@ plugins { id 'play' } -def playVersion = "2.6.10" +def playVersion = "2.6.11" def scalaVersion = System.getProperty("scala.binary.version", /* default = */ "2.12") model { diff --git a/project/plugins.sbt b/project/plugins.sbt index 8b2aa417b..4dfd80710 100644 --- a/project/plugins.sbt +++ b/project/plugins.sbt @@ -1,3 +1,3 @@ // The Play plugin -addSbtPlugin("com.typesafe.play" % "sbt-plugin" % "2.6.10") +addSbtPlugin("com.typesafe.play" % "sbt-plugin" % "2.6.11") From c57119b67b56f59d48eb62845df7ae606598d40e Mon Sep 17 00:00:00 2001 From: Renato Cavalcanti Date: Mon, 26 Nov 2018 11:22:14 +0100 Subject: [PATCH 39/53] Upgrade branch 2.6.x using TemplateControl (#71) This PR was originally triggered by template control but it evolves into a fix for many errors and improvements that were in place for some time: * fixed cross compilations * remove broken jdk9 build * Resolves #74 - added openjdk11 build, but allowed to fail (see #74) * Fixes #57 --- .gitignore | 4 ++-- .travis.yml | 15 ++++++++------- README.md | 2 +- build.gradle | 2 +- build.sbt | 4 +--- gradle/wrapper/gradle-wrapper.properties | 2 +- modules/one/build.gradle | 2 +- modules/one/build.sbt | 3 +-- modules/one/project/build.properties | 5 +---- modules/two/build.gradle | 2 +- modules/two/build.sbt | 3 +-- modules/two/project/build.properties | 2 +- play | 21 +++++++++++++++++---- project/build.properties | 5 +---- project/plugins.sbt | 2 +- scripts/script-helper | 10 ++-------- scripts/test-gradle | 7 +------ scripts/test-sbt | 2 +- 18 files changed, 43 insertions(+), 50 deletions(-) diff --git a/.gitignore b/.gitignore index c28bf5538..16d6623e8 100644 --- a/.gitignore +++ b/.gitignore @@ -13,6 +13,6 @@ dist /certs /.idea_modules /.classpath -/.project +.project /RUNNING_PID -/.settings +.settings diff --git a/.travis.yml b/.travis.yml index 981dece36..d998d9631 100644 --- a/.travis.yml +++ b/.travis.yml @@ -2,11 +2,10 @@ language: scala scala: # When updating Scala versions, also check the excludes # in build matrix below. -- 2.11.12 -- 2.12.4 +- 2.12.7 jdk: - oraclejdk8 -- oraclejdk9 +- openjdk11 env: matrix: - SCRIPT=scripts/test-sbt @@ -25,10 +24,12 @@ before_cache: # Exclude some combinations from build matrix. See: # https://docs.travis-ci.com/user/customizing-the-build/#Build-Matrix matrix: - exclude: - - scala: 2.11.12 - jdk: oraclejdk9 - + allow_failures: + # We are not fully validating for Java 11 yet, so we allow this to + # failure until we tackle all the problems. Anyway, having it at the + # build helps us to track the progress and discover problems sooner. + - jdk: openjdk11 + # See https://blog.travis-ci.com/2014-03-13-slack-notifications/ # created with travis encrypt command line tool notifications: diff --git a/README.md b/README.md index 591a71af3..6b6446176 100644 --- a/README.md +++ b/README.md @@ -45,7 +45,7 @@ $ sudo vi /etc/hosts Now that you've generated the certificates and added the `example.com` host entries to `/etc/hosts`, you can start Play itself. -This application is not run with `activator` -- you should run it with `./play` instead, as there are a number of system properties required to use it effectively. +This application is not run with `sbt` -- you should run it with `./play` instead, as there are a number of system properties required to use it effectively. The `CustomSSLEngineProvider` is responsible for Play's HTTPS server. More details can be found in [Configuring HTTPS](http://www.playframework.com/documentation/2.5.x/ConfiguringHttps). diff --git a/build.gradle b/build.gradle index 4b40dbe3d..6737b5a48 100644 --- a/build.gradle +++ b/build.gradle @@ -3,7 +3,7 @@ plugins { id 'idea' } -def playVersion = "2.6.11" +def playVersion = "2.6.20" def scalaVersion = System.getProperty("scala.binary.version", /* default = */ "2.12") model { diff --git a/build.sbt b/build.sbt index b1a5a7fb7..31ab1d933 100644 --- a/build.sbt +++ b/build.sbt @@ -11,9 +11,7 @@ lazy val root = (project in file(".")) .aggregate(one, two) .dependsOn(one, two) -scalaVersion := "2.12.4" - -crossScalaVersions := Seq("2.11.12", "2.12.4") +scalaVersion := "2.12.7" libraryDependencies += ws libraryDependencies += guice diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 5ce78ed19..89dba2d9d 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,4 +1,4 @@ -distributionUrl=https\://services.gradle.org/distributions/gradle-4.4-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-4.9-bin.zip distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists zipStorePath=wrapper/dists diff --git a/modules/one/build.gradle b/modules/one/build.gradle index b37c863c5..eabe15855 100644 --- a/modules/one/build.gradle +++ b/modules/one/build.gradle @@ -2,7 +2,7 @@ plugins { id 'play' } -def playVersion = "2.6.11" +def playVersion = "2.6.20" def scalaVersion = System.getProperty("scala.binary.version", /* default = */ "2.12") model { diff --git a/modules/one/build.sbt b/modules/one/build.sbt index 98597746a..4c5694690 100644 --- a/modules/one/build.sbt +++ b/modules/one/build.sbt @@ -1,2 +1 @@ - -scalaVersion := "2.12.4" +scalaVersion := "2.12.7" \ No newline at end of file diff --git a/modules/one/project/build.properties b/modules/one/project/build.properties index e0899f82b..7c58a83ab 100644 --- a/modules/one/project/build.properties +++ b/modules/one/project/build.properties @@ -1,4 +1 @@ -#Activator-generated Properties -#Fri Jul 08 22:56:54 PDT 2016 -template.uuid=f57599cf-a4f5-4333-9ff1-55d48fd49891 -sbt.version=1.1.0 +sbt.version=1.2.6 diff --git a/modules/two/build.gradle b/modules/two/build.gradle index 8bcbefd65..2dab8ea13 100644 --- a/modules/two/build.gradle +++ b/modules/two/build.gradle @@ -2,7 +2,7 @@ plugins { id 'play' } -def playVersion = "2.6.11" +def playVersion = "2.6.20" def scalaVersion = System.getProperty("scala.binary.version", /* default = */ "2.12") model { diff --git a/modules/two/build.sbt b/modules/two/build.sbt index 98597746a..4c5694690 100644 --- a/modules/two/build.sbt +++ b/modules/two/build.sbt @@ -1,2 +1 @@ - -scalaVersion := "2.12.4" +scalaVersion := "2.12.7" \ No newline at end of file diff --git a/modules/two/project/build.properties b/modules/two/project/build.properties index 8b697bbb9..7c58a83ab 100644 --- a/modules/two/project/build.properties +++ b/modules/two/project/build.properties @@ -1 +1 @@ -sbt.version=1.1.0 +sbt.version=1.2.6 diff --git a/play b/play index b6cc9ebfb..02e4ba101 100755 --- a/play +++ b/play @@ -1,7 +1,5 @@ #!/bin/bash -SBT=sbt - DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" # Export the keystore password for use in ws.conf @@ -63,8 +61,23 @@ JVM_OPTIONS="$JVM_OPTIONS -Dsun.security.ssl.allowLegacyHelloMessages=false" JVM_OPTIONS="$JVM_OPTIONS -Dkey.password=$KEY_PASSWORD" JVM_OPTIONS="$JVM_OPTIONS -DcertificateDirectory=$DIR/scripts" -AGENT=$DIR/target/universal/stage/jetty-alpn-agent/jetty-alpn-agent-2.0.6.jar +# ssl-play requires an ALPN Agent. This is downdloaded and stored in the target folder. +# This snippet detects when the ALPN agent hasn't been downloaded yet and runs +# `sbt stage` to obtain it. +export AGENT_TEST=$(pwd)/$(find target -name 'jetty-alpn-agent-*.jar') +export NUM_AGENTS_FOUND=$(echo $AGENT_TEST| grep target | wc -l) + +if [ $NUM_AGENTS_FOUND -eq "0" ]; then + echo "No ALPN Agent jar found, running 'sbt stage'" + sbt stage; +fi +# Start `sbt` with the JVM_OPTIONS and the ALPN agent +export AGENT=$(pwd)/$(find target -name 'jetty-alpn-agent-*.jar' | head -1) +echo "Detected ALPN Agent: $AGENT " # Run Play (this should work for both run and start). -SBT_OPTS=-javaagent:$AGENT $SBT $JVM_OPTIONS "$* $JVM_OPTIONS"; +export SBT_OPTS="$SBT_OPTS -javaagent:$AGENT" + +# Run Play +sbt $JVM_OPTIONS $*; \ No newline at end of file diff --git a/project/build.properties b/project/build.properties index b32ec7993..2e6e3d246 100644 --- a/project/build.properties +++ b/project/build.properties @@ -1,4 +1 @@ -#Activator-generated Properties -#Sun Jul 06 17:54:30 PDT 2014 -template.uuid=af582966-096a-43df-a504-5ddae8d4ebf1 -sbt.version=1.1.0 +sbt.version=1.2.6 \ No newline at end of file diff --git a/project/plugins.sbt b/project/plugins.sbt index 4dfd80710..e8850b751 100644 --- a/project/plugins.sbt +++ b/project/plugins.sbt @@ -1,3 +1,3 @@ // The Play plugin -addSbtPlugin("com.typesafe.play" % "sbt-plugin" % "2.6.11") +addSbtPlugin("com.typesafe.play" % "sbt-plugin" % "2.6.20") diff --git a/scripts/script-helper b/scripts/script-helper index ac39d9a51..4d008f598 100644 --- a/scripts/script-helper +++ b/scripts/script-helper @@ -3,11 +3,5 @@ set -e set -o pipefail -java_version=$(java -version 2>&1 | java -version 2>&1 | awk -F '"' '/version/ {print $2}') - -if [[ $java_version = 9* ]] ; then - echo "The build is using Java 9 ($java_version). We need additional JVM parameters" - export _JAVA_OPTIONS="$_JAVA_OPTIONS --add-modules=java.xml.bind" -else - echo "The build is NOT using Java 9 ($java_version). No addional JVM params needed." -fi +# Export the keystore password for use in ws.conf +export KEY_PASSWORD=`cat scripts/password` \ No newline at end of file diff --git a/scripts/test-gradle b/scripts/test-gradle index 84a051a20..fdd4151fe 100755 --- a/scripts/test-gradle +++ b/scripts/test-gradle @@ -2,12 +2,7 @@ . "$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )/script-helper" -# Using cut because TRAVIS_SCALA_VERSION is the full Scala -# version (for example 2.12.4), but Gradle expects just the -# binary version (for example 2.12) -scala_binary_version=$(echo $TRAVIS_SCALA_VERSION | cut -c1-4) - echo "+------------------------------+" echo "| Executing tests using Gradle |" echo "+------------------------------+" -./gradlew -Dscala.binary.version=$scala_binary_version check -i --stacktrace +./gradlew check -i --stacktrace diff --git a/scripts/test-sbt b/scripts/test-sbt index 0425367b1..7d4f4ef7a 100755 --- a/scripts/test-sbt +++ b/scripts/test-sbt @@ -5,4 +5,4 @@ echo "+----------------------------+" echo "| Executing tests using sbt |" echo "+----------------------------+" -sbt ++$TRAVIS_SCALA_VERSION test +sbt test From 36617c7c3eca1d3dda0a226e4a31415cc76966d8 Mon Sep 17 00:00:00 2001 From: Renato Cavalcanti Date: Mon, 26 Nov 2018 16:52:45 +0100 Subject: [PATCH 40/53] AkkaHttpServer.Context - removed usage of deprecated API (#76) --- test/integration/GuiceOneHttpsServerPerTest.scala | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/test/integration/GuiceOneHttpsServerPerTest.scala b/test/integration/GuiceOneHttpsServerPerTest.scala index cc1885349..1da264ac4 100644 --- a/test/integration/GuiceOneHttpsServerPerTest.scala +++ b/test/integration/GuiceOneHttpsServerPerTest.scala @@ -5,6 +5,8 @@ import play.api.test.{Helpers, TestServer} import play.api.{Application, Mode} import org.scalatest._ import org.scalatestplus.play.guice.GuiceFakeApplicationFactory +import play.core.server +import play.core.server.AkkaHttpServer.Context import play.core.server.{AkkaHttpServer, ServerConfig, ServerProvider} /** @@ -56,7 +58,6 @@ trait GuiceOneHttpsServerPerTest extends TestSuiteMixin with ServerProvider with } def createServer(context: ServerProvider.Context) = - new AkkaHttpServer(context.config, context.appProvider, context.actorSystem, context.materializer, - context.stopHook) + new AkkaHttpServer(AkkaHttpServer.Context.fromServerProviderContext(context)) } From c419e2dfca602a7367db1b5772194598324959ac Mon Sep 17 00:00:00 2001 From: Renato Cavalcanti Date: Wed, 28 Nov 2018 16:45:15 +0100 Subject: [PATCH 41/53] mergify file (#77) --- .mergify.yml | 37 +++++++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) create mode 100644 .mergify.yml diff --git a/.mergify.yml b/.mergify.yml new file mode 100644 index 000000000..e03e1c309 --- /dev/null +++ b/.mergify.yml @@ -0,0 +1,37 @@ +pull_request_rules: + + - name: automatic merge 2.6.x on CI success + conditions: + - status-success=continuous-integration/travis-ci/pr + - base=2.6.x + - label=merge-when-green + - label!=work-in-progress + actions: + merge: + method: merge + strict: smart + + - name: automatic merge 2.7.x on CI success + conditions: + - status-success=continuous-integration/travis-ci/pr + - base=2.7.x + - label=merge-when-green + - label!=work-in-progress + actions: + merge: + method: merge + strict: smart + + - name: delete branch after merge + conditions: + - merged + actions: + delete_head_branch: {} + + - name: remove label after merge + conditions: + - merged + - label=[merge-when-green] + actions: + label: + remove: [merge-when-green] \ No newline at end of file From d51edadf09d491802a1348ff0b53ec2da80f3d91 Mon Sep 17 00:00:00 2001 From: Renato Cavalcanti Date: Wed, 28 Nov 2018 17:20:33 +0100 Subject: [PATCH 42/53] minor mergify improvements (#78) --- .mergify.yml | 24 ++++++++++++++++++------ 1 file changed, 18 insertions(+), 6 deletions(-) diff --git a/.mergify.yml b/.mergify.yml index e03e1c309..40591346b 100644 --- a/.mergify.yml +++ b/.mergify.yml @@ -1,9 +1,9 @@ pull_request_rules: - - - name: automatic merge 2.6.x on CI success + - name: automatic merge on CI success require review conditions: - status-success=continuous-integration/travis-ci/pr - - base=2.6.x + - "#approved-reviews-by>=1" + - "#changes-requested-reviews-by=0" - label=merge-when-green - label!=work-in-progress actions: @@ -11,27 +11,39 @@ pull_request_rules: method: merge strict: smart - - name: automatic merge 2.7.x on CI success + - name: automatic merge on CI success for TemplateControl conditions: - status-success=continuous-integration/travis-ci/pr - - base=2.7.x - label=merge-when-green + - label=template-control - label!=work-in-progress actions: merge: method: merge strict: smart + # delete any branch when already merged + # doesn't matter if marked with labels or not - name: delete branch after merge conditions: - merged actions: delete_head_branch: {} + # delete 'merge-when-green' label if present and merged - name: remove label after merge conditions: - merged - label=[merge-when-green] actions: label: - remove: [merge-when-green] \ No newline at end of file + remove: [merge-when-green] + + # delete 'template-control' label if present and merged + - name: remove label after merge + conditions: + - merged + - label=[template-control] + actions: + label: + remove: [template-control] \ No newline at end of file From 6224f082b688cd29b4d5f28ce3a0c141ed24f967 Mon Sep 17 00:00:00 2001 From: Renato Cavalcanti Date: Wed, 28 Nov 2018 17:36:59 +0100 Subject: [PATCH 43/53] mergify with squash (#79) --- .mergify.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.mergify.yml b/.mergify.yml index 40591346b..d4e59c92b 100644 --- a/.mergify.yml +++ b/.mergify.yml @@ -8,7 +8,7 @@ pull_request_rules: - label!=work-in-progress actions: merge: - method: merge + method: squash strict: smart - name: automatic merge on CI success for TemplateControl @@ -19,7 +19,7 @@ pull_request_rules: - label!=work-in-progress actions: merge: - method: merge + method: squash strict: smart # delete any branch when already merged From 7fbb70f354c0aa2819b6767dc74680652cbf87d7 Mon Sep 17 00:00:00 2001 From: Renato Cavalcanti Date: Wed, 28 Nov 2018 19:41:38 +0100 Subject: [PATCH 44/53] remove array syntax on label conditional check --- .mergify.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.mergify.yml b/.mergify.yml index d4e59c92b..5228c152f 100644 --- a/.mergify.yml +++ b/.mergify.yml @@ -34,7 +34,7 @@ pull_request_rules: - name: remove label after merge conditions: - merged - - label=[merge-when-green] + - label=merge-when-green actions: label: remove: [merge-when-green] @@ -43,7 +43,7 @@ pull_request_rules: - name: remove label after merge conditions: - merged - - label=[template-control] + - label=template-control actions: label: remove: [template-control] \ No newline at end of file From 8645e489eae07f4d02712b8312f9e3e6177f2ab8 Mon Sep 17 00:00:00 2001 From: Renato Cavalcanti Date: Thu, 29 Nov 2018 20:44:12 +0100 Subject: [PATCH 45/53] Upgrade branch 2.6.x using TemplateControl (#83) ``` Updated with template-control on 2018-11-29T16:03:57.815Z /.mergify.yml: wrote /.mergify.yml ``` --- .mergify.yml | 14 +++++++++++--- modules/one/build.sbt | 2 +- modules/two/build.sbt | 2 +- project/build.properties | 2 +- 4 files changed, 14 insertions(+), 6 deletions(-) diff --git a/.mergify.yml b/.mergify.yml index 5228c152f..4a37a16dd 100644 --- a/.mergify.yml +++ b/.mergify.yml @@ -5,7 +5,7 @@ pull_request_rules: - "#approved-reviews-by>=1" - "#changes-requested-reviews-by=0" - label=merge-when-green - - label!=work-in-progress + - label!=block-merge actions: merge: method: squash @@ -16,7 +16,7 @@ pull_request_rules: - status-success=continuous-integration/travis-ci/pr - label=merge-when-green - label=template-control - - label!=work-in-progress + - label!=block-merge actions: merge: method: squash @@ -46,4 +46,12 @@ pull_request_rules: - label=template-control actions: label: - remove: [template-control] \ No newline at end of file + remove: [template-control] + + - name: auto add wip + conditions: + # match a few flavours of wip + - title~=^(\[wip\]( |:) |\[WIP\]( |:) |wip( |:) |WIP( |:)).* + actions: + label: + add: ["block-merge"] \ No newline at end of file diff --git a/modules/one/build.sbt b/modules/one/build.sbt index 4c5694690..1c3d07424 100644 --- a/modules/one/build.sbt +++ b/modules/one/build.sbt @@ -1 +1 @@ -scalaVersion := "2.12.7" \ No newline at end of file +scalaVersion := "2.12.7" diff --git a/modules/two/build.sbt b/modules/two/build.sbt index 4c5694690..1c3d07424 100644 --- a/modules/two/build.sbt +++ b/modules/two/build.sbt @@ -1 +1 @@ -scalaVersion := "2.12.7" \ No newline at end of file +scalaVersion := "2.12.7" diff --git a/project/build.properties b/project/build.properties index 2e6e3d246..7c58a83ab 100644 --- a/project/build.properties +++ b/project/build.properties @@ -1 +1 @@ -sbt.version=1.2.6 \ No newline at end of file +sbt.version=1.2.6 From 32b926665748560c4c8cf459a2db5f750542ad31 Mon Sep 17 00:00:00 2001 From: Dale Wijnand <344610+dwijnand@users.noreply.github.com> Date: Tue, 4 Dec 2018 18:04:57 +0000 Subject: [PATCH 46/53] Make Travis CI fast_finish Fixes #80 --- .travis.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index d998d9631..95b196dfa 100644 --- a/.travis.yml +++ b/.travis.yml @@ -29,9 +29,10 @@ matrix: # failure until we tackle all the problems. Anyway, having it at the # build helps us to track the progress and discover problems sooner. - jdk: openjdk11 + fast_finish: true # See https://blog.travis-ci.com/2014-03-13-slack-notifications/ # created with travis encrypt command line tool notifications: slack: - secure: K6HWTI6zJpQfxS7sH5ZQ1jEK5TkkUl5GtcGinNecHMBqvfS4IXAnU23lz/kLqCqMVPIFaRx1g6UwgJgMvR4XWeIhpzLOzAnOOcmv+kQzv7A8vEJBM20z1HNzDcxzvuNNO2BHn8EjXh5VD65vXMcA+lKzUxASey/Rs+CBReQWE7M= \ No newline at end of file + secure: K6HWTI6zJpQfxS7sH5ZQ1jEK5TkkUl5GtcGinNecHMBqvfS4IXAnU23lz/kLqCqMVPIFaRx1g6UwgJgMvR4XWeIhpzLOzAnOOcmv+kQzv7A8vEJBM20z1HNzDcxzvuNNO2BHn8EjXh5VD65vXMcA+lKzUxASey/Rs+CBReQWE7M= From 45ed2207c8e0207372d903901dbf30fbc9144afe Mon Sep 17 00:00:00 2001 From: Marcos Pereira Date: Fri, 4 Jan 2019 17:51:32 -0500 Subject: [PATCH 47/53] Updated with template-control on 2019-01-04T21:47:52.378Z (#87) /.travis.yml: wrote /.travis.yml **build.sbt: scalaVersion := "2.12.8" **build.sbt: scalaVersion := "2.12.8" **build.sbt: scalaVersion := "2.12.8" **/build.properties: sbt.version=1.2.8 **/build.properties: sbt.version=1.2.8 **/build.properties: sbt.version=1.2.8 --- .travis.yml | 70 ++++++++++++++++------------ build.sbt | 2 +- modules/one/build.sbt | 2 +- modules/one/project/build.properties | 2 +- modules/two/build.sbt | 2 +- modules/two/project/build.properties | 2 +- project/build.properties | 2 +- 7 files changed, 47 insertions(+), 35 deletions(-) diff --git a/.travis.yml b/.travis.yml index 95b196dfa..1e8c0e7c4 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,38 +1,50 @@ language: scala scala: -# When updating Scala versions, also check the excludes -# in build matrix below. -- 2.12.7 -jdk: -- oraclejdk8 -- openjdk11 + - 2.12.8 + +before_install: + - curl -sL https://github.com/shyiko/jabba/raw/master/install.sh | bash && . ~/.jabba/jabba.sh + env: + global: + - JABBA_HOME=$HOME/.jabba matrix: - - SCRIPT=scripts/test-sbt - - SCRIPT=scripts/test-gradle -script: -- $SCRIPT -cache: - directories: - - "$HOME/.ivy2/cache" - - "$HOME/.gradle/caches" -before_cache: -- rm -rf $HOME/.ivy2/cache/com.typesafe.play/* -- rm -rf $HOME/.ivy2/cache/scala_*/sbt_*/com.typesafe.play/* -- find $HOME/.ivy2/cache -name "ivydata-*.properties" -print0 | xargs -n10 -0 rm + # There is no concise way to specify multi-dimensional build matrix: + # https://github.com/travis-ci/travis-ci/issues/1519 + - SCRIPT=scripts/test-sbt TRAVIS_JDK=adopt@1.8.192-12 + - SCRIPT=scripts/test-sbt TRAVIS_JDK=adopt@1.11.0-1 + - SCRIPT=scripts/test-gradle TRAVIS_JDK=adopt@1.8.192-12 + - SCRIPT=scripts/test-gradle TRAVIS_JDK=adopt@1.11.0-1 # Exclude some combinations from build matrix. See: # https://docs.travis-ci.com/user/customizing-the-build/#Build-Matrix matrix: - allow_failures: - # We are not fully validating for Java 11 yet, so we allow this to - # failure until we tackle all the problems. Anyway, having it at the - # build helps us to track the progress and discover problems sooner. - - jdk: openjdk11 fast_finish: true - -# See https://blog.travis-ci.com/2014-03-13-slack-notifications/ -# created with travis encrypt command line tool -notifications: - slack: - secure: K6HWTI6zJpQfxS7sH5ZQ1jEK5TkkUl5GtcGinNecHMBqvfS4IXAnU23lz/kLqCqMVPIFaRx1g6UwgJgMvR4XWeIhpzLOzAnOOcmv+kQzv7A8vEJBM20z1HNzDcxzvuNNO2BHn8EjXh5VD65vXMcA+lKzUxASey/Rs+CBReQWE7M= + allow_failures: + # Current release of Gradle still does not supports Play 2.7.x releases + # As soon as there is a release of Gradle that fixes that, we can then + # remove this allowed failure. + - env: SCRIPT=scripts/test-gradle TRAVIS_JDK=adopt@1.8.192-12 + - env: SCRIPT=scripts/test-gradle TRAVIS_JDK=adopt@1.11.0-1 + # Java 11 is still not fully supported. It is good that we are already + # testing our sample applications to better discover possible problems + # but we can allow failures here too. + - env: SCRIPT=scripts/test-sbt TRAVIS_JDK=adopt@1.11.0-1 + +install: + - $JABBA_HOME/bin/jabba install $TRAVIS_JDK + - unset _JAVA_OPTIONS + - export JAVA_HOME="$JABBA_HOME/jdk/$TRAVIS_JDK" && export PATH="$JAVA_HOME/bin:$PATH" && java -Xmx32m -version + +script: + - $SCRIPT + +before_cache: + - find $HOME/.ivy2 -name "ivydata-*.properties" -delete + - find $HOME/.sbt -name "*.lock" -delete + +cache: + directories: + - "$HOME/.ivy2/cache" + - "$HOME/.gradle/caches" + - "$HOME/.jabba/jdk" diff --git a/build.sbt b/build.sbt index 31ab1d933..66e7355f2 100644 --- a/build.sbt +++ b/build.sbt @@ -11,7 +11,7 @@ lazy val root = (project in file(".")) .aggregate(one, two) .dependsOn(one, two) -scalaVersion := "2.12.7" +scalaVersion := "2.12.8" libraryDependencies += ws libraryDependencies += guice diff --git a/modules/one/build.sbt b/modules/one/build.sbt index 1c3d07424..5642f168f 100644 --- a/modules/one/build.sbt +++ b/modules/one/build.sbt @@ -1 +1 @@ -scalaVersion := "2.12.7" +scalaVersion := "2.12.8" diff --git a/modules/one/project/build.properties b/modules/one/project/build.properties index 7c58a83ab..c0bab0494 100644 --- a/modules/one/project/build.properties +++ b/modules/one/project/build.properties @@ -1 +1 @@ -sbt.version=1.2.6 +sbt.version=1.2.8 diff --git a/modules/two/build.sbt b/modules/two/build.sbt index 1c3d07424..5642f168f 100644 --- a/modules/two/build.sbt +++ b/modules/two/build.sbt @@ -1 +1 @@ -scalaVersion := "2.12.7" +scalaVersion := "2.12.8" diff --git a/modules/two/project/build.properties b/modules/two/project/build.properties index 7c58a83ab..c0bab0494 100644 --- a/modules/two/project/build.properties +++ b/modules/two/project/build.properties @@ -1 +1 @@ -sbt.version=1.2.6 +sbt.version=1.2.8 diff --git a/project/build.properties b/project/build.properties index 7c58a83ab..c0bab0494 100644 --- a/project/build.properties +++ b/project/build.properties @@ -1 +1 @@ -sbt.version=1.2.6 +sbt.version=1.2.8 From 5f3e433017e8e03120c99c9d422903dd41ba3f8d Mon Sep 17 00:00:00 2001 From: Renato Cavalcanti Date: Tue, 8 Jan 2019 17:04:29 +0100 Subject: [PATCH 48/53] Updated with template-control on 2019-01-08T14:44:41.961Z (#93) **/plugins.sbt: addSbtPlugin("com.typesafe.play" % "sbt-plugin" % "2.6.21") **build.gradle: def playVersion = "2.6.21" **build.gradle: playTest "org.scalatestplus.play:scalatestplus-play_\$scalaVersion:3.1.2" **build.gradle: def playVersion = "2.6.21" **build.gradle: def playVersion = "2.6.21" --- build.gradle | 4 ++-- modules/one/build.gradle | 2 +- modules/two/build.gradle | 2 +- project/plugins.sbt | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/build.gradle b/build.gradle index 6737b5a48..7312bde2e 100644 --- a/build.gradle +++ b/build.gradle @@ -3,7 +3,7 @@ plugins { id 'idea' } -def playVersion = "2.6.20" +def playVersion = "2.6.21" def scalaVersion = System.getProperty("scala.binary.version", /* default = */ "2.12") model { @@ -30,7 +30,7 @@ dependencies { play project(":one") play project(":two") - playTest "org.scalatestplus.play:scalatestplus-play_$scalaVersion:3.1.2" + playTest "org.scalatestplus.play:scalatestplus-play_\$scalaVersion:3.1.2" } allprojects { diff --git a/modules/one/build.gradle b/modules/one/build.gradle index eabe15855..68a565bdf 100644 --- a/modules/one/build.gradle +++ b/modules/one/build.gradle @@ -2,7 +2,7 @@ plugins { id 'play' } -def playVersion = "2.6.20" +def playVersion = "2.6.21" def scalaVersion = System.getProperty("scala.binary.version", /* default = */ "2.12") model { diff --git a/modules/two/build.gradle b/modules/two/build.gradle index 2dab8ea13..8fd7554f1 100644 --- a/modules/two/build.gradle +++ b/modules/two/build.gradle @@ -2,7 +2,7 @@ plugins { id 'play' } -def playVersion = "2.6.20" +def playVersion = "2.6.21" def scalaVersion = System.getProperty("scala.binary.version", /* default = */ "2.12") model { diff --git a/project/plugins.sbt b/project/plugins.sbt index e8850b751..f9c49a60a 100644 --- a/project/plugins.sbt +++ b/project/plugins.sbt @@ -1,3 +1,3 @@ // The Play plugin -addSbtPlugin("com.typesafe.play" % "sbt-plugin" % "2.6.20") +addSbtPlugin("com.typesafe.play" % "sbt-plugin" % "2.6.21") From 2e9833579822ad92a0de5bf6e3531adfd2ac6247 Mon Sep 17 00:00:00 2001 From: Renato Cavalcanti Date: Wed, 16 Jan 2019 13:53:42 +0100 Subject: [PATCH 49/53] Upgrade branch 2.6.x using TemplateControl (#96) ``` Updated with template-control on 2019-01-16T12:08:46.175Z /LICENSE: wrote /LICENSE /NOTICE: wrote /NOTICE /.mergify.yml: wrote /.mergify.yml **build.gradle: playTest "org.scalatestplus.play:scalatestplus-play_$scalaVersion:3.1.2" ``` --- .mergify.yml | 10 ++--- LICENSE | 119 ++++++++++++++++++++++++++++++++++++++++++++++++--- NOTICE | 8 ++++ build.gradle | 2 +- 4 files changed, 126 insertions(+), 13 deletions(-) create mode 100644 NOTICE diff --git a/.mergify.yml b/.mergify.yml index 4a37a16dd..3549efd41 100644 --- a/.mergify.yml +++ b/.mergify.yml @@ -22,16 +22,13 @@ pull_request_rules: method: squash strict: smart - # delete any branch when already merged - # doesn't matter if marked with labels or not - name: delete branch after merge conditions: - merged actions: delete_head_branch: {} - # delete 'merge-when-green' label if present and merged - - name: remove label after merge + - name: remove merge-when-green label after merge conditions: - merged - label=merge-when-green @@ -39,8 +36,7 @@ pull_request_rules: label: remove: [merge-when-green] - # delete 'template-control' label if present and merged - - name: remove label after merge + - name: remove template-control label after merge conditions: - merged - label=template-control @@ -54,4 +50,4 @@ pull_request_rules: - title~=^(\[wip\]( |:) |\[WIP\]( |:) |wip( |:) |WIP( |:)).* actions: label: - add: ["block-merge"] \ No newline at end of file + add: ["block-merge"] diff --git a/LICENSE b/LICENSE index b018ae2bc..670154e35 100644 --- a/LICENSE +++ b/LICENSE @@ -1,7 +1,116 @@ -License -------- -Written in 2016 by Lightbend +CC0 1.0 Universal -To the extent possible under law, the author(s) have dedicated all copyright and related and neighboring rights to this software to the public domain worldwide. This software is distributed without any warranty. +Statement of Purpose -You should have received a copy of the CC0 Public Domain Dedication along with this software. If not, see . +The laws of most jurisdictions throughout the world automatically confer +exclusive Copyright and Related Rights (defined below) upon the creator and +subsequent owner(s) (each and all, an "owner") of an original work of +authorship and/or a database (each, a "Work"). + +Certain owners wish to permanently relinquish those rights to a Work for the +purpose of contributing to a commons of creative, cultural and scientific +works ("Commons") that the public can reliably and without fear of later +claims of infringement build upon, modify, incorporate in other works, reuse +and redistribute as freely as possible in any form whatsoever and for any +purposes, including without limitation commercial purposes. These owners may +contribute to the Commons to promote the ideal of a free culture and the +further production of creative, cultural and scientific works, or to gain +reputation or greater distribution for their Work in part through the use and +efforts of others. + +For these and/or other purposes and motivations, and without any expectation +of additional consideration or compensation, the person associating CC0 with a +Work (the "Affirmer"), to the extent that he or she is an owner of Copyright +and Related Rights in the Work, voluntarily elects to apply CC0 to the Work +and publicly distribute the Work under its terms, with knowledge of his or her +Copyright and Related Rights in the Work and the meaning and intended legal +effect of CC0 on those rights. + +1. Copyright and Related Rights. A Work made available under CC0 may be +protected by copyright and related or neighboring rights ("Copyright and +Related Rights"). Copyright and Related Rights include, but are not limited +to, the following: + + i. the right to reproduce, adapt, distribute, perform, display, communicate, + and translate a Work; + + ii. moral rights retained by the original author(s) and/or performer(s); + + iii. publicity and privacy rights pertaining to a person's image or likeness + depicted in a Work; + + iv. rights protecting against unfair competition in regards to a Work, + subject to the limitations in paragraph 4(a), below; + + v. rights protecting the extraction, dissemination, use and reuse of data in + a Work; + + vi. database rights (such as those arising under Directive 96/9/EC of the + European Parliament and of the Council of 11 March 1996 on the legal + protection of databases, and under any national implementation thereof, + including any amended or successor version of such directive); and + + vii. other similar, equivalent or corresponding rights throughout the world + based on applicable law or treaty, and any national implementations thereof. + +2. Waiver. To the greatest extent permitted by, but not in contravention of, +applicable law, Affirmer hereby overtly, fully, permanently, irrevocably and +unconditionally waives, abandons, and surrenders all of Affirmer's Copyright +and Related Rights and associated claims and causes of action, whether now +known or unknown (including existing as well as future claims and causes of +action), in the Work (i) in all territories worldwide, (ii) for the maximum +duration provided by applicable law or treaty (including future time +extensions), (iii) in any current or future medium and for any number of +copies, and (iv) for any purpose whatsoever, including without limitation +commercial, advertising or promotional purposes (the "Waiver"). Affirmer makes +the Waiver for the benefit of each member of the public at large and to the +detriment of Affirmer's heirs and successors, fully intending that such Waiver +shall not be subject to revocation, rescission, cancellation, termination, or +any other legal or equitable action to disrupt the quiet enjoyment of the Work +by the public as contemplated by Affirmer's express Statement of Purpose. + +3. Public License Fallback. Should any part of the Waiver for any reason be +judged legally invalid or ineffective under applicable law, then the Waiver +shall be preserved to the maximum extent permitted taking into account +Affirmer's express Statement of Purpose. In addition, to the extent the Waiver +is so judged Affirmer hereby grants to each affected person a royalty-free, +non transferable, non sublicensable, non exclusive, irrevocable and +unconditional license to exercise Affirmer's Copyright and Related Rights in +the Work (i) in all territories worldwide, (ii) for the maximum duration +provided by applicable law or treaty (including future time extensions), (iii) +in any current or future medium and for any number of copies, and (iv) for any +purpose whatsoever, including without limitation commercial, advertising or +promotional purposes (the "License"). The License shall be deemed effective as +of the date CC0 was applied by Affirmer to the Work. Should any part of the +License for any reason be judged legally invalid or ineffective under +applicable law, such partial invalidity or ineffectiveness shall not +invalidate the remainder of the License, and in such case Affirmer hereby +affirms that he or she will not (i) exercise any of his or her remaining +Copyright and Related Rights in the Work or (ii) assert any associated claims +and causes of action with respect to the Work, in either case contrary to +Affirmer's express Statement of Purpose. + +4. Limitations and Disclaimers. + + a. No trademark or patent rights held by Affirmer are waived, abandoned, + surrendered, licensed or otherwise affected by this document. + + b. Affirmer offers the Work as-is and makes no representations or warranties + of any kind concerning the Work, express, implied, statutory or otherwise, + including without limitation warranties of title, merchantability, fitness + for a particular purpose, non infringement, or the absence of latent or + other defects, accuracy, or the present or absence of errors, whether or not + discoverable, all to the greatest extent permissible under applicable law. + + c. Affirmer disclaims responsibility for clearing rights of other persons + that may apply to the Work or any use thereof, including without limitation + any person's Copyright and Related Rights in the Work. Further, Affirmer + disclaims responsibility for obtaining any necessary consents, permissions + or other rights required for any use of the Work. + + d. Affirmer understands and acknowledges that Creative Commons is not a + party to this document and has no duty or obligation with respect to this + CC0 or use of the Work. + +For more information, please see + diff --git a/NOTICE b/NOTICE new file mode 100644 index 000000000..6d6c034d3 --- /dev/null +++ b/NOTICE @@ -0,0 +1,8 @@ +Written by Lightbend + +To the extent possible under law, the author(s) have dedicated all copyright and +related and neighboring rights to this software to the public domain worldwide. +This software is distributed without any warranty. + +You should have received a copy of the CC0 Public Domain Dedication along with +this software. If not, see . diff --git a/build.gradle b/build.gradle index 7312bde2e..a623cebe2 100644 --- a/build.gradle +++ b/build.gradle @@ -30,7 +30,7 @@ dependencies { play project(":one") play project(":two") - playTest "org.scalatestplus.play:scalatestplus-play_\$scalaVersion:3.1.2" + playTest "org.scalatestplus.play:scalatestplus-play_$scalaVersion:3.1.2" } allprojects { From 089a86580872feae295561a1cafa4375874763b8 Mon Sep 17 00:00:00 2001 From: Renato Cavalcanti Date: Thu, 17 Jan 2019 17:45:26 +0100 Subject: [PATCH 50/53] Upgrade branch 2.6.x using TemplateControl (#97) ``` Updated with template-control on 2019-01-17T15:10:58.085Z /.mergify.yml: wrote /.mergify.yml ``` --- .mergify.yml | 18 ------------------ 1 file changed, 18 deletions(-) diff --git a/.mergify.yml b/.mergify.yml index 3549efd41..b215a7709 100644 --- a/.mergify.yml +++ b/.mergify.yml @@ -4,7 +4,6 @@ pull_request_rules: - status-success=continuous-integration/travis-ci/pr - "#approved-reviews-by>=1" - "#changes-requested-reviews-by=0" - - label=merge-when-green - label!=block-merge actions: merge: @@ -15,7 +14,6 @@ pull_request_rules: conditions: - status-success=continuous-integration/travis-ci/pr - label=merge-when-green - - label=template-control - label!=block-merge actions: merge: @@ -35,19 +33,3 @@ pull_request_rules: actions: label: remove: [merge-when-green] - - - name: remove template-control label after merge - conditions: - - merged - - label=template-control - actions: - label: - remove: [template-control] - - - name: auto add wip - conditions: - # match a few flavours of wip - - title~=^(\[wip\]( |:) |\[WIP\]( |:) |wip( |:) |WIP( |:)).* - actions: - label: - add: ["block-merge"] From 252a9f2e3a5baeda76d73876351be5680577b624 Mon Sep 17 00:00:00 2001 From: Renato Cavalcanti Date: Fri, 1 Feb 2019 14:11:17 +0100 Subject: [PATCH 51/53] Upgrade branch 2.6.x using TemplateControl (#98) ``` Updated with template-control on 2019-02-01T10:40:33.291Z /.mergify.yml: wrote /.mergify.yml ``` --- .mergify.yml | 8 -------- 1 file changed, 8 deletions(-) diff --git a/.mergify.yml b/.mergify.yml index b215a7709..fbbe4380f 100644 --- a/.mergify.yml +++ b/.mergify.yml @@ -25,11 +25,3 @@ pull_request_rules: - merged actions: delete_head_branch: {} - - - name: remove merge-when-green label after merge - conditions: - - merged - - label=merge-when-green - actions: - label: - remove: [merge-when-green] From e6548367f8b2dc77f51a5bc098297b52477daf2a Mon Sep 17 00:00:00 2001 From: Marcos Pereira Date: Thu, 14 Feb 2019 00:39:37 -0500 Subject: [PATCH 52/53] Updated with template-control on 2019-02-13T20:25:39.799Z (#100) /.mergify.yml: wrote /.mergify.yml --- .mergify.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.mergify.yml b/.mergify.yml index fbbe4380f..32f8689ae 100644 --- a/.mergify.yml +++ b/.mergify.yml @@ -1,7 +1,7 @@ pull_request_rules: - name: automatic merge on CI success require review conditions: - - status-success=continuous-integration/travis-ci/pr + - status-success=Travis CI - Pull Request - "#approved-reviews-by>=1" - "#changes-requested-reviews-by=0" - label!=block-merge @@ -12,7 +12,7 @@ pull_request_rules: - name: automatic merge on CI success for TemplateControl conditions: - - status-success=continuous-integration/travis-ci/pr + - status-success=Travis CI - Pull Request - label=merge-when-green - label!=block-merge actions: From dc755991953bc0cad5e6835f5adf448f6b1ad518 Mon Sep 17 00:00:00 2001 From: Dale Wijnand Date: Tue, 23 Apr 2019 15:49:59 +0100 Subject: [PATCH 53/53] Nest play-scala-tls-example --- .gitignore => play-scala-tls-example/.gitignore | 0 .mergify.yml => play-scala-tls-example/.mergify.yml | 0 .travis.yml => play-scala-tls-example/.travis.yml | 0 LICENSE => play-scala-tls-example/LICENSE | 0 NOTICE => play-scala-tls-example/NOTICE | 0 README.md => play-scala-tls-example/README.md | 0 {app => play-scala-tls-example/app}/Main.scala | 0 .../app}/controllers/HomeController.scala | 0 .../app}/https/CustomSSLEngineProvider.scala | 0 .../app}/https/SniKeyManager.scala | 0 .../app}/router/MultiSiteRequestHandler.scala | 0 .../app}/views/index.scala.html | 0 build.gradle => play-scala-tls-example/build.gradle | 0 build.sbt => play-scala-tls-example/build.sbt | 0 .../conf}/application.conf | 0 .../conf}/disabledAlgorithms.properties | 0 .../conf}/generated.keystore | Bin {conf => play-scala-tls-example/conf}/logback.xml | 0 {conf => play-scala-tls-example/conf}/routes | 0 {conf => play-scala-tls-example/conf}/ws.conf | 0 .../gradle}/wrapper/gradle-wrapper.jar | Bin .../gradle}/wrapper/gradle-wrapper.properties | 0 gradlew => play-scala-tls-example/gradlew | 0 gradlew.bat => play-scala-tls-example/gradlew.bat | 0 .../one/app/controllers/HomeController.scala | 0 .../modules}/one/app/views/one/index.scala.html | 0 .../modules}/one/build.gradle | 0 .../modules}/one/build.sbt | 0 .../modules}/one/conf/one.routes | 0 .../modules}/one/project/build.properties | 0 .../two/app/controllers/HomeController.scala | 0 .../modules}/two/app/views/two/index.scala.html | 0 .../modules}/two/build.gradle | 0 .../modules}/two/build.sbt | 0 .../modules}/two/conf/two.routes | 0 .../modules}/two/project/build.properties | 0 play => play-scala-tls-example/play | 0 .../project}/build.properties | 0 .../project}/plugins.sbt | 0 .../scripts}/client.crt | 0 .../scripts}/client.csr | 0 .../scripts}/client.jks | Bin .../scripts}/client.p12 | Bin .../scripts}/clientca.crt | 0 .../scripts}/clientca.jks | Bin .../scripts}/example.com.crt | 0 .../scripts}/example.com.csr | 0 .../scripts}/example.com.jks | Bin .../scripts}/exampleca.crt | 0 .../scripts}/exampleca.jks | Bin .../scripts}/exampletrust.jks | Bin .../scripts}/gen-example.com.sh | 0 .../scripts}/gen-one.example.com.sh | 0 .../scripts}/gen-two.example.com.sh | 0 .../scripts}/gen-wildcard.example.com.sh | 0 .../scripts}/genca.sh | 0 .../scripts}/gencerts.sh | 0 .../scripts}/genclient.sh | 0 .../scripts}/gentrustanchor.sh | 0 .../scripts}/one.example.com.crt | 0 .../scripts}/one.example.com.csr | 0 .../scripts}/password | 0 .../scripts}/script-helper | 0 .../scripts}/test-gradle | 0 .../scripts}/test-sbt | 0 .../scripts}/two.example.com.crt | 0 .../scripts}/two.example.com.csr | 0 .../scripts}/wildcard.example.com.crt | 0 .../scripts}/wildcard.example.com.csr | 0 .../settings.gradle | 0 .../integration/GuiceOneHttpsServerPerTest.scala | 0 .../test}/integration/ServerSpec.scala | 0 .../tutorial}/index.html | 0 73 files changed, 0 insertions(+), 0 deletions(-) rename .gitignore => play-scala-tls-example/.gitignore (100%) rename .mergify.yml => play-scala-tls-example/.mergify.yml (100%) rename .travis.yml => play-scala-tls-example/.travis.yml (100%) rename LICENSE => play-scala-tls-example/LICENSE (100%) rename NOTICE => play-scala-tls-example/NOTICE (100%) rename README.md => play-scala-tls-example/README.md (100%) rename {app => play-scala-tls-example/app}/Main.scala (100%) rename {app => play-scala-tls-example/app}/controllers/HomeController.scala (100%) rename {app => play-scala-tls-example/app}/https/CustomSSLEngineProvider.scala (100%) rename {app => play-scala-tls-example/app}/https/SniKeyManager.scala (100%) rename {app => play-scala-tls-example/app}/router/MultiSiteRequestHandler.scala (100%) rename {app => play-scala-tls-example/app}/views/index.scala.html (100%) rename build.gradle => play-scala-tls-example/build.gradle (100%) rename build.sbt => play-scala-tls-example/build.sbt (100%) rename {conf => play-scala-tls-example/conf}/application.conf (100%) rename {conf => play-scala-tls-example/conf}/disabledAlgorithms.properties (100%) rename {conf => play-scala-tls-example/conf}/generated.keystore (100%) rename {conf => play-scala-tls-example/conf}/logback.xml (100%) rename {conf => play-scala-tls-example/conf}/routes (100%) rename {conf => play-scala-tls-example/conf}/ws.conf (100%) rename {gradle => play-scala-tls-example/gradle}/wrapper/gradle-wrapper.jar (100%) rename {gradle => play-scala-tls-example/gradle}/wrapper/gradle-wrapper.properties (100%) rename gradlew => play-scala-tls-example/gradlew (100%) rename gradlew.bat => play-scala-tls-example/gradlew.bat (100%) rename {modules => play-scala-tls-example/modules}/one/app/controllers/HomeController.scala (100%) rename {modules => play-scala-tls-example/modules}/one/app/views/one/index.scala.html (100%) rename {modules => play-scala-tls-example/modules}/one/build.gradle (100%) rename {modules => play-scala-tls-example/modules}/one/build.sbt (100%) rename {modules => play-scala-tls-example/modules}/one/conf/one.routes (100%) rename {modules => play-scala-tls-example/modules}/one/project/build.properties (100%) rename {modules => play-scala-tls-example/modules}/two/app/controllers/HomeController.scala (100%) rename {modules => play-scala-tls-example/modules}/two/app/views/two/index.scala.html (100%) rename {modules => play-scala-tls-example/modules}/two/build.gradle (100%) rename {modules => play-scala-tls-example/modules}/two/build.sbt (100%) rename {modules => play-scala-tls-example/modules}/two/conf/two.routes (100%) rename {modules => play-scala-tls-example/modules}/two/project/build.properties (100%) rename play => play-scala-tls-example/play (100%) rename {project => play-scala-tls-example/project}/build.properties (100%) rename {project => play-scala-tls-example/project}/plugins.sbt (100%) rename {scripts => play-scala-tls-example/scripts}/client.crt (100%) rename {scripts => play-scala-tls-example/scripts}/client.csr (100%) rename {scripts => play-scala-tls-example/scripts}/client.jks (100%) rename {scripts => play-scala-tls-example/scripts}/client.p12 (100%) rename {scripts => play-scala-tls-example/scripts}/clientca.crt (100%) rename {scripts => play-scala-tls-example/scripts}/clientca.jks (100%) rename {scripts => play-scala-tls-example/scripts}/example.com.crt (100%) rename {scripts => play-scala-tls-example/scripts}/example.com.csr (100%) rename {scripts => play-scala-tls-example/scripts}/example.com.jks (100%) rename {scripts => play-scala-tls-example/scripts}/exampleca.crt (100%) rename {scripts => play-scala-tls-example/scripts}/exampleca.jks (100%) rename {scripts => play-scala-tls-example/scripts}/exampletrust.jks (100%) rename {scripts => play-scala-tls-example/scripts}/gen-example.com.sh (100%) rename {scripts => play-scala-tls-example/scripts}/gen-one.example.com.sh (100%) rename {scripts => play-scala-tls-example/scripts}/gen-two.example.com.sh (100%) rename {scripts => play-scala-tls-example/scripts}/gen-wildcard.example.com.sh (100%) rename {scripts => play-scala-tls-example/scripts}/genca.sh (100%) rename {scripts => play-scala-tls-example/scripts}/gencerts.sh (100%) rename {scripts => play-scala-tls-example/scripts}/genclient.sh (100%) rename {scripts => play-scala-tls-example/scripts}/gentrustanchor.sh (100%) rename {scripts => play-scala-tls-example/scripts}/one.example.com.crt (100%) rename {scripts => play-scala-tls-example/scripts}/one.example.com.csr (100%) rename {scripts => play-scala-tls-example/scripts}/password (100%) rename {scripts => play-scala-tls-example/scripts}/script-helper (100%) rename {scripts => play-scala-tls-example/scripts}/test-gradle (100%) rename {scripts => play-scala-tls-example/scripts}/test-sbt (100%) rename {scripts => play-scala-tls-example/scripts}/two.example.com.crt (100%) rename {scripts => play-scala-tls-example/scripts}/two.example.com.csr (100%) rename {scripts => play-scala-tls-example/scripts}/wildcard.example.com.crt (100%) rename {scripts => play-scala-tls-example/scripts}/wildcard.example.com.csr (100%) rename settings.gradle => play-scala-tls-example/settings.gradle (100%) rename {test => play-scala-tls-example/test}/integration/GuiceOneHttpsServerPerTest.scala (100%) rename {test => play-scala-tls-example/test}/integration/ServerSpec.scala (100%) rename {tutorial => play-scala-tls-example/tutorial}/index.html (100%) diff --git a/.gitignore b/play-scala-tls-example/.gitignore similarity index 100% rename from .gitignore rename to play-scala-tls-example/.gitignore diff --git a/.mergify.yml b/play-scala-tls-example/.mergify.yml similarity index 100% rename from .mergify.yml rename to play-scala-tls-example/.mergify.yml diff --git a/.travis.yml b/play-scala-tls-example/.travis.yml similarity index 100% rename from .travis.yml rename to play-scala-tls-example/.travis.yml diff --git a/LICENSE b/play-scala-tls-example/LICENSE similarity index 100% rename from LICENSE rename to play-scala-tls-example/LICENSE diff --git a/NOTICE b/play-scala-tls-example/NOTICE similarity index 100% rename from NOTICE rename to play-scala-tls-example/NOTICE diff --git a/README.md b/play-scala-tls-example/README.md similarity index 100% rename from README.md rename to play-scala-tls-example/README.md diff --git a/app/Main.scala b/play-scala-tls-example/app/Main.scala similarity index 100% rename from app/Main.scala rename to play-scala-tls-example/app/Main.scala diff --git a/app/controllers/HomeController.scala b/play-scala-tls-example/app/controllers/HomeController.scala similarity index 100% rename from app/controllers/HomeController.scala rename to play-scala-tls-example/app/controllers/HomeController.scala diff --git a/app/https/CustomSSLEngineProvider.scala b/play-scala-tls-example/app/https/CustomSSLEngineProvider.scala similarity index 100% rename from app/https/CustomSSLEngineProvider.scala rename to play-scala-tls-example/app/https/CustomSSLEngineProvider.scala diff --git a/app/https/SniKeyManager.scala b/play-scala-tls-example/app/https/SniKeyManager.scala similarity index 100% rename from app/https/SniKeyManager.scala rename to play-scala-tls-example/app/https/SniKeyManager.scala diff --git a/app/router/MultiSiteRequestHandler.scala b/play-scala-tls-example/app/router/MultiSiteRequestHandler.scala similarity index 100% rename from app/router/MultiSiteRequestHandler.scala rename to play-scala-tls-example/app/router/MultiSiteRequestHandler.scala diff --git a/app/views/index.scala.html b/play-scala-tls-example/app/views/index.scala.html similarity index 100% rename from app/views/index.scala.html rename to play-scala-tls-example/app/views/index.scala.html diff --git a/build.gradle b/play-scala-tls-example/build.gradle similarity index 100% rename from build.gradle rename to play-scala-tls-example/build.gradle diff --git a/build.sbt b/play-scala-tls-example/build.sbt similarity index 100% rename from build.sbt rename to play-scala-tls-example/build.sbt diff --git a/conf/application.conf b/play-scala-tls-example/conf/application.conf similarity index 100% rename from conf/application.conf rename to play-scala-tls-example/conf/application.conf diff --git a/conf/disabledAlgorithms.properties b/play-scala-tls-example/conf/disabledAlgorithms.properties similarity index 100% rename from conf/disabledAlgorithms.properties rename to play-scala-tls-example/conf/disabledAlgorithms.properties diff --git a/conf/generated.keystore b/play-scala-tls-example/conf/generated.keystore similarity index 100% rename from conf/generated.keystore rename to play-scala-tls-example/conf/generated.keystore diff --git a/conf/logback.xml b/play-scala-tls-example/conf/logback.xml similarity index 100% rename from conf/logback.xml rename to play-scala-tls-example/conf/logback.xml diff --git a/conf/routes b/play-scala-tls-example/conf/routes similarity index 100% rename from conf/routes rename to play-scala-tls-example/conf/routes diff --git a/conf/ws.conf b/play-scala-tls-example/conf/ws.conf similarity index 100% rename from conf/ws.conf rename to play-scala-tls-example/conf/ws.conf diff --git a/gradle/wrapper/gradle-wrapper.jar b/play-scala-tls-example/gradle/wrapper/gradle-wrapper.jar similarity index 100% rename from gradle/wrapper/gradle-wrapper.jar rename to play-scala-tls-example/gradle/wrapper/gradle-wrapper.jar diff --git a/gradle/wrapper/gradle-wrapper.properties b/play-scala-tls-example/gradle/wrapper/gradle-wrapper.properties similarity index 100% rename from gradle/wrapper/gradle-wrapper.properties rename to play-scala-tls-example/gradle/wrapper/gradle-wrapper.properties diff --git a/gradlew b/play-scala-tls-example/gradlew similarity index 100% rename from gradlew rename to play-scala-tls-example/gradlew diff --git a/gradlew.bat b/play-scala-tls-example/gradlew.bat similarity index 100% rename from gradlew.bat rename to play-scala-tls-example/gradlew.bat diff --git a/modules/one/app/controllers/HomeController.scala b/play-scala-tls-example/modules/one/app/controllers/HomeController.scala similarity index 100% rename from modules/one/app/controllers/HomeController.scala rename to play-scala-tls-example/modules/one/app/controllers/HomeController.scala diff --git a/modules/one/app/views/one/index.scala.html b/play-scala-tls-example/modules/one/app/views/one/index.scala.html similarity index 100% rename from modules/one/app/views/one/index.scala.html rename to play-scala-tls-example/modules/one/app/views/one/index.scala.html diff --git a/modules/one/build.gradle b/play-scala-tls-example/modules/one/build.gradle similarity index 100% rename from modules/one/build.gradle rename to play-scala-tls-example/modules/one/build.gradle diff --git a/modules/one/build.sbt b/play-scala-tls-example/modules/one/build.sbt similarity index 100% rename from modules/one/build.sbt rename to play-scala-tls-example/modules/one/build.sbt diff --git a/modules/one/conf/one.routes b/play-scala-tls-example/modules/one/conf/one.routes similarity index 100% rename from modules/one/conf/one.routes rename to play-scala-tls-example/modules/one/conf/one.routes diff --git a/modules/one/project/build.properties b/play-scala-tls-example/modules/one/project/build.properties similarity index 100% rename from modules/one/project/build.properties rename to play-scala-tls-example/modules/one/project/build.properties diff --git a/modules/two/app/controllers/HomeController.scala b/play-scala-tls-example/modules/two/app/controllers/HomeController.scala similarity index 100% rename from modules/two/app/controllers/HomeController.scala rename to play-scala-tls-example/modules/two/app/controllers/HomeController.scala diff --git a/modules/two/app/views/two/index.scala.html b/play-scala-tls-example/modules/two/app/views/two/index.scala.html similarity index 100% rename from modules/two/app/views/two/index.scala.html rename to play-scala-tls-example/modules/two/app/views/two/index.scala.html diff --git a/modules/two/build.gradle b/play-scala-tls-example/modules/two/build.gradle similarity index 100% rename from modules/two/build.gradle rename to play-scala-tls-example/modules/two/build.gradle diff --git a/modules/two/build.sbt b/play-scala-tls-example/modules/two/build.sbt similarity index 100% rename from modules/two/build.sbt rename to play-scala-tls-example/modules/two/build.sbt diff --git a/modules/two/conf/two.routes b/play-scala-tls-example/modules/two/conf/two.routes similarity index 100% rename from modules/two/conf/two.routes rename to play-scala-tls-example/modules/two/conf/two.routes diff --git a/modules/two/project/build.properties b/play-scala-tls-example/modules/two/project/build.properties similarity index 100% rename from modules/two/project/build.properties rename to play-scala-tls-example/modules/two/project/build.properties diff --git a/play b/play-scala-tls-example/play similarity index 100% rename from play rename to play-scala-tls-example/play diff --git a/project/build.properties b/play-scala-tls-example/project/build.properties similarity index 100% rename from project/build.properties rename to play-scala-tls-example/project/build.properties diff --git a/project/plugins.sbt b/play-scala-tls-example/project/plugins.sbt similarity index 100% rename from project/plugins.sbt rename to play-scala-tls-example/project/plugins.sbt diff --git a/scripts/client.crt b/play-scala-tls-example/scripts/client.crt similarity index 100% rename from scripts/client.crt rename to play-scala-tls-example/scripts/client.crt diff --git a/scripts/client.csr b/play-scala-tls-example/scripts/client.csr similarity index 100% rename from scripts/client.csr rename to play-scala-tls-example/scripts/client.csr diff --git a/scripts/client.jks b/play-scala-tls-example/scripts/client.jks similarity index 100% rename from scripts/client.jks rename to play-scala-tls-example/scripts/client.jks diff --git a/scripts/client.p12 b/play-scala-tls-example/scripts/client.p12 similarity index 100% rename from scripts/client.p12 rename to play-scala-tls-example/scripts/client.p12 diff --git a/scripts/clientca.crt b/play-scala-tls-example/scripts/clientca.crt similarity index 100% rename from scripts/clientca.crt rename to play-scala-tls-example/scripts/clientca.crt diff --git a/scripts/clientca.jks b/play-scala-tls-example/scripts/clientca.jks similarity index 100% rename from scripts/clientca.jks rename to play-scala-tls-example/scripts/clientca.jks diff --git a/scripts/example.com.crt b/play-scala-tls-example/scripts/example.com.crt similarity index 100% rename from scripts/example.com.crt rename to play-scala-tls-example/scripts/example.com.crt diff --git a/scripts/example.com.csr b/play-scala-tls-example/scripts/example.com.csr similarity index 100% rename from scripts/example.com.csr rename to play-scala-tls-example/scripts/example.com.csr diff --git a/scripts/example.com.jks b/play-scala-tls-example/scripts/example.com.jks similarity index 100% rename from scripts/example.com.jks rename to play-scala-tls-example/scripts/example.com.jks diff --git a/scripts/exampleca.crt b/play-scala-tls-example/scripts/exampleca.crt similarity index 100% rename from scripts/exampleca.crt rename to play-scala-tls-example/scripts/exampleca.crt diff --git a/scripts/exampleca.jks b/play-scala-tls-example/scripts/exampleca.jks similarity index 100% rename from scripts/exampleca.jks rename to play-scala-tls-example/scripts/exampleca.jks diff --git a/scripts/exampletrust.jks b/play-scala-tls-example/scripts/exampletrust.jks similarity index 100% rename from scripts/exampletrust.jks rename to play-scala-tls-example/scripts/exampletrust.jks diff --git a/scripts/gen-example.com.sh b/play-scala-tls-example/scripts/gen-example.com.sh similarity index 100% rename from scripts/gen-example.com.sh rename to play-scala-tls-example/scripts/gen-example.com.sh diff --git a/scripts/gen-one.example.com.sh b/play-scala-tls-example/scripts/gen-one.example.com.sh similarity index 100% rename from scripts/gen-one.example.com.sh rename to play-scala-tls-example/scripts/gen-one.example.com.sh diff --git a/scripts/gen-two.example.com.sh b/play-scala-tls-example/scripts/gen-two.example.com.sh similarity index 100% rename from scripts/gen-two.example.com.sh rename to play-scala-tls-example/scripts/gen-two.example.com.sh diff --git a/scripts/gen-wildcard.example.com.sh b/play-scala-tls-example/scripts/gen-wildcard.example.com.sh similarity index 100% rename from scripts/gen-wildcard.example.com.sh rename to play-scala-tls-example/scripts/gen-wildcard.example.com.sh diff --git a/scripts/genca.sh b/play-scala-tls-example/scripts/genca.sh similarity index 100% rename from scripts/genca.sh rename to play-scala-tls-example/scripts/genca.sh diff --git a/scripts/gencerts.sh b/play-scala-tls-example/scripts/gencerts.sh similarity index 100% rename from scripts/gencerts.sh rename to play-scala-tls-example/scripts/gencerts.sh diff --git a/scripts/genclient.sh b/play-scala-tls-example/scripts/genclient.sh similarity index 100% rename from scripts/genclient.sh rename to play-scala-tls-example/scripts/genclient.sh diff --git a/scripts/gentrustanchor.sh b/play-scala-tls-example/scripts/gentrustanchor.sh similarity index 100% rename from scripts/gentrustanchor.sh rename to play-scala-tls-example/scripts/gentrustanchor.sh diff --git a/scripts/one.example.com.crt b/play-scala-tls-example/scripts/one.example.com.crt similarity index 100% rename from scripts/one.example.com.crt rename to play-scala-tls-example/scripts/one.example.com.crt diff --git a/scripts/one.example.com.csr b/play-scala-tls-example/scripts/one.example.com.csr similarity index 100% rename from scripts/one.example.com.csr rename to play-scala-tls-example/scripts/one.example.com.csr diff --git a/scripts/password b/play-scala-tls-example/scripts/password similarity index 100% rename from scripts/password rename to play-scala-tls-example/scripts/password diff --git a/scripts/script-helper b/play-scala-tls-example/scripts/script-helper similarity index 100% rename from scripts/script-helper rename to play-scala-tls-example/scripts/script-helper diff --git a/scripts/test-gradle b/play-scala-tls-example/scripts/test-gradle similarity index 100% rename from scripts/test-gradle rename to play-scala-tls-example/scripts/test-gradle diff --git a/scripts/test-sbt b/play-scala-tls-example/scripts/test-sbt similarity index 100% rename from scripts/test-sbt rename to play-scala-tls-example/scripts/test-sbt diff --git a/scripts/two.example.com.crt b/play-scala-tls-example/scripts/two.example.com.crt similarity index 100% rename from scripts/two.example.com.crt rename to play-scala-tls-example/scripts/two.example.com.crt diff --git a/scripts/two.example.com.csr b/play-scala-tls-example/scripts/two.example.com.csr similarity index 100% rename from scripts/two.example.com.csr rename to play-scala-tls-example/scripts/two.example.com.csr diff --git a/scripts/wildcard.example.com.crt b/play-scala-tls-example/scripts/wildcard.example.com.crt similarity index 100% rename from scripts/wildcard.example.com.crt rename to play-scala-tls-example/scripts/wildcard.example.com.crt diff --git a/scripts/wildcard.example.com.csr b/play-scala-tls-example/scripts/wildcard.example.com.csr similarity index 100% rename from scripts/wildcard.example.com.csr rename to play-scala-tls-example/scripts/wildcard.example.com.csr diff --git a/settings.gradle b/play-scala-tls-example/settings.gradle similarity index 100% rename from settings.gradle rename to play-scala-tls-example/settings.gradle diff --git a/test/integration/GuiceOneHttpsServerPerTest.scala b/play-scala-tls-example/test/integration/GuiceOneHttpsServerPerTest.scala similarity index 100% rename from test/integration/GuiceOneHttpsServerPerTest.scala rename to play-scala-tls-example/test/integration/GuiceOneHttpsServerPerTest.scala diff --git a/test/integration/ServerSpec.scala b/play-scala-tls-example/test/integration/ServerSpec.scala similarity index 100% rename from test/integration/ServerSpec.scala rename to play-scala-tls-example/test/integration/ServerSpec.scala diff --git a/tutorial/index.html b/play-scala-tls-example/tutorial/index.html similarity index 100% rename from tutorial/index.html rename to play-scala-tls-example/tutorial/index.html