├── CODEOWNERS ├── dev-resources ├── version-file ├── puppetlabs │ └── analytics │ │ └── test │ │ ├── puppet.conf │ │ ├── localhost_cert.pem │ │ ├── ca.pem │ │ └── localhost_key.pem ├── bootstrap.cfg ├── logback-test.xml ├── logback-dev.xml ├── test-config.conf ├── config.conf ├── java.security.jdk8-fips └── java.security.jdk11-fips ├── .gitignore ├── .travis.yml ├── CHANGELOG.md ├── test └── puppetlabs │ └── analytics │ ├── service_test.clj │ ├── storage_test.clj │ ├── checkin │ ├── test_utils.clj │ └── analytics_service_core_test.clj │ ├── internal_api_test.clj │ ├── test_util.clj │ ├── web_core_test.clj │ └── core_test.clj ├── src └── puppetlabs │ └── analytics │ ├── api.clj │ ├── internal_api.clj │ ├── middleware.clj │ ├── service.clj │ ├── storage.clj │ ├── web_core.clj │ ├── core.clj │ └── checkin │ └── core.clj ├── dev └── user.clj ├── .github └── workflows │ └── mend.yml ├── README.md ├── project.clj └── LICENSE /CODEOWNERS: -------------------------------------------------------------------------------- 1 | * @puppetlabs/dumpling 2 | -------------------------------------------------------------------------------- /dev-resources/version-file: -------------------------------------------------------------------------------- 1 | 1.0.0 2 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | /target 2 | /classes 3 | /checkouts 4 | pom.xml 5 | pom.xml.asc 6 | *.jar 7 | *.class 8 | /.lein-* 9 | /.nrepl-port 10 | -------------------------------------------------------------------------------- /dev-resources/puppetlabs/analytics/test/puppet.conf: -------------------------------------------------------------------------------- 1 | [main] 2 | 3 | certname = localhost 4 | environmentpath = $confdir/environments 5 | environment_timeout = unlimited 6 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: clojure 2 | lein: 2.9.1 3 | jdk: 4 | - openjdk8 5 | - openjdk11 6 | env: 7 | - ADDITIONAL_ARGS='with-profile fips' 8 | - ADDITIONAL_ARGS='' 9 | script: lein $ADDITIONAL_ARGS test :all 10 | notifications: 11 | email: false 12 | -------------------------------------------------------------------------------- /dev-resources/bootstrap.cfg: -------------------------------------------------------------------------------- 1 | puppetlabs.analytics.service/analytics-service 2 | puppetlabs.trapperkeeper.services.scheduler.scheduler-service/scheduler-service 3 | puppetlabs.trapperkeeper.services.webserver.jetty9-service/jetty9-service 4 | puppetlabs.trapperkeeper.services.webrouting.webrouting-service/webrouting-service 5 | -------------------------------------------------------------------------------- /dev-resources/logback-test.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | %d %-5p [%c{2}] %m%n 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /dev-resources/logback-dev.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | %d %-5p [%c{2}] %m%n 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /dev-resources/test-config.conf: -------------------------------------------------------------------------------- 1 | global: { 2 | logging-config: ./dev-resources/logback-test.xml 3 | 4 | hostname: coolcerts.biz 5 | 6 | certs: { 7 | ssl-cert: ./dev-resources/puppetlabs/analytics/test/localhost_cert.pem 8 | ssl-key: ./dev-resources/puppetlabs/analytics/test/localhost_key.pem 9 | ssl-ca-cert: ./dev-resources/puppetlabs/analytics/test/ca.pem 10 | } 11 | } 12 | 13 | webserver: { 14 | host: localhost 15 | port: 8553 16 | } 17 | 18 | web-router-service: { 19 | "puppetlabs.analytics.service/analytics-service": "/analytics" 20 | } 21 | 22 | analytics: { 23 | data-directory: ./target 24 | } 25 | 26 | product: { 27 | version-path: "./dev-resources/version-file" 28 | pe-version-path: "/tmp/no-longer-valid" 29 | name: { 30 | artifact-id: "puppetserver" 31 | group-id: "puppet" 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /dev-resources/config.conf: -------------------------------------------------------------------------------- 1 | global: { 2 | logging-config: ./dev-resources/logback-dev.xml 3 | hostname: localhost 4 | certs: { 5 | ssl-key: ./dev-resources/puppetlabs/analytics/test/localhost_key.pem 6 | ssl-cert: ./dev-resources/puppetlabs/analytics/test/localhost_cert.pem 7 | ssl-ca-cert: ./dev-resources/puppetlabs/analytics/test/ca.pem 8 | } 9 | } 10 | 11 | webserver: { 12 | host: localhost 13 | port: 8080 14 | client-auth: want 15 | ssl-host: "0.0.0.0" 16 | ssl-port: 4433 17 | ssl-key: ./dev-resources/puppetlabs/analytics/test/localhost_key.pem 18 | ssl-cert: ./dev-resources/puppetlabs/analytics/test/localhost_cert.pem 19 | ssl-ca-cert: ./dev-resources/puppetlabs/analytics/test/ca.pem 20 | } 21 | 22 | web-router-service: { 23 | "puppetlabs.analytics.service/analytics-service": "/analytics" 24 | } 25 | 26 | analytics: { 27 | data-directory: ./target 28 | } 29 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Change Log 2 | All notable changes to this project will be documented in this file. This change log follows the conventions of [keepachangelog.com](http://keepachangelog.com/). 3 | 4 | ## [Unreleased] 5 | ### Changed 6 | 7 | ## [1.1.3] - 2023-06-29 8 | - update clj-parent, remove unused clj-yaml reference 9 | 10 | ## [1.1.2] 11 | - security and code owner changes 12 | 13 | ## [1.1.1] - 2022-03-02 14 | ### Fixed 15 | - Switch default update URL from updates.puppetlabs.com to updates.puppet.com 16 | 17 | ## [1.1.0] - 2022-03-02 18 | ### Changed 19 | - Updated dependencies and FIPS profile 20 | 21 | ## [1.0.1] - 2019-10-16 22 | ### Added 23 | - Add FIPS profile 24 | 25 | ## 1.0.0 - 2019-04-22 26 | ### Added 27 | - Service for aggregating analytics and uploading to http://updates.puppetlabs.com 28 | 29 | [Unreleased]: https://github.com/your-name/analytics/compare/1.1.1...HEAD 30 | [1.1.1]: https://github.com/puppetlabs/analytics/compare/1.1.0...1.1.1 31 | [1.1.0]: https://github.com/puppetlabs/analytics/compare/1.0.1...1.1.0 32 | [1.0.1]: https://github.com/puppetlabs/analytics/compare/1.0.0...1.0.1 33 | -------------------------------------------------------------------------------- /test/puppetlabs/analytics/service_test.clj: -------------------------------------------------------------------------------- 1 | (ns puppetlabs.analytics.service-test 2 | (:require [clojure.test :refer :all] 3 | [puppetlabs.trapperkeeper.testutils.bootstrap :refer [with-app-with-config]] 4 | [puppetlabs.trapperkeeper.services.webserver.jetty9-service :refer [jetty9-service]] 5 | [puppetlabs.trapperkeeper.services.webrouting.webrouting-service :refer [webrouting-service]] 6 | [puppetlabs.trapperkeeper.services.scheduler.scheduler-service :refer [scheduler-service]] 7 | [cheshire.core :as json] 8 | [clj-http.client :as client] 9 | [clojure.test :refer :all] 10 | [puppetlabs.analytics.test-util 11 | :refer 12 | [base-url 13 | with-analytics-service 14 | with-analytics-service-config]] 15 | [puppetlabs.trapperkeeper.testutils.bootstrap 16 | :refer 17 | [with-app-with-config]] 18 | [clojure.set :as set])) 19 | 20 | (deftest analytics-service-test 21 | (testing "returns the entrypoint" 22 | (with-analytics-service 23 | (let [resp (client/get base-url {:as :text})] 24 | (is (= ["commands" "version"] (keys (json/parse-string (:body resp))))))))) 25 | -------------------------------------------------------------------------------- /src/puppetlabs/analytics/api.clj: -------------------------------------------------------------------------------- 1 | (ns puppetlabs.analytics.api 2 | (:require [schema.core :as schema])) 3 | 4 | (def ScalarValue 5 | (schema/cond-pre schema/Str schema/Num schema/Bool)) 6 | 7 | (def MapValue 8 | {schema/Str ScalarValue}) 9 | 10 | (def ListValue 11 | [(schema/cond-pre MapValue ScalarValue)]) 12 | 13 | (def FieldValue 14 | (schema/cond-pre 15 | ListValue 16 | MapValue 17 | ScalarValue)) 18 | 19 | (def Metadata 20 | {schema/Str FieldValue}) 21 | 22 | (def SnapshotIn 23 | {(schema/required-key "fields") Metadata 24 | ; This exists as a string after conversion to internal snapshot. 25 | (schema/optional-key "timestamp") schema/Str}) 26 | 27 | (def SnapshotOut 28 | {schema/Str {(schema/required-key "value") FieldValue 29 | (schema/required-key "timestamp") schema/Str}}) 30 | 31 | (def EventIn 32 | {(schema/required-key "event") schema/Str 33 | (schema/optional-key "metadata") Metadata}) 34 | 35 | (def EventOut 36 | {(schema/required-key "event") schema/Str 37 | (schema/optional-key "metadata") Metadata 38 | ; This exists as a string after conversion to internal event. 39 | (schema/optional-key "timestamp") schema/Str}) 40 | 41 | (def Analytics 42 | {(schema/required-key "events") [EventOut] 43 | (schema/required-key "snapshots") SnapshotOut}) 44 | -------------------------------------------------------------------------------- /src/puppetlabs/analytics/internal_api.clj: -------------------------------------------------------------------------------- 1 | (ns puppetlabs.analytics.internal-api 2 | (:require [schema.core :as schema] 3 | [puppetlabs.analytics.api :as api] 4 | [clj-time.core :as time] 5 | [clj-time.coerce :as time.coerce])) 6 | 7 | ;; The internal versions merge the namespace with the names 8 | (def Event 9 | {(schema/required-key "event") schema/Str 10 | (schema/optional-key "metadata") api/Metadata 11 | (schema/required-key "timestamp") org.joda.time.DateTime}) 12 | 13 | (def Snapshot 14 | {schema/Str {(schema/required-key "value") api/FieldValue 15 | (schema/required-key "timestamp") org.joda.time.DateTime}}) 16 | 17 | (def Analytics 18 | {(schema/required-key "events") [Event] 19 | (schema/required-key "snapshots") Snapshot}) 20 | 21 | (schema/defn ^:always-validate ->internal-event :- Event 22 | [event :- api/EventIn] 23 | (assoc event 24 | "timestamp" (time/now))) 25 | 26 | (schema/defn ^:always-validate 27 | ->internal-snapshot :- Snapshot 28 | [{:strs [fields]} :- api/SnapshotIn] 29 | (into {} (for [[key value] fields] 30 | [key {"value" value, "timestamp" (time/now)}]))) 31 | 32 | (schema/defn ^:always-validate render-event :- api/EventOut 33 | [event :- Event] 34 | (update event "timestamp" time.coerce/to-string)) 35 | 36 | (schema/defn ^:always-validate render-snapshot :- api/SnapshotOut 37 | [snapshot :- Snapshot] 38 | (reduce-kv (fn [m k _] 39 | (update-in m [k "timestamp"] time.coerce/to-string)) snapshot snapshot)) 40 | 41 | (schema/defn ^:always-validate render-analytics :- api/Analytics 42 | [analytics :- Analytics] 43 | {"events" (map render-event (get analytics "events")) 44 | "snapshots" (render-snapshot (get analytics "snapshots"))}) 45 | -------------------------------------------------------------------------------- /dev/user.clj: -------------------------------------------------------------------------------- 1 | (ns user 2 | (:require [clojure.pprint :as pprint] 3 | [clojure.tools.namespace.repl :refer [refresh]] 4 | [puppetlabs.trapperkeeper.app :as tka] 5 | [puppetlabs.trapperkeeper.bootstrap :as bootstrap] 6 | [puppetlabs.trapperkeeper.config :as config] 7 | [puppetlabs.trapperkeeper.core :as tk])) 8 | 9 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 10 | ;;; Basic system life cycle 11 | 12 | (def system nil) 13 | 14 | (defn init [] 15 | (alter-var-root #'system 16 | (fn [_] (tk/build-app 17 | (bootstrap/parse-bootstrap-config! "./dev-resources/bootstrap.cfg") 18 | (config/load-config "./dev-resources/config.conf")))) 19 | (alter-var-root #'system tka/init) 20 | (tka/check-for-errors! system)) 21 | 22 | (defn start [] 23 | (alter-var-root #'system 24 | (fn [s] (if s (tka/start s)))) 25 | (tka/check-for-errors! system)) 26 | 27 | (defn stop [] 28 | (alter-var-root #'system 29 | (fn [s] (when s (tka/stop s))))) 30 | 31 | (defn go [] 32 | (init) 33 | (start)) 34 | 35 | (defn reset [] 36 | (stop) 37 | (refresh :after 'user/go)) 38 | 39 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 40 | ;;; Utilities for interacting with running system 41 | 42 | (defn context 43 | "Get the current TK application context. Accepts an optional array 44 | argument, which is treated as a sequence of keys to retrieve a nested 45 | subset of the map (a la `get-in`)." 46 | ([] 47 | (context [])) 48 | ([keys] 49 | (get-in @(tka/app-context system) keys))) 50 | 51 | (defn print-context 52 | "Pretty-print the current TK application context. Accepts an optional 53 | array of keys (a la `get-in`) to print a nested subset of the context." 54 | ([] 55 | (print-context [])) 56 | ([keys] 57 | (pprint/pprint (context keys)))) 58 | -------------------------------------------------------------------------------- /dev-resources/puppetlabs/analytics/test/localhost_cert.pem: -------------------------------------------------------------------------------- 1 | -----BEGIN CERTIFICATE----- 2 | MIIFdzCCA1+gAwIBAgIBAzANBgkqhkiG9w0BAQsFADAxMS8wLQYDVQQDDCZQdXBw 3 | ZXQgQ0E6IHN3YW5zb24uaHNkMS5vci5jb21jYXN0Lm5ldDAeFw0xNDEwMTYxODQ3 4 | MjNaFw0xOTEwMTYxODQ3MjNaMBQxEjAQBgNVBAMMCWxvY2FsaG9zdDCCAiIwDQYJ 5 | KoZIhvcNAQEBBQADggIPADCCAgoCggIBAOydDohx7bU5g2l9CE9diciHZMgmobKm 6 | s/xflo3hk+XUlh4n3tnE/LRuPLYEAEnafokCJNAgA3CrDmSxa3M27UabXRS14G4p 7 | E2Ae/zqmuS9jZvysqIt9SvNuyW4fiwPNXL7pw8SMWGODlUm4VAqDjNQnevPBA0U+ 8 | HuCO5VJC3ZEuBjvt49xqggvU9UYktjVIn7uNSRAsbF1AsgVP5swgKBEC6Hp6eajP 9 | atbXoS6kDakgIISxAnE8LB/jUTOeO++ydC2SEXdOh3qVxow/JiFnNT92B6BLbqXq 10 | ey3In2FOBUff8l/wgbJRFh2JZVBoH8uIDMGcW/UNO3VXBlkMch5mybH/xWpSD+wG 11 | WxZmk4APsNlUuOjHRii76dO8E2RkRr643UL7vnlZbRwTTSKnMSFsnQE8KVEsAnoy 12 | IHfsjBaIUoE/TN45vtyyxN28+3qL/nLyFZDXlVr/rSnqW61FewUglEuGUAySypoG 13 | oJ7fW7gd2nugrfuQxQHC7OT+s9Kd4Kx55KC7kZS1liufi1KuVb1FSbKt2pBV+POc 14 | p5t3Xs6RUZ0oZuUzjtfVtiRXh28iF0ukz2GIxI8neabaxCTMlGKl4PGAuKgesUf3 15 | HsIhsLZlNjcdXkxE1biG7taeDqtKNr9rOYABX9RuwhNpM3qLU18uQ9hrfX0hSh+V 16 | qTF7aa6Yxt8bAgMBAAGjgbYwgbMwMQYJYIZIAYb4QgENBCQWIlB1cHBldCBTZXJ2 17 | ZXIgSW50ZXJuYWwgQ2VydGlmaWNhdGUwHwYDVR0jBBgwFoAUsmotJHwnT2qYrICA 18 | mKzmAbmN3uowHQYDVR0OBBYEFLvpPGvjNC9JC6LhM9iCJnEN5Tm8MAwGA1UdEwEB 19 | /wQCMAAwIAYDVR0lAQH/BBYwFAYIKwYBBQUHAwEGCCsGAQUFBwMCMA4GA1UdDwEB 20 | /wQEAwIFoDANBgkqhkiG9w0BAQsFAAOCAgEAA/JZc05lSvFH1wLNOOH58d1HA3EL 21 | 4YIcZclRwUQBRORmx41OUuBzbZ+QQcczd2oDfnjFxFpLdAqR4JIv34zhZhdoVjsS 22 | LKByq3rMYsVJivIXHj4ZXX/8dxrPAs6gwOy5FLGLwcgBXyqFFRVgxY1kFYC2TIt1 23 | VW2HTORpW5UjmzSTxNWEJELQSX+hM1/YCGBb/T/aoQCOXyS9cjhR5NNxRZdP0IHb 24 | RR2ImhPM+IWunUa4Oc/KRwzPyQsaw5Nem+qRZfiRicpxNF1CvZsKu5QOetpNZ1nx 25 | tWy/xXjgrWG1pqeUxaOHgVn+hb9IjwyTVn18s7oKazkwt7+0NvPwiZAsfeyFI2+1 26 | KNwWcdFRY/qNy3KYjwtS5OiMMWchEE4TQIlnfaPncJwRLRH1w+0ZPfN96rKBhHfi 27 | 3WxUpAanUui8pMaZZkHm/IrVGgVCft/sU5yK6bK5WTbiWgQteWwiRlIVNWpPPAM1 28 | iFgGxVh6IvgNe9lwS5zv0aQxN1Jqfrn1ordHN0P5exwuCs2ZNw9flIdRkwPqqabR 29 | OIBEfLcxPcV+h04lTT0x/lnfoEJvQ//kVDrXPzlU+SB3T5TLywjc2qzpq5DB1y1o 30 | sDEZDFQC/l0qyMQclcL4Vt1RD688LoWk+e7tI06P5ji5QYvzALGU98qUjCvp98ic 31 | 3pbvybV2gWLjBd0= 32 | -----END CERTIFICATE----- 33 | -------------------------------------------------------------------------------- /dev-resources/puppetlabs/analytics/test/ca.pem: -------------------------------------------------------------------------------- 1 | -----BEGIN CERTIFICATE----- 2 | MIIFmTCCA4GgAwIBAgIBATANBgkqhkiG9w0BAQsFADAxMS8wLQYDVQQDDCZQdXBw 3 | ZXQgQ0E6IHN3YW5zb24uaHNkMS5vci5jb21jYXN0Lm5ldDAeFw0xNDEwMTYxODQy 4 | NTVaFw0xOTEwMTYxODQyNTVaMDExLzAtBgNVBAMMJlB1cHBldCBDQTogc3dhbnNv 5 | bi5oc2QxLm9yLmNvbWNhc3QubmV0MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIIC 6 | CgKCAgEAmXDdKo7gdBLx7T0Yxd7xwUKhIXj70dBoaoMqbfr96sd4bT+pG96o2slC 7 | 0uPyGbnJ3OQTORuNfsJiw9bV5C9j8eHhK3KmQONsgQWc6PjEo34MT0L2eKw/fo+S 8 | mejkvYOEoXjHR+rmSH43CPw+g477XF2nEeYeBT1KtDIOsIV1s/MDNy/zsDk3xt6I 9 | IMifMDkA5exMbqRQxp67cfrPed8JGMVtqdXM6jLKZtOArfyimmfvP8eccvjYk4mI 10 | WyEXUPhX9Izebl93n5M2MZDO5dm/eEAOUFOov4ARRQobAWoQfKU1JxtOfIHnY10P 11 | m/r7WtT4MByEu6H3nKND+E0wcHI+vfkpznFoUK6K6WXdbgCRvTCai5hvLsGhnWQp 12 | MNxjOm7jC4P8+lCUHzXd5Y15Oh+93blZLrwYV1+vQiaR8UYjKAoJazIosyyRh6uB 13 | FiY7rdplfs5sUzAxu+MnV7w+nMzm8lMMZcq2jY72q7WnsFCXltC8EpiQ3uttZZxB 14 | cZSA7yPD+dUu5R/nHi5JSCuLDPXPB+f+7D8JhwkvjGMQZAdaIe6KIbXFVD39Go82 15 | 6JIWb1jQVZahExL90kmN1KvfLxU6JuD01e1+NVQQ6gnIoHCoBI84Q0I7SMNkpsAA 16 | DrbXdUZJSH4+gtm0GgtOKrUztXeun8A2HxmKuSXhs5mU/9YUJ0UCAwEAAaOBuzCB 17 | uDAxBglghkgBhvhCAQ0EJBYiUHVwcGV0IFNlcnZlciBJbnRlcm5hbCBDZXJ0aWZp 18 | Y2F0ZTBDBgNVHSMEPDA6oTWkMzAxMS8wLQYDVQQDDCZQdXBwZXQgQ0E6IHN3YW5z 19 | b24uaHNkMS5vci5jb21jYXN0Lm5ldIIBATAdBgNVHQ4EFgQUsmotJHwnT2qYrICA 20 | mKzmAbmN3uowDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwDQYJKoZI 21 | hvcNAQELBQADggIBADbOxNL7Jm2KcGA/+gL/soo03J07906QpWpF9v7QDhzKv1k8 22 | 6G8qKhU+L7aDI0PzIlBQOYg0KUnigTw5pQoa4IdjmYPFvVRH1hbnhT65PctWpRa/ 23 | n2K87/3Yo+W7ABlmsWKNYSF6+Z50h9l3roG0TKKRY0glgAdwDiI91jNcQU12TPmm 24 | gz2CeVLX8hjV/hnOcnzmVt7iClIZBqNEHuXJcouf9XYUYc2dvGgXv/NVQT+OY6Bb 25 | h3Thh7vJCoI0DmXp8xCV9GLhYBljpgFbLCzHrd6+tGSb5QBUbWu1fNqE9izylu5e 26 | w66PjabH8yrn12z6LXqiV+zRm0EHCo9dWnroe7rWJCuhx1Qr68feO8DshcMX+/b9 27 | 93mJ4264JhxpyifJzHxA0sabA3kNQbUMmAxhNTW50mGEnbM0Rd24N2v2Wk+vjvZE 28 | J/p1NjuwCxO5BE/7UCQN8HEAm/0mj6r8VY1CFlipCkSsKstmRvlIOLZVGYewvqNF 29 | QzNPGhkzkFmBQ2DIR75J33fTC/n0gcOC5YNILRjCACXJpWtfRP0CUZWVUXmXJFBg 30 | G+hxOsvyNrsrVDlX5A3GzbJzBFgYLkxXCgqZa1d4oBso/ZY1no0ndIWES33NKpUA 31 | 3VsY8XNF1rARE9w5V8Lk1I0xr8Lu3kWkx341kCGkx+YNfuFWVvuzLRZ1TZgz 32 | -----END CERTIFICATE----- 33 | -------------------------------------------------------------------------------- /.github/workflows/mend.yml: -------------------------------------------------------------------------------- 1 | name: mend_scan 2 | on: 3 | workflow_dispatch: 4 | push: 5 | branches: 6 | - main 7 | jobs: 8 | build: 9 | runs-on: ubuntu-latest 10 | steps: 11 | - name: connect_twingate 12 | uses: twingate/github-action@v1 13 | with: 14 | service-key: ${{ secrets.TWINGATE_PUBLIC_REPO_KEY }} 15 | - name: checkout repo content 16 | uses: actions/checkout@v2 # checkout the repository content to github runner. 17 | with: 18 | fetch-depth: 1 19 | # install java which is required for mend and clojure 20 | - name: setup java 21 | uses: actions/setup-java@v3 22 | with: 23 | distribution: temurin 24 | java-version: 17 25 | # install clojure tools 26 | - name: Install Clojure tools 27 | uses: DeLaGuardo/setup-clojure@10.1 28 | with: 29 | # Install just one or all simultaneously 30 | # The value must indicate a particular version of the tool, or use 'latest' 31 | # to always provision the latest version 32 | cli: latest # Clojure CLI based on tools.deps 33 | lein: latest # Leiningen 34 | boot: latest # Boot.clj 35 | bb: latest # Babashka 36 | clj-kondo: latest # Clj-kondo 37 | cljstyle: latest # cljstyle 38 | zprint: latest # zprint 39 | # run lein gen 40 | - name: create pom.xml 41 | run: lein pom 42 | # download mend 43 | - name: download_mend 44 | run: curl -o wss-unified-agent.jar https://unified-agent.s3.amazonaws.com/wss-unified-agent.jar 45 | - name: run mend 46 | run: env WS_INCLUDES=pom.xml java -jar wss-unified-agent.jar 47 | env: 48 | WS_APIKEY: ${{ secrets.MEND_API_KEY }} 49 | WS_WSS_URL: https://saas-eu.whitesourcesoftware.com/agent 50 | WS_USERKEY: ${{ secrets.MEND_TOKEN }} 51 | WS_PRODUCTNAME: Puppet Enterprise 52 | WS_PROJECTNAME: ${{ github.event.repository.name }} 53 | WS_FILESYSTEMSCAN: true 54 | WS_CHECKPOLICIES: true 55 | WS_FORCEUPDATE: true 56 | -------------------------------------------------------------------------------- /src/puppetlabs/analytics/middleware.clj: -------------------------------------------------------------------------------- 1 | (ns puppetlabs.analytics.middleware 2 | (:require [cheshire.core :as json] 3 | [clojure.string :as str] 4 | [clojure.tools.logging :as log] 5 | [ring.util.response :as ring-response] 6 | [schema.core :as schema] 7 | [slingshot.slingshot :refer [throw+ try+]])) 8 | 9 | (defn- log-exception 10 | "Log an exception including request method and URI" 11 | [request exception] 12 | (let [method (-> request :request-method name str/upper-case)] 13 | (log/warn exception method (:uri request)))) 14 | 15 | (defn json-response 16 | [status-code body] 17 | (-> body 18 | json/encode 19 | ring-response/response 20 | (ring-response/status status-code) 21 | (ring-response/content-type "application/json; charset=utf-8"))) 22 | 23 | (defn wrap-schema-errors 24 | "Middleware to handle schema validation failures." 25 | [handler] 26 | (fn [request] 27 | (try+ 28 | (handler request) 29 | (catch [:kind :schema-violation] {:keys [schema submitted error]} 30 | (json-response 31 | 422 32 | {:kind "schema-violation" 33 | :msg (format "The objects that were submitted did not conform to the schema. The problem is: %s" (seq error)) 34 | :details {:submitted (str submitted) 35 | :schema (str schema) 36 | :error error}}))))) 37 | 38 | (defn wrap-error-catchall 39 | "Wrap the handler in a try/catch that swallows any throwable and returns a 500 40 | to the client with the throwable's error message." 41 | [handler] 42 | (fn [request] 43 | (try 44 | (handler request) 45 | (catch Exception e 46 | (log-exception request e) 47 | (json-response 48 | 500 49 | {:kind :application-error 50 | :msg "An uncaught server error was thrown. Check the log for details."}))))) 51 | 52 | (defn wrap-invalid-json 53 | [handler] 54 | (fn [request] 55 | (try+ 56 | (handler request) 57 | (catch [:kind :invalid-json] {:keys [exception]} 58 | (json-response 59 | 400 60 | {:kind :invalid-data 61 | :msg (format "Failed to parse body as JSON: %s" (.getMessage exception))}))))) 62 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Analytics Service 2 | 3 | A trapperkeeper web app designed to store analytics for later reporting. 4 | This is a cache that flushes once per day, submitting its cached data to 5 | a data processing pipelin. It will provide a REST endpoint where Puppet 6 | developers can submit their application telemetry. This is designed to 7 | run where Puppet Server runs. 8 | 9 | ## Self-service Analytics 10 | 11 | If you are looking to add analytics to an application that: 12 | 1) runs inside a Puppet install, and 13 | 2) is written in Clojure, 14 | see the instructions on the README of the [Analytics Client](https://github.com/puppetlabs/analytics-client). 15 | 16 | ## Usage 17 | 18 | First, run: 19 | 20 | $ lein tk 21 | 22 | Then, open a browser and visit: `http://localhost:8080/analytics` 23 | 24 | ### Running from the REPL 25 | 26 | Alternately, run: 27 | 28 | $ lein repl 29 | nREPL server started on port 52137 on host 127.0.0.1 30 | user => (go) 31 | 32 | This will allow you to launch the app from the Clojure REPL. You can then make 33 | changes and run `(reset)` to reload the app or `(stop)` to shutdown the app. 34 | 35 | In addition, the functions `(context)` and `(print-context)` are available to 36 | print out the current trapperkeeper application context. Both of these take an 37 | optional array of keys as a parameter, which is used to retrieve a nested 38 | subset of the context map. 39 | 40 | ### Querying data in analytics service 41 | 42 | To query the data that has been sent to the analytics service, you can 43 | hit the analytics service API. To query events, using the default 44 | settings, query this URL: 45 | 46 | http://localhost:8080/analytics/collections/events 47 | 48 | Snapshots can be found here: 49 | 50 | http://localhost:8080/analytics/collections/snapshots 51 | 52 | Querying stored snapshots in the analytics service might look like this: 53 | 54 | $ curl http://localhost:8080/analytics/collections/snapshots 55 | [{"hello":{"value":"world","timestamp":"2018-04-04T20:42:00.794Z"}}] 56 | 57 | Querying stored events might look like this: 58 | 59 | $ curl http://localhost:8080/analytics/collections/events 60 | [{"event":"some-event","timestamp":"2018-04-04T21:02:51.784Z"}] 61 | 62 | ## License 63 | 64 | Copyright © 2017 FIXME 65 | 66 | Distributed under the Eclipse Public License either version 1.0 or (at 67 | your option) any later version. 68 | -------------------------------------------------------------------------------- /src/puppetlabs/analytics/service.clj: -------------------------------------------------------------------------------- 1 | (ns puppetlabs.analytics.service 2 | (:require [cheshire.core :as json] 3 | [clojure.tools.logging :as log] 4 | [puppetlabs.analytics.checkin.core :as checkin] 5 | [puppetlabs.analytics.storage :as storage] 6 | [puppetlabs.analytics.web-core :as web] 7 | [puppetlabs.http.client.sync :as http] 8 | [puppetlabs.trapperkeeper.core :as trapperkeeper]) 9 | (:import java.io.IOException)) 10 | 11 | (defprotocol AnalyticsService) 12 | 13 | (defn get-whitelist 14 | [dujour-url] 15 | (try 16 | (let [response (http/get (str dujour-url "/whitelist") 17 | {:connect-timeout-milliseconds 5000 18 | :socket-timeout-milliseconds 5000})] 19 | (if (= 200 (:status response)) 20 | (-> response 21 | :body 22 | slurp 23 | json/decode) 24 | (log/infof "Received unexpected response with status code %s when trying to retrieve the whitelist." (:status response)))) 25 | (catch java.io.IOException e 26 | (log/infof "Encountered an error trying to retrieve the whitelist: %s" e)))) 27 | 28 | (trapperkeeper/defservice analytics-service 29 | AnalyticsService 30 | [[:ConfigService get-in-config get-config] 31 | [:WebroutingService add-ring-handler get-route] 32 | [:SchedulerService interspaced]] 33 | (init [this context] 34 | (log/info "Initializing analytics webservice") 35 | (let [url-prefix (get-route this) 36 | data-dir (get-in-config [:analytics :data-directory]) 37 | dujour-url (get-in-config [:product :update-server-url]) 38 | !whitelist (atom (when dujour-url (get-whitelist dujour-url))) 39 | queue (storage/init-queue data-dir) 40 | handler (web/app->wrapped-handler url-prefix (web/app queue !whitelist (get-config)))] 41 | (log/infof "Prefix is %s" url-prefix) 42 | (add-ring-handler this handler) 43 | (assoc context 44 | :url-prefix url-prefix 45 | :whitelist !whitelist 46 | :queue queue))) 47 | 48 | (start [this context] 49 | (let [checkin-interval-millis (* 1000 60 60 24) ; once per day 50 | !whitelist (:whitelist context) 51 | queue (:queue context) 52 | config (assoc (get-config) :queue queue)] 53 | (let [checkin-interval-millis (* 1000 60 60 24) 54 | args (checkin/create-checkin-args config)] ; once per day 55 | ;; TODO Read analytics, submit to dujour, clear cache 56 | (interspaced checkin-interval-millis 57 | (fn [] 58 | (let [checkin-args (checkin/create-checkin-args config)] 59 | (when-let [new-whitelist (:whitelist (checkin/checkin checkin-args))] 60 | (swap! !whitelist (constantly new-whitelist))))))) 61 | (log/infof "Analytics web service started.")) 62 | context)) 63 | -------------------------------------------------------------------------------- /dev-resources/puppetlabs/analytics/test/localhost_key.pem: -------------------------------------------------------------------------------- 1 | -----BEGIN RSA PRIVATE KEY----- 2 | MIIJKQIBAAKCAgEA7J0OiHHttTmDaX0IT12JyIdkyCahsqaz/F+WjeGT5dSWHife 3 | 2cT8tG48tgQASdp+iQIk0CADcKsOZLFrczbtRptdFLXgbikTYB7/Oqa5L2Nm/Kyo 4 | i31K827Jbh+LA81cvunDxIxYY4OVSbhUCoOM1Cd688EDRT4e4I7lUkLdkS4GO+3j 5 | 3GqCC9T1RiS2NUifu41JECxsXUCyBU/mzCAoEQLoenp5qM9q1tehLqQNqSAghLEC 6 | cTwsH+NRM54777J0LZIRd06HepXGjD8mIWc1P3YHoEtupep7LcifYU4FR9/yX/CB 7 | slEWHYllUGgfy4gMwZxb9Q07dVcGWQxyHmbJsf/FalIP7AZbFmaTgA+w2VS46MdG 8 | KLvp07wTZGRGvrjdQvu+eVltHBNNIqcxIWydATwpUSwCejIgd+yMFohSgT9M3jm+ 9 | 3LLE3bz7eov+cvIVkNeVWv+tKepbrUV7BSCUS4ZQDJLKmgagnt9buB3ae6Ct+5DF 10 | AcLs5P6z0p3grHnkoLuRlLWWK5+LUq5VvUVJsq3akFX485ynm3dezpFRnShm5TOO 11 | 19W2JFeHbyIXS6TPYYjEjyd5ptrEJMyUYqXg8YC4qB6xR/cewiGwtmU2Nx1eTETV 12 | uIbu1p4Oq0o2v2s5gAFf1G7CE2kzeotTXy5D2Gt9fSFKH5WpMXtprpjG3xsCAwEA 13 | AQKCAgA9vqZiOMi9N+rxBi26+D/SUnKcQGiFxDbHrvIMyEbd/OHHsMPYtCz1sKar 14 | INQqcZf/jM2qehArwJea8ymFAVpdyIE7vFJ6rMFfnfcgiQ1eLmRbn3rEG8gJSmnK 15 | EPUn4tlHAJ2TlsQiA95bRHy52aZQXpUZMs71rMZF90QkeUp0bjw2O1fw1uJk0AfJ 16 | bB8YPIFiYfYlAFKu6wkJldY2glWySr376CYDRU0uD0sCbtEZx0Z1GfP3NKqXD6zK 17 | +YnOfRUQJ0PjjFySQq9zPa9nnBUrIFPRIp4XMd8/DVF6BPAf13LaUlql+773qjkE 18 | CIfzhuc9Rt5ATlmrvy/q4PKOuGf9SKR4WPNEZemDq4W68iDffTiQv5rJED0fWIZd 19 | B6aV/VW+faubKnI4ypJPXhsKSJxEl2atkmJaSy4GFjoue9efqHTBxUvzdErSd7RO 20 | UwELxMQXVXAKAWke8wsL6B3BAmg9+gUsLbtclPNfKRkW3zEBXzt2qRfJZK1y+h+y 21 | wVqfKX8Mz4Mmgw2I2jWfFtykJZpOXBKb7rf7aALmYpiXS3mANZ/DPu5PlyokrPvB 22 | m/qRgMOhgxdr15nBNBLtM2uY7GDa7963ZQQn4RZ1QOTDNugMgWbYOANzEqC7MxYJ 23 | Zv2VOsHnFy24gd3rk9pJLNlmsTIe5YSteJZ8xpl+NVhMauUb8QKCAQEA/5xU779Z 24 | U6PVa40AVM3kuOCi82sjDcD/bRA5zDSwQeJUQMTCtp+Y8AN5tkLyhf0Frdw6/n0b 25 | E81O4PYtRBRnAFlD0i0069/SatDZYpN7cdpGQj1/99/ZYI6Rfzfmp3hpJJyDWxIK 26 | arkyXBgLejray8MmWiKnKTBfeU23kZ/H1RG6JJdyIn6jFWQBEOoAitO9nFlW2x7K 27 | rpaFW3/QjtjdF3CKVz40ec2uBnYdqN10ZI7A4ZzWfVHvahov1ZA5hapr22Ads35r 28 | h3Lb7KuKVavFvCzMZvMWxsDfIDFEDb10FECG9PUJF58+2QX2bVUiLWM29+DaaekA 29 | XeNvd0SpA85tDQKCAQEA7PlRTHc7lzvqWrddofsXXYsA0WCveTJEGjxqH05qvCQZ 30 | lJfsX7iJgLUyvVdR2AHFrCFc0M3XYvAi53nwPeTlC3teYMb2uEfjYDIkv+z53msw 31 | 0FSZxhnkArDkhXs8aJ/QvoWbrQZlJvd/udZuVXy2SzCet8e1k0HXOnQxfFIhNOmP 32 | KY3g+jKg8WcY57N7ygWSDsQTd/q7Bw92ufWJhRRQHHV9GWzU+WLSPU1VyeBVestT 33 | hZSm3b6P7KpMDKZFFpsvFY8J9W3irLXGEDnkLznrHam00HK1Dz+xUdZj9SWN6rMh 34 | NYo0OCx6iwAlBFuIMuRIHzkTrveo6p5B7cX43s4CxwKCAQAS8Ip6mTsNL36I0ZHM 35 | ttTTvhFU6ANY6YwDkMg3kU/eEd8cTXgAACNc5WUHVD6UHwNktoTIhoyTEwtdL+B6 36 | wug+5l5YHHFnaNY2g/MXksX60amTDuuEelmpBedR/dphXlKsG8y/2r5a2g4ZNM7k 37 | 56d+oZ8d3qN0MdlhK5kGeUhdSUr5mx8h3zBGTXqmvi/8GWRbSWNeKRHrjcuj0/yo 38 | GPmI2xXlEP7iZ5MVd3sLIB2Xtdwk23IpJwEOY5JXyK/6b34+awjIW/2rs58IEk3V 39 | uzyTjN44Ypq1b2UZBY19VyRau81EKUPbNDl76y0vPLejlU5lX4vPfSxByLBhrfy4 40 | A3uhAoIBAQCCrJz7KIiwxbZendzBFL/2sk8aJlG86E4LlaMDbm+HHfUJLpmG0zDn 41 | y4OWS09zaM7DM4aGEewiv77PnDsxNkZjhX0uqqikR+gHRL9lIl1LHBrH1s8RIXfN 42 | UBRD0wglvXMTjIOi7vLagQJqzOb8tw+i+MWdHEBxWo4/ypD7OCLdlal/RaB493Au 43 | jiZ6pkutxFKdV9xQfe+iXhGfS9mwi9n9R4Bbg9sRRkAe08Vp1A3u76437Bf0EUA2 44 | RlY3Z3yTkbFuFvlr4FNt37K/gdzlee+/5LQzef2D0iCKu0lVhobylCLM7lALZeOR 45 | QNwowfyh66YlqYjEJAd+kRRT9KZe3oVDAoIBAQDTcB1c5UN32Dz19vJXN9uO+zuJ 46 | CizhA34aaxlMjIYyWYP6CiL0/kPTM09H/aoy8BcpM9vVY27UUC89d8qn/DNi36C1 47 | Bk3uWgbzjqYQ9PUOoFyaZlrjfR4M78OtdE8TiNohuMZQCO0em2mQsZKpwmfBn1Qg 48 | 9915EwE9ouLc0UxyDXTdqdHytFQ/dlOiKtM4Pm98XXvpD+tCMf6s8OkFpXpILK8X 49 | XvRITDg0JY4FdA/Nj6KVw0gk87XgSk3z+/GQQQ8YQVAQS24czHcQIojCOJsVhUJg 50 | STn3N+EO2KC0GAgqtAL2iis+PJhZw7eG7hyzSCB6Vy3JF0c8fWgwiruhy7PV 51 | -----END RSA PRIVATE KEY----- 52 | -------------------------------------------------------------------------------- /test/puppetlabs/analytics/storage_test.clj: -------------------------------------------------------------------------------- 1 | (ns puppetlabs.analytics.storage-test 2 | (:require [clj-time.core :as time] 3 | [clojure.test :refer :all] 4 | [puppetlabs.analytics.core :as core] 5 | [puppetlabs.analytics.storage :as storage] 6 | [puppetlabs.analytics.test-util :refer [with-queue with-temp-directory]] 7 | [puppetlabs.analytics.internal-api :as internal-api] 8 | slingshot.test) 9 | (:import java.nio.file.Files)) 10 | 11 | ;; THE TESTS 12 | 13 | (deftest initialize-queue 14 | (testing "if the queue already exists open it" 15 | (with-temp-directory tmp-queue-dir "analytics-test" 16 | (let [queue (storage/init-queue (.toString tmp-queue-dir))] 17 | (is (= (:directory queue) 18 | (:directory (storage/init-queue (.toString tmp-queue-dir))))))))) 19 | 20 | (deftest initialize-queue-root-dir 21 | (testing "create the directory if it doesn't exist" 22 | (with-temp-directory tmp-queue-dir "analytics-test" 23 | (let [sub-path (.resolve tmp-queue-dir "nope") 24 | queue (storage/init-queue (.toString sub-path))] 25 | (is (Files/isWritable (:directory queue))))))) 26 | 27 | (deftest initialize-queue-errors 28 | (testing "throws an error if unable to initialize the queue" 29 | (is (thrown+-with-msg? [:kind :storage-init-failed] 30 | #"Encountered an error initializing analytics storage" 31 | (storage/init-queue "/dev/"))))) 32 | 33 | (deftest add-to-queue 34 | (testing "a message can be added to the queue and replayed" 35 | (with-queue queue 36 | (let [message (-> {"event" "hello.thing" 37 | "metadata" {"time" "first"}} 38 | internal-api/->internal-event) 39 | message-id (storage/store queue message)] 40 | (is (= message 41 | (storage/read-entry queue message-id))))))) 42 | 43 | (deftest reduce-queue-basic 44 | (testing "multiple messages can be combined" 45 | (with-queue queue 46 | (let [first-message (-> {"event" "good.morning" 47 | "metadata" {"weather" "cloudy"}} 48 | internal-api/->internal-event) 49 | second-message (-> {"event" "good.afternoon" 50 | "metadata" {"weather" "raining"}} 51 | internal-api/->internal-event)] 52 | (storage/store queue first-message) 53 | (storage/store queue second-message) 54 | (is (= #{first-message second-message} 55 | (storage/reduce-entries queue 56 | (fn [coll entry-id] 57 | (conj coll (storage/read-entry queue entry-id))) 58 | #{}))))))) 59 | 60 | (deftest time-encoding 61 | (testing "can encode and decode event timestamps" 62 | (with-queue queue 63 | (let [timestamp (time/date-time 1970) 64 | event {"event" "timey" 65 | "metadata" {"stuff" [1 2 3 4 5]} 66 | "timestamp" timestamp} 67 | entry-id (storage/store queue event)] 68 | (is (time/equal? timestamp 69 | (-> (storage/read-entry queue entry-id) 70 | (get "timestamp")))))))) 71 | 72 | 73 | ;; TODO error conditions for init-queue 74 | ;; ensure filesystem permissions etc 75 | -------------------------------------------------------------------------------- /test/puppetlabs/analytics/checkin/test_utils.clj: -------------------------------------------------------------------------------- 1 | (ns puppetlabs.analytics.checkin.test-utils 2 | (:require [clojure.test :refer :all] 3 | [puppetlabs.analytics.storage :as storage] 4 | [puppetlabs.kitchensink.core :as ks] 5 | [puppetlabs.trapperkeeper.app :as tk-app] 6 | [puppetlabs.trapperkeeper.testutils.logging :refer [with-test-logging]] 7 | [cheshire.core :as json] 8 | [me.raynes.fs :as fs] 9 | [puppetlabs.trapperkeeper.testutils.bootstrap :refer [with-app-with-config]] 10 | [puppetlabs.trapperkeeper.services.webserver.jetty9-service :refer :all] 11 | [ring.util.codec :as codec]) 12 | (:import (java.io File))) 13 | 14 | (def test-resources-path "./dev-resources/puppetlabs/analytics/test") 15 | (def ssl-cert-path (str test-resources-path "/localhost_cert.pem")) 16 | (def ssl-key-path (str test-resources-path "/localhost_key.pem")) 17 | (def ssl-ca-cert-path (str test-resources-path "/ca.pem")) 18 | 19 | (def jetty-config 20 | {:webserver {:port 8553 21 | :ssl-host "0.0.0.0" 22 | :ssl-port 8554 23 | :ssl-cert ssl-cert-path 24 | :ssl-key ssl-key-path 25 | :ssl-ca-cert ssl-ca-cert-path}}) 26 | 27 | (defn- add-dujour-handler 28 | "Adds a handler for dujour. This accepts a promise that will return the parameters 29 | sent to the dujour client, and returns a string for the URL for the endpoint that 30 | the handler will handle." 31 | [app handler-extension a-promise] 32 | (add-ring-handler 33 | (tk-app/get-service app :WebserverService) 34 | (fn [req] 35 | (let [params (json/parse-string (slurp (:body req))) 36 | return-message {"newer" true 37 | "product" "puppet-server" 38 | "link" "https://docs.puppet.com/puppet-server/9.9/release_notes.html" 39 | "message" "Puppet Server 9.9.9 is now available." 40 | "version" "9.9.9"} 41 | body (json/encode return-message)] 42 | (deliver a-promise params) 43 | {:status 200 :body body})) 44 | handler-extension) 45 | (str "http://localhost:8553" handler-extension)) 46 | 47 | (defn check-promise 48 | ([promise] 49 | (check-promise promise nil)) 50 | ([promise result] 51 | (if (realized? promise) 52 | @promise 53 | (if result 54 | (throw (RuntimeException. "Promise not realized before returning")) 55 | (throw (RuntimeException. (str "Promise not realized before returning; error was " result))))))) 56 | 57 | (defn add-promise 58 | "Adds a promise to the args for send-analytics, returning 59 | an array of the arguments including `:telemetry-url`, plus 60 | the promise which will contain the parameters sent to the 61 | dujour handler." 62 | [app args] 63 | (let [result (promise) 64 | telemetry-url (add-dujour-handler app "/dujour" result) 65 | args (merge {:telemetry-url telemetry-url} args)] 66 | [args result])) 67 | 68 | (defn with-mock-dujour 69 | [body] 70 | (with-test-logging 71 | (with-app-with-config 72 | app 73 | [jetty9-service] 74 | jetty-config 75 | (let [s (tk-app/get-service app :WebserverService) 76 | add-ring-handler (partial add-ring-handler s) 77 | queue (storage/init-queue (.getPath (ks/temp-dir "queue"))) 78 | args {:analytics-opt-out-path (File. "/also/does/not/exist") 79 | :version-path (File. "/fake/version/path") 80 | :cacert "my-ca-cert" 81 | :certname "localhost" 82 | :product-name "puppet" 83 | :queue queue}] 84 | (body app args))))) 85 | -------------------------------------------------------------------------------- /src/puppetlabs/analytics/storage.clj: -------------------------------------------------------------------------------- 1 | (ns puppetlabs.analytics.storage 2 | (:require [cheshire.core :as json] 3 | [puppetlabs.analytics.internal-api :as internal-api] 4 | [puppetlabs.stockpile.queue :as stockpile] 5 | [schema.core :as schema] 6 | [slingshot.slingshot :refer [throw+]]) 7 | (:import [java.io ByteArrayInputStream IOException] 8 | [java.nio.file Files FileSystems NoSuchFileException Path Paths] 9 | java.nio.file.attribute.FileAttribute 10 | [org.joda.time DateTime DateTimeZone] 11 | puppetlabs.stockpile.queue.Stockpile)) 12 | 13 | (defn- ^Path path-get [^String s & more-strings] 14 | (Paths/get s (into-array String more-strings))) 15 | 16 | (defn init-queue 17 | "Initialize a queue. The `dir` is expected to exist and be writable." 18 | [dir] 19 | (let [root (.toAbsolutePath (path-get dir)) 20 | queue-path (.resolve root "analytics")] 21 | (try 22 | (try 23 | (Files/createDirectories root (make-array FileAttribute 0)) 24 | (catch java.nio.file.FileAlreadyExistsException _)) 25 | (try (stockpile/open queue-path) 26 | (catch java.nio.file.NoSuchFileException _ 27 | (stockpile/create queue-path))) 28 | (catch java.io.IOException e 29 | (throw+ {:kind :storage-init-failed 30 | :msg (format "Encountered an error initializing analytics storage in %s: %s" queue-path e)} 31 | e))))) 32 | 33 | (defn- timestamps->millis 34 | "Convert all timestamps in an object to be written to the queue to 35 | milliseconds since the epoch." 36 | [object] 37 | (if (contains? object "timestamp") 38 | (update object "timestamp" #(.getMillis %)) 39 | (into {} (for [[field snapshot] object] 40 | [field 41 | (update snapshot "timestamp" #(.getMillis %))])))) 42 | 43 | (defn- millis->timestamps 44 | "Convert timestamps in millisecond since to epoch to joda DateTime objects" 45 | [object] 46 | (let [from-millis (fn [millis] (DateTime. (long millis) (DateTimeZone/UTC)))] 47 | (if (contains? object "timestamp") 48 | (update object "timestamp" from-millis) 49 | (into {} (for [[field snapshot] object] 50 | [field 51 | (update snapshot "timestamp" from-millis)]))))) 52 | 53 | (schema/defn ^:always-validate 54 | store :- (schema/protocol stockpile/Entry) 55 | "Store a message on the queue. The queue should already be initialized. The 56 | message should be a map. This returns a message id that can be used to 57 | retrieve the message." 58 | [queue :- puppetlabs.stockpile.queue.Stockpile 59 | object :- (schema/if #(contains? % "event") internal-api/Event internal-api/Snapshot)] 60 | (->> object 61 | timestamps->millis 62 | json/encode 63 | .getBytes 64 | ByteArrayInputStream. 65 | (stockpile/store queue))) 66 | 67 | (defn read-entry 68 | "Read a message from the queue. This does not remove it from the queue, but 69 | just reads a message by id." 70 | [queue message-id] 71 | (-> (stockpile/stream queue message-id) 72 | slurp 73 | json/decode 74 | millis->timestamps)) 75 | 76 | (defn reduce-entries 77 | "Reduce over the entries. The reducer function should expect to get entry ids." 78 | [queue f val] 79 | (stockpile/reduce queue f val)) 80 | 81 | (schema/defn ^:always-validate discard! 82 | [queue :- Stockpile 83 | entry-ids :- [schema/Int]] 84 | (doseq [entry entry-ids] 85 | (stockpile/discard queue entry))) 86 | 87 | (schema/defn ^:always-validate purge-queue! 88 | [queue :- Stockpile] 89 | (let [entries (stockpile/reduce queue conj ())] 90 | (discard! queue entries))) 91 | 92 | -------------------------------------------------------------------------------- /project.clj: -------------------------------------------------------------------------------- 1 | (defn deploy-info 2 | [url] 3 | {:url url 4 | :username :env/clojars_jenkins_username 5 | :password :env/clojars_jenkins_password 6 | :sign-releases false}) 7 | 8 | (defproject puppetlabs/analytics "1.1.4-SNAPSHOT" 9 | :description "Analytics service for Puppet" 10 | :url "https://github.com/puppetlabs/analytics" 11 | 12 | :pedantic? :abort 13 | 14 | :dependencies [[org.clojure/clojure] 15 | [org.clojure/tools.logging] 16 | [puppetlabs/comidi] 17 | [puppetlabs/dujour-version-check] 18 | [puppetlabs/http-client] 19 | [puppetlabs/kitchensink] 20 | [puppetlabs/trapperkeeper] 21 | [puppetlabs/trapperkeeper-scheduler] 22 | [puppetlabs/trapperkeeper-webserver-jetty9] 23 | [prismatic/schema] 24 | [trptcolin/versioneer "0.2.0"] 25 | [puppetlabs/stockpile "0.0.4"] 26 | [clj-time]] 27 | 28 | :parent-project {:coords [puppetlabs/clj-parent "7.1.0"] 29 | :inherit [:managed-dependencies]} 30 | 31 | :profiles {:defaults {:source-paths ["dev"] 32 | :dependencies [[puppetlabs/trapperkeeper :classifier "test" :scope "test"] 33 | [puppetlabs/kitchensink :classifier "test" :scope "test"] 34 | [clj-http "3.0.0"] 35 | [org.clojure/tools.namespace "0.2.11"] 36 | [ring-mock "0.1.5"]]} 37 | :dev [:defaults {:dependencies [[org.bouncycastle/bcpkix-jdk15on]]}] 38 | :fips [:defaults {:dependencies [[org.bouncycastle/bcpkix-fips] 39 | [org.bouncycastle/bctls-fips] 40 | [org.bouncycastle/bc-fips]] 41 | :jvm-opts ~(let [version (System/getProperty "java.version") 42 | [major minor _] (clojure.string/split version #"\.") 43 | unsupported-ex (ex-info "Unsupported major Java version. Expects 8 or 11." 44 | {:major major 45 | :minor minor})] 46 | (condp = (java.lang.Integer/parseInt major) 47 | 1 (if (= 8 (java.lang.Integer/parseInt minor)) 48 | ["-Djava.security.properties==./dev-resources/java.security.jdk8-fips"] 49 | (throw unsupported-ex)) 50 | 11 ["-Djava.security.properties==./dev-resources/java.security.jdk11-fips"] 51 | 17 ["-Djava.security.properties==./dev-resources/java.security.jdk17-fips"] 52 | (throw unsupported-ex)))}] 53 | :ci {:plugins [[lein-pprint "1.1.2" :exclusions [org.clojure/clojure]]]}} 54 | 55 | :repl-options {:init-ns user} 56 | 57 | :aliases {"tk" ["trampoline" "run" "--config" "dev-resources/config.conf"]} 58 | 59 | :main puppetlabs.trapperkeeper.main 60 | :plugins [[lein-parent "0.3.8"]] 61 | 62 | :repositories [["releases" "https://artifactory.delivery.puppetlabs.net/artifactory/clojure-releases__local/"] 63 | ["snapshots" "https://artifactory.delivery.puppetlabs.net/artifactory/clojure-snapshots__local/"]] 64 | :deploy-repositories [["releases" ~(deploy-info "https://clojars.org/repo")] 65 | ["snapshots" "https://artifactory.delivery.puppetlabs.net/artifactory/clojure-snapshots__local/"]] 66 | ) 67 | -------------------------------------------------------------------------------- /test/puppetlabs/analytics/internal_api_test.clj: -------------------------------------------------------------------------------- 1 | (ns puppetlabs.analytics.internal-api-test 2 | (:require [clojure.test :refer :all] 3 | [clj-time.core :as time] 4 | [puppetlabs.analytics.internal-api :as internal-api])) 5 | 6 | (deftest test-convert-internal-snapshot 7 | (testing "converts a snapshot to an internal snapshot" 8 | (let [fake-now (time/date-time 1234)] 9 | (time/do-at 10 | fake-now 11 | (let [internal-snapshot (internal-api/->internal-snapshot 12 | {"fields" {"abc.def" 123 13 | "abc.ghi.jk" [{"cat" "dog" "ferret" "gerbil"}]}})] 14 | (is (= {"abc.def" {"value" 123, "timestamp" fake-now} 15 | "abc.ghi.jk" {"value" [{"cat" "dog" "ferret" "gerbil"}], "timestamp" fake-now}} 16 | internal-snapshot))))))) 17 | 18 | (deftest test-convert-internal-event 19 | (testing "converts an event to an internal event" 20 | (let [internal-event (internal-api/->internal-event {"event" "abc.some.event" 21 | "metadata" {"meta" "data"}})] 22 | (is (= {"event" "abc.some.event" 23 | "metadata" {"meta" "data"}} 24 | (select-keys internal-event ["event" "metadata"])))))) 25 | 26 | (deftest test-render-event 27 | (testing "properly serializes date objects" 28 | (let [fake-now (time/date-time 1234)] 29 | (time/do-at fake-now 30 | (let [event {"event" "some.other.analytic" 31 | "metadata" {"some.crazy.metadata" true} 32 | "timestamp" (time/now)} 33 | rendered (internal-api/render-event event)] 34 | (is (= "1234-01-01T00:00:00.000Z" (get rendered "timestamp")))))))) 35 | 36 | (deftest test-render-snapshot 37 | (testing "properly serializes date objects" 38 | (let [snapshot {"some.snapshot" {"value" 5 39 | "timestamp" (time/date-time 1234)} 40 | "other.snapshot" {"value" [{"cat" "dog"}] 41 | "timestamp" (time/date-time 2015)}} 42 | rendered (internal-api/render-snapshot snapshot) 43 | expected {"some.snapshot" {"value" 5 44 | "timestamp" "1234-01-01T00:00:00.000Z"} 45 | "other.snapshot" {"value" [{"cat" "dog"}] 46 | "timestamp" "2015-01-01T00:00:00.000Z"}}] 47 | (is (= expected rendered))))) 48 | 49 | (deftest test-render-analytics 50 | (testing "properly serializes all date objects" 51 | (let [input {"snapshots" {"some.snapshot" {"value" 5 52 | "timestamp" (time/date-time 1234)} 53 | "other.snapshot" {"value" [3 4 5] 54 | "timestamp" (time/date-time 2015)}} 55 | "events" [{"event" "some.event" 56 | "metadata" {"some.crazy.metadata" true} 57 | "timestamp" (time/date-time 2011)} 58 | {"event" "some.other.event" 59 | "timestamp" (time/date-time 2012)}]} 60 | rendered (internal-api/render-analytics input) 61 | expected {"snapshots" {"some.snapshot" {"value" 5 62 | "timestamp" "1234-01-01T00:00:00.000Z"} 63 | "other.snapshot" {"value" [3 4 5] 64 | "timestamp" "2015-01-01T00:00:00.000Z"}} 65 | "events" [{"event" "some.event" 66 | "metadata" {"some.crazy.metadata" true} 67 | "timestamp" "2011-01-01T00:00:00.000Z"} 68 | {"event" "some.other.event" 69 | "timestamp" "2012-01-01T00:00:00.000Z"}]}] 70 | (is (= expected rendered))))) 71 | -------------------------------------------------------------------------------- /test/puppetlabs/analytics/test_util.clj: -------------------------------------------------------------------------------- 1 | (ns puppetlabs.analytics.test-util 2 | (:require [puppetlabs.analytics.service :as svc] 3 | [puppetlabs.analytics.storage :as storage] 4 | [puppetlabs.kitchensink.core :as ks] 5 | [puppetlabs.trapperkeeper.bootstrap :as bootstrap] 6 | [puppetlabs.trapperkeeper.config :as tk-config] 7 | [puppetlabs.trapperkeeper.testutils.bootstrap 8 | :refer 9 | [with-app-with-config]] 10 | [me.raynes.fs :as fs]) 11 | (:import [java.nio.file Files FileVisitor FileVisitResult] 12 | java.nio.file.attribute.FileAttribute)) 13 | 14 | (defn create-temp-directory 15 | [prefix] 16 | (Files/createTempDirectory prefix (make-array FileAttribute 0))) 17 | 18 | (defn delete-tree 19 | "Recursively delete a directory. Java NIO uses a visitor with walkFileTree, so 20 | we construct a FileVisitor that deletes files on visit and deletes directories 21 | after visit." 22 | [path] 23 | (let [delete-visitor (reify FileVisitor 24 | (visitFile [_ file attrs] 25 | (Files/delete file) 26 | FileVisitResult/CONTINUE) 27 | (postVisitDirectory [_ dir exc] 28 | (Files/delete dir) 29 | FileVisitResult/CONTINUE) 30 | (preVisitDirectory [_ dir attrs] 31 | FileVisitResult/CONTINUE) 32 | (visitFileFailed [_ file exc] 33 | FileVisitResult/CONTINUE))] 34 | (Files/walkFileTree path delete-visitor))) 35 | 36 | (defmacro with-temp-directory 37 | "Create a temporary directory bound to `name`, execute the body, and delete 38 | the directory and its contents." 39 | [name prefix & body] 40 | `(let [~name (create-temp-directory ~prefix)] 41 | (try 42 | ~@body 43 | (finally 44 | (delete-tree ~name))))) 45 | 46 | (defmacro with-queue 47 | "Execute the body with a temporary queue bound to `name`." 48 | [name & body] 49 | `(let [temp-path# (create-temp-directory "analytics-test") 50 | ~name (storage/init-queue (.toString temp-path#))] 51 | (try 52 | ~@body 53 | (finally 54 | (delete-tree temp-path#))))) 55 | 56 | (def test-config 57 | (tk-config/load-config "dev-resources/test-config.conf")) 58 | 59 | (def base-url 60 | (let [{:keys [host port]} (get-in test-config [:webserver]) 61 | service-id :puppetlabs.analytics.service/analytics-service 62 | prefix (or (get-in test-config [:web-router-service service-id :route]) 63 | (get-in test-config [:web-router-service service-id]))] 64 | (str "http://" host ":" port prefix))) 65 | 66 | (defn service-id->webserver 67 | [app-config service-id] 68 | (let [default-server (->> (:webserver app-config) 69 | (filter (comp :default-server second)) 70 | first 71 | first)] 72 | (or (get-in app-config [:web-router-service service-id :server]) 73 | default-server))) 74 | 75 | (defn with-analytics-service* 76 | ([f] (with-analytics-service* {} f)) 77 | ([config f] 78 | (with-temp-directory var-dir "analytics-test" 79 | (let [base-config (assoc-in test-config [:analytics :data-directory] (.toString var-dir)) 80 | conf-dir (ks/temp-dir "conf-dir") 81 | _ (fs/touch (str conf-dir "/analytics-opt-out")) 82 | opt-out-config (assoc-in base-config [:product :conf-dir] (.getPath conf-dir)) 83 | services (bootstrap/parse-bootstrap-config! "dev-resources/bootstrap.cfg")] 84 | (with-app-with-config 85 | app 86 | services 87 | (ks/deep-merge opt-out-config config) 88 | (f)))))) 89 | 90 | (defmacro with-analytics-service 91 | [& body] 92 | `(with-analytics-service* {} (fn [] ~@body))) 93 | 94 | (defmacro with-analytics-service-config 95 | [config & body] 96 | `(with-analytics-service* ~config (fn [] ~@body))) 97 | 98 | -------------------------------------------------------------------------------- /src/puppetlabs/analytics/web_core.clj: -------------------------------------------------------------------------------- 1 | (ns puppetlabs.analytics.web-core 2 | (:require [cheshire.core :as json] 3 | [puppetlabs.analytics.api :as api] 4 | [puppetlabs.analytics.core :as core] 5 | [puppetlabs.analytics.middleware :as middleware] 6 | [puppetlabs.analytics.storage :as storage] 7 | [puppetlabs.comidi :as comidi] 8 | [schema.core :as schema] 9 | [slingshot.slingshot :refer [throw+]] 10 | [puppetlabs.analytics.internal-api :as internal-api] 11 | [puppetlabs.analytics.checkin.core :as checkin]) 12 | (:import com.fasterxml.jackson.core.JsonParseException)) 13 | 14 | (defn app->wrapped-handler 15 | [url-prefix app] 16 | (->> app 17 | (comidi/context url-prefix) 18 | comidi/routes->handler 19 | middleware/wrap-invalid-json 20 | middleware/wrap-schema-errors 21 | middleware/wrap-error-catchall)) 22 | 23 | (defn parse-json 24 | [body] 25 | (try 26 | (json/decode (slurp body)) 27 | (catch JsonParseException e 28 | (throw+ {:kind :invalid-json 29 | :exception e})))) 30 | 31 | (defn validate-schema! 32 | "This wraps schema/check and throws a custom slingshot stone instead of the 33 | generic exception that schema/validate would throw." 34 | [schema body] 35 | (when-let [schema-error (schema/check schema body)] 36 | (throw+ {:kind :schema-violation 37 | :schema schema 38 | :submitted body 39 | :error schema-error}))) 40 | 41 | (defn handle-snapshot-post 42 | [queue whitelist body] 43 | (let [snapshot (parse-json body) 44 | _ (validate-schema! api/SnapshotIn snapshot) 45 | 46 | {:keys [accepted rejected] :as results} 47 | (->> snapshot 48 | internal-api/->internal-snapshot 49 | (core/partition-snapshots-whitelist whitelist)) 50 | 51 | to-render (update results :accepted internal-api/render-snapshot)] 52 | (storage/store queue accepted) 53 | (if (not-empty rejected) 54 | (middleware/json-response 206 to-render) 55 | (middleware/json-response 200 to-render)))) 56 | 57 | (defn handle-event-post 58 | [queue whitelist body] 59 | (let [api-event (parse-json body) 60 | _ (validate-schema! api/EventIn api-event) 61 | event (internal-api/->internal-event api-event) 62 | error (core/event-whitelist-error? whitelist event)] 63 | (if error 64 | (middleware/json-response 422 {"rejected" {(get event "event") error}}) 65 | (do 66 | (storage/store queue event) 67 | (middleware/json-response 200 (internal-api/render-event event)))))) 68 | 69 | (defn handle-send-post 70 | [queue !whitelist config body] 71 | (try 72 | (let [config (assoc config :queue queue) 73 | checkin-args (checkin/create-checkin-args config) 74 | result (checkin/checkin checkin-args)] 75 | (if (:error result) 76 | (middleware/json-response 500 (assoc result :status "failure")) 77 | (do 78 | (when-let [new-whitelist (:whitelist result)] 79 | (swap! !whitelist (constantly new-whitelist))) 80 | (middleware/json-response 200 {:status "success" :response result})))) 81 | (catch Exception e 82 | (middleware/json-response 422 (str "Caught exception: " (.getMessage e)))))) 83 | 84 | (defn app 85 | [queue !whitelist config] 86 | (comidi/routes 87 | (comidi/GET [""] request 88 | (middleware/json-response 200 (core/entrypoint request))) 89 | 90 | (comidi/POST ["/commands/snapshot"] {body :body} 91 | (handle-snapshot-post queue @!whitelist body)) 92 | 93 | (comidi/POST ["/commands/event"] {body :body} 94 | (handle-event-post queue @!whitelist body)) 95 | 96 | (comidi/POST ["/commands/send"] {body :body} 97 | (handle-send-post queue !whitelist config body)) 98 | 99 | (comidi/GET ["/collections/snapshots"] [request] 100 | (->> (storage/reduce-entries 101 | queue 102 | (fn [acc entry-id] 103 | (let [entry (storage/read-entry queue entry-id)] 104 | (if (nil? (schema/check internal-api/Snapshot entry)) 105 | (conj acc (internal-api/render-snapshot entry)) 106 | acc))) 107 | []) 108 | (middleware/json-response 200))) 109 | 110 | (comidi/GET ["/collections/events"] [request] 111 | (->> (storage/reduce-entries 112 | queue 113 | (fn [acc entry-id] 114 | (let [entry (storage/read-entry queue entry-id)] 115 | (if (nil? (schema/check internal-api/Event entry)) 116 | (conj acc (internal-api/render-event entry)) 117 | acc))) 118 | []) 119 | (middleware/json-response 200))) 120 | 121 | (comidi/not-found "Not Found!!!!"))) 122 | -------------------------------------------------------------------------------- /test/puppetlabs/analytics/checkin/analytics_service_core_test.clj: -------------------------------------------------------------------------------- 1 | (ns puppetlabs.analytics.checkin.analytics-service-core-test 2 | (:require [clojure.test :refer :all] 3 | [me.raynes.fs :as fs] 4 | [puppetlabs.analytics.checkin.core :as checkin] 5 | [puppetlabs.analytics.checkin.test-utils :refer [with-mock-dujour add-promise check-promise]] 6 | [puppetlabs.analytics.internal-api :as internal-api] 7 | [puppetlabs.analytics.storage :as storage] 8 | [puppetlabs.kitchensink.core :as ks] 9 | [puppetlabs.trapperkeeper.app :as tk-app] 10 | [puppetlabs.trapperkeeper.services.scheduler.scheduler-service 11 | :refer 12 | [scheduler-service]] 13 | [puppetlabs.trapperkeeper.services.webserver.jetty9-service :refer :all] 14 | [puppetlabs.trapperkeeper.testutils.bootstrap 15 | :refer 16 | [with-app-with-config]] 17 | [puppetlabs.trapperkeeper.testutils.logging :refer [with-test-logging]] 18 | [schema.test :as schema-test] 19 | [clojure.string :as str]) 20 | (:import java.io.File)) 21 | 22 | (use-fixtures :once schema-test/validate-schemas) 23 | 24 | (deftest opt-out-reason 25 | (testing "opt-out file exists" 26 | (let [opt-out-file (ks/temp-file "opt-out")] 27 | (is (= (str opt-out-file " exists") (checkin/get-opt-out-reason opt-out-file))))) 28 | 29 | (testing "everything is in order" 30 | (let [facter-path (ks/temp-file "facter") 31 | _ (fs/chmod "+x" facter-path)] 32 | (is (= nil (checkin/get-opt-out-reason nil)))))) 33 | 34 | (deftest checkin 35 | (testing "will not check in if opt-out-reason is set" 36 | (let [opt-out-file (ks/temp-file "opt-out")] 37 | (is (= (str opt-out-file " exists") (checkin/get-opt-out-reason opt-out-file))) 38 | (with-mock-dujour 39 | (fn [app args] 40 | (let [[args _] (add-promise app args) ; Only done to fill URLs. 41 | queue (storage/init-queue (.getPath (ks/temp-dir "queue"))) 42 | args (assoc args :analytics-opt-out-path opt-out-file 43 | :version-path (File. "/fake/version/path") 44 | :product-name "puppet" 45 | :queue queue)] 46 | (with-test-logging 47 | (checkin/checkin args) 48 | (is (logged? #"Not sending analytics data")))))))) 49 | (testing "will not check in if product-name is missing" 50 | (with-mock-dujour 51 | (fn [app args] 52 | (let [[args _] (add-promise app args) ; Only done to fill URLs. 53 | queue (storage/init-queue (.getPath (ks/temp-dir "queue"))) 54 | args (assoc args :analytics-opt-out-path (File. "does/not/exist") 55 | :version-path (File. "/fake/version/path") 56 | :product-name nil 57 | :queue queue)] 58 | (with-test-logging 59 | (checkin/checkin args) 60 | (is (logged? #"Not sending analytics data")) 61 | (is (logged? #"missing product name value"))))))) 62 | 63 | (testing "sends the correct arguments to dujour" 64 | (with-mock-dujour 65 | (fn [app args] 66 | (let [[args promise] (add-promise app args) 67 | _ (with-test-logging (checkin/checkin args)) 68 | params (check-promise promise)] 69 | (is (= "puppet" (params "product"))) 70 | (is (= "puppetlabs.packages" (params "group"))))))) 71 | 72 | (testing "does not throw if the server is not reachable" 73 | (with-mock-dujour 74 | (fn [app args] 75 | (with-test-logging 76 | (let [args (merge {:telemetry-url "http://does-not-exist.unreachable/dujour"} args) 77 | return (checkin/checkin args)] 78 | (is (str/starts-with? (:error return ) "does-not-exist.unreachable"))))))) 79 | 80 | (testing "omits queued analytics when there are none" 81 | (with-mock-dujour 82 | (fn [app args] 83 | (let [[args promise] (add-promise app args) 84 | result (checkin/checkin args) 85 | params (check-promise promise result)] 86 | (is (not (contains? params "events"))) 87 | (is (not (contains? params "snapshots"))))))) 88 | 89 | (testing "discards entries on completion" 90 | (with-mock-dujour 91 | (fn [app args] 92 | (let [[args _] (add-promise app args) 93 | queue (:queue args) 94 | event {"event" "some.weird.analytic"} 95 | event2 {"event" "some.other.analytic" 96 | "metadata" {"some.crazy.metadata" true}} 97 | snapshot {"fields" {"some.snapshot" 5}}] 98 | (storage/store queue (internal-api/->internal-event event)) 99 | (storage/store queue (internal-api/->internal-event event2)) 100 | (storage/store queue (internal-api/->internal-snapshot snapshot)) 101 | (is (not (= [] (storage/reduce-entries queue conj [])))) 102 | (checkin/checkin args)))))) 103 | 104 | (deftest create-checkin-args 105 | (let [cacert "secret-ca-cert" 106 | cacert-file (ks/temp-file "ca" ".pem") 107 | cacert-path (.getPath cacert-file) 108 | _ (spit cacert-file cacert) 109 | queue (storage/init-queue (.getPath (ks/temp-dir "queue"))) 110 | config {:global {:certs {:ssl-cert "hostcert" 111 | :ssl-key "hostprivkey" 112 | :ssl-ca-cert cacert-path} 113 | :hostname "certname"} 114 | :product {:conf-dir "/etc/puppetlabs" 115 | :pe-version-path "/wrong/version/path" 116 | :version-path "/fake/version/path"} 117 | :queue queue} 118 | args (checkin/create-checkin-args config)] 119 | (testing "it has the correct default paths" 120 | (is (= (File. "/etc/puppetlabs/analytics-opt-out") (:analytics-opt-out-path args))) 121 | (is (= (File. "/fake/version/path") (:version-path args)))) 122 | (is (= "certname" (get-in args [:certname]))) 123 | (is (= cacert (get-in args [:cacert]))) 124 | (is (= nil (:product-name args))) 125 | (is (= "https://updates.puppet.com" (:telemetry-url args))))) 126 | -------------------------------------------------------------------------------- /src/puppetlabs/analytics/core.clj: -------------------------------------------------------------------------------- 1 | (ns puppetlabs.analytics.core 2 | (:require [puppetlabs.analytics.api :as api] 3 | [puppetlabs.analytics.internal-api :as internal-api] 4 | [puppetlabs.analytics.storage :as storage] 5 | [schema.core :as schema] 6 | [trptcolin.versioneer.core :as version] 7 | [clj-time.core :as time] 8 | [puppetlabs.kitchensink.core :as ks]) 9 | (:import org.joda.time.DateTime) 10 | (:import (puppetlabs.stockpile.queue Stockpile))) 11 | 12 | (def Whitelist 13 | {schema/Str {(schema/required-key "datatype") schema/Str 14 | (schema/optional-key "description") schema/Str}}) 15 | 16 | (defn entrypoint 17 | "Returns the entrypoint, which is metadata describing the API and where to find 18 | various items." 19 | [request] 20 | (let [protocol (name (get request :scheme "https")) 21 | uri (get request :uri "/analytics") 22 | host (get request :server-name) 23 | port (get request :server-port) 24 | entrypoint-url (str protocol "://" host ":" port uri)] 25 | {:commands {:event {:name "event" 26 | :rel "https://api.puppetlabs.com/analytics/v1/commands/event" 27 | :id (str entrypoint-url "/commands/event") 28 | :params {"namespace" {"datatype" "string"} 29 | "event" {"datatype" "string"} 30 | "metadata" {"datatype" "object" 31 | "optional" "true"}}}, 32 | :snapshot {:name "snapshot" 33 | :rel "https://api.puppetlabs.com/analytics/v1/commands/snapshot" 34 | :id (str entrypoint-url "/commands/snapshot") 35 | :params {"namespace" {"datatype" "string"} 36 | "fields" {"datatype" "object"}}}} 37 | ;; Note: Collection endpoints are undocumented and unsupported until required in the API. 38 | :version {:server (version/get-version "puppetlabs" "analytics" "")}})) 39 | 40 | (schema/defn ^:always-validate combine-events :- internal-api/Analytics 41 | [base-analytics :- internal-api/Analytics 42 | new-events :- [internal-api/Event]] 43 | (update base-analytics "events" #(concat % new-events))) 44 | 45 | (defn- add-snapshot-if-newer 46 | [snapshots field candidate-snapshot] 47 | (if-let [{existing-timestamp "timestamp"} (get snapshots field)] 48 | (if (time/before? existing-timestamp (get candidate-snapshot "timestamp")) 49 | (assoc snapshots field candidate-snapshot) 50 | snapshots) 51 | (assoc snapshots field candidate-snapshot))) 52 | 53 | (defn- select-newest-snapshots 54 | "Given two maps of snapshots produce a single map using the newest value present for each." 55 | [base-snapshots candidate-snapshots] 56 | (reduce-kv add-snapshot-if-newer base-snapshots candidate-snapshots)) 57 | 58 | (schema/defn ^:always-validate combine-snapshots :- internal-api/Analytics 59 | [base-analytics :- internal-api/Analytics 60 | candidate-snapshots :- internal-api/Snapshot] 61 | (update base-analytics "snapshots" #(select-newest-snapshots % candidate-snapshots))) 62 | 63 | (schema/defn ^:always-validate partition-entries :- [(schema/cond-pre internal-api/Analytics [schema/Int])] 64 | "Partitions entries from a storage queue into a map of events and snapshots." 65 | [queue :- Stockpile] 66 | (storage/reduce-entries 67 | queue 68 | (fn [acc entry-id] 69 | (let [entry (storage/read-entry queue entry-id)] 70 | (if (nil? (schema/check internal-api/Event entry)) 71 | [(combine-events (first acc) [entry]) (conj (second acc) entry-id)] 72 | (if (nil? (schema/check internal-api/Snapshot entry)) 73 | [(combine-snapshots (first acc) entry) (conj (second acc) entry-id)] 74 | acc)))) 75 | [{"events" [] 76 | "snapshots" {}} 77 | []])) 78 | 79 | (schema/defn ^:always-validate get-self-service-analytics :- [(schema/cond-pre api/Analytics [schema/Int])] 80 | "Retrieves self-service analytics from the given path." 81 | [queue :- Stockpile] 82 | (let [[entries entry-ids] (partition-entries queue) 83 | rendered (internal-api/render-analytics entries)] 84 | [rendered entry-ids])) 85 | 86 | (schema/defn ^:always-validate purge-queue! 87 | [queue :- Stockpile] 88 | (storage/purge-queue! queue)) 89 | 90 | (schema/defn ^:always-validate discard! 91 | [queue :- Stockpile 92 | entry-ids :- [schema/Int]] 93 | (storage/discard! queue entry-ids)) 94 | 95 | (def datatype->schema-checker 96 | (ks/mapvals 97 | schema/checker 98 | {"string" schema/Str 99 | "number" schema/Num 100 | "boolean" schema/Bool 101 | "array[string]" [schema/Str] 102 | "array[number]" [schema/Num] 103 | "array[boolean]" [schema/Bool] 104 | "object[string-number]" {schema/Str schema/Num} 105 | "object[string-string]" {schema/Str schema/Str} 106 | "object[string-boolean]" {schema/Str schema/Bool}})) 107 | 108 | (defn- type-error? 109 | [{:strs [datatype]} {:strs [value]}] 110 | (when ((datatype->schema-checker datatype) value) 111 | (str "Expected a value of type " datatype))) 112 | 113 | (defn- validate-snapshot 114 | [whitelist results field value] 115 | (if-let [spec (get whitelist field)] 116 | (if-let [error (type-error? spec value)] 117 | (assoc-in results [:rejected field] error) 118 | (assoc-in results [:accepted field] value)) 119 | (assoc-in results [:rejected field] "Not an expected field"))) 120 | 121 | (schema/defn ^:always-validate partition-snapshots-whitelist 122 | [whitelist :- (schema/maybe Whitelist) 123 | snapshot :- internal-api/Snapshot] 124 | (if whitelist 125 | (reduce-kv (partial validate-snapshot whitelist) 126 | {:accepted {} :rejected {}} 127 | snapshot) 128 | {:accepted snapshot :rejected {}})) 129 | 130 | (schema/defn ^:always-validate event-whitelist-error? 131 | [whitelist :- (schema/maybe Whitelist) 132 | event :- internal-api/Event] 133 | (when whitelist 134 | (let [event-name (get event "event") 135 | expected-type (get-in whitelist [event-name "datatype"])] 136 | (if (nil? expected-type) 137 | "Not an expected event" 138 | (if (not (= "event" expected-type)) 139 | (str "Expected a value of type " expected-type) 140 | nil))))) 141 | -------------------------------------------------------------------------------- /src/puppetlabs/analytics/checkin/core.clj: -------------------------------------------------------------------------------- 1 | (ns puppetlabs.analytics.checkin.core 2 | (:require [cheshire.core :as json] 3 | [clojure.java.io :as io] 4 | [clojure.java.shell :as shell] 5 | [clojure.set :as set] 6 | [clojure.string :as str] 7 | [clojure.tools.logging :as log] 8 | [me.raynes.fs :as fs] 9 | [puppetlabs.dujour.version-check :as version-check] 10 | [puppetlabs.kitchensink.core :as ks] 11 | [schema.core :as schema] 12 | [slingshot.slingshot :refer [try+]] 13 | [puppetlabs.i18n.core :refer [trs]] 14 | [puppetlabs.config.typesafe :as hocon] 15 | [puppetlabs.analytics.core :as core]) 16 | (:import java.io.File 17 | (puppetlabs.stockpile.queue Stockpile))) 18 | 19 | (defn get-opt-out-reason 20 | "Calculate whether the user has opted out and return the reason for opting out, or nil if opting in" 21 | [opt-out-path] 22 | (cond (fs/exists? opt-out-path) 23 | (trs "{0} exists" opt-out-path) 24 | 25 | :default nil)) 26 | 27 | (def CheckinRequirements 28 | "These are various file paths and variables required 29 | to create a checkin." 30 | {:analytics-opt-out-path File 31 | :cacert schema/Str 32 | :certname schema/Str 33 | :telemetry-url schema/Str 34 | :version-path File 35 | :product-name (schema/maybe schema/Str) 36 | :queue Stockpile}) 37 | 38 | (def ProductConfig 39 | "Optional product keys that help the developer configure the analytics 40 | service with local settings." 41 | {(schema/optional-key :version-path) schema/Str 42 | (schema/optional-key :pe-version-path) schema/Str ; deprecated 43 | (schema/optional-key :name) {:group-id schema/Str 44 | :artifact-id schema/Str} 45 | (schema/optional-key :update-server-url) schema/Str 46 | (schema/optional-key :conf-dir) schema/Str 47 | schema/Any schema/Any}) 48 | 49 | (def AnalyticsConfig 50 | "The minimum required config settings for the analytics namespace" 51 | {:global {:certs {:ssl-ca-cert schema/Str 52 | schema/Any schema/Any} 53 | :hostname schema/Str 54 | schema/Any schema/Any} 55 | (schema/optional-key :product) ProductConfig 56 | schema/Any schema/Any}) 57 | 58 | (def CheckVersionResponse 59 | "The response map returned from Dujour when checking the version" 60 | {:message schema/Str 61 | :link schema/Str 62 | schema/Any schema/Any}) 63 | 64 | (schema/defn ^:always-validate 65 | create-checkin-args :- CheckinRequirements 66 | "Creates the object that is used as input to the checkin method." 67 | [config :- AnalyticsConfig] 68 | (let [telemetry-url (get-in config [:product :update-server-url] "https://updates.puppet.com") 69 | conf-dir (get-in config [:product :conf-dir] "/etc/puppetlabs") 70 | analytics-opt-out-path (File. (str conf-dir "/analytics-opt-out")) 71 | certname (get-in config [:global :hostname]) 72 | ssl-ca-cert (get-in config [:global :certs :ssl-ca-cert]) 73 | cacert (if (fs/readable? ssl-ca-cert) 74 | (slurp ssl-ca-cert) 75 | (log/debug (trs "cacert file is not readable"))) 76 | version-path (File. (or (get-in config [:product :version-path]) 77 | (get-in config [:product :pe-version-path]) 78 | "N/A")) 79 | product-name (get-in config [:product :name :artifact-id]) 80 | queue (get-in config [:queue])] 81 | {:analytics-opt-out-path analytics-opt-out-path 82 | :telemetry-url telemetry-url 83 | :version-path version-path 84 | :certname certname 85 | :cacert cacert 86 | :product-name product-name 87 | :queue queue})) 88 | 89 | (defn send-analytics-and-log-errors 90 | [query-params telemetry-url] 91 | (try+ 92 | (version-check/send-telemetry query-params telemetry-url) 93 | (catch [:kind :puppetlabs.dujour.version-check/connection-error] {:keys [msg cause]} 94 | (log/debug cause (trs "Unable to connect to telemetry service at {0}: {1}." telemetry-url msg)) 95 | {:error msg}) 96 | (catch [:kind :puppetlabs.dujour.version-check/http-error-code] {:keys [msg details]} 97 | (log/debug (trs "Telemetry service at {0} responded with HTTP status code {1}, body: {2}." telemetry-url (:status details) (:body details))) 98 | {:error msg 99 | :details details}) 100 | (catch [:kind :puppetlabs.dujour.version-check/unexpected-response] {:keys [msg details]} 101 | (log/debug (trs "Received an unexpected response from telemetry service at {0}. body: {1}" telemetry-url (:body details))) 102 | {:error msg 103 | :details details}) 104 | (catch Exception {:keys [msg] :as e} 105 | (log/debug e (trs "Encountered an error when sending telemetry - url: {0}" telemetry-url)) 106 | {:error msg}))) 107 | 108 | (schema/defn ^:always-validate send-analytics 109 | "Retrieves and sends analytics to dujour" 110 | [args telemetry-url] 111 | (send-analytics-and-log-errors args telemetry-url)) 112 | 113 | (defn get-version 114 | [version-path] 115 | (if (fs/exists? version-path) 116 | (str/trim (slurp version-path)) 117 | (log/info (trs "No version file; analytics will fail to send.")))) 118 | 119 | (schema/defn ^:always-validate checkin 120 | [{:keys [analytics-opt-out-path telemetry-url queue 121 | version-path product-name cacert certname]} 122 | :- CheckinRequirements] 123 | (let [opt-out-reason (get-opt-out-reason analytics-opt-out-path) 124 | missing-name-warning (when-not product-name 125 | (trs "missing product name value from configuration"))] 126 | (if (or opt-out-reason missing-name-warning) 127 | (let [reason (->> [opt-out-reason missing-name-warning] (remove nil?) (str/join ", "))] 128 | (core/purge-queue! queue) ; Empty the queue to prevent overflow. 129 | (log/info (trs "Not sending analytics data - (reason: {0})." reason))) 130 | (let [[self-service-analytics entry-ids] (core/get-self-service-analytics queue) 131 | version (get-version version-path) 132 | args {:product-name product-name 133 | :version version 134 | :cacert cacert 135 | :certname certname 136 | :self-service-analytics self-service-analytics} 137 | result (send-analytics args telemetry-url)] 138 | ; TODO Should this check for something? `dujour-version-check` only returns those 5 keys... 139 | ;(when (some #(= (:status result) %) ["success", "partial"]) ... ) 140 | (core/discard! queue entry-ids) 141 | result)))) 142 | -------------------------------------------------------------------------------- /test/puppetlabs/analytics/web_core_test.clj: -------------------------------------------------------------------------------- 1 | (ns puppetlabs.analytics.web-core-test 2 | (:require [cheshire.core :as json] 3 | [clojure.string :as str] 4 | [clojure.test :refer :all] 5 | [puppetlabs.analytics.test-util :as test-util] 6 | [puppetlabs.analytics.checkin.test-utils :as checkin-utils] 7 | [puppetlabs.analytics.web-core :as web] 8 | [ring.mock.request :as mock] 9 | [ring.util.io :as ring-io] 10 | [clj-time.core :as time])) 11 | 12 | (defn mock-post 13 | [endpoint input] 14 | (let [ring-app (web/app->wrapped-handler "some-analytics" (web/app nil (atom {}) {})) 15 | body (ring-io/string-input-stream input) 16 | request (-> 17 | (mock/request :post (str "some-analytics/commands" endpoint)) 18 | (assoc :body body)) 19 | response (ring-app request)] 20 | response)) 21 | 22 | (deftest entrypoint 23 | (testing "provides the entrypoint" 24 | (let [ring-app (web/app->wrapped-handler "some-analytics" (web/app nil (atom {}) {})) 25 | response (ring-app (mock/request :get "some-analytics"))] 26 | (is (str/starts-with? (get-in response [:headers "Content-Type"]) 27 | "application/json")) 28 | (let [body (json/parse-string (:body response))] 29 | (is (= ["event" "snapshot"] (keys (get body "commands")))) 30 | (is (not-empty ((get body "version") "server"))))))) 31 | 32 | (deftest malformed-json 33 | (testing "returns 400 upon malformed JSON" 34 | (let [input "{: :) (: :}" 35 | response (mock-post "/snapshot" input) 36 | body (json/decode (:body response) true)] 37 | (is (= 400 (:status response))) 38 | (is (= "invalid-data" (:kind body))) 39 | (is (= (str/starts-with? (:msg body) "Failed to parse body as JSON")))))) 40 | 41 | (deftest event-validation 42 | (testing "event returns reasonable schema errors" 43 | (let [input (json/generate-string {:event "something.something-happened" 44 | :extra "not allowed"}) 45 | response (mock-post "/event" input) 46 | body (json/decode (:body response) true)] 47 | (is (= 422 (:status response))) 48 | (is (= "schema-violation" (:kind body))) 49 | (is (str/includes? (:msg body) "([\"extra\" disallowed-key])"))))) 50 | 51 | (deftest snapshot-validation 52 | (testing "event returns reasonable schema errors" 53 | (let [input (json/generate-string {:fields {"reasonable" "value"} 54 | :extra "not allowed"}) 55 | response (mock-post "/snapshot" input) 56 | body (json/decode (:body response) true)] 57 | (is (= 422 (:status response))) 58 | (is (= "schema-violation" (:kind body))) 59 | (is (str/includes? (:msg body) "([\"extra\" disallowed-key])"))))) 60 | 61 | (deftest store-event 62 | (testing "when posting an event the event is stored" 63 | (test-util/with-queue queue 64 | (let [whitelist (atom {"here.something-said" {"datatype" "event", "description" "thing"}}) 65 | handler (web/app->wrapped-handler "" (web/app queue whitelist {})) 66 | event (json/encode {:event "here.something-said" 67 | :metadata {"good" "no"}}) 68 | event-request (assoc (mock/request :post "/commands/event") 69 | :body (ring-io/string-input-stream event)) 70 | event-response (handler event-request) 71 | collection-request (mock/request :get "/collections/events") 72 | collection-response (handler collection-request)] 73 | (is (= 200 (:status event-response))) 74 | (is (= 200 (:status collection-response))) 75 | (is (= {"event" "here.something-said" 76 | "metadata" {"good" "no"}} 77 | (-> collection-response 78 | :body 79 | json/decode 80 | first 81 | (select-keys ["event" "metadata"])))))))) 82 | 83 | (deftest store-snapshot 84 | (testing "when posting a snapshot the snapshot is stored" 85 | (test-util/with-queue queue 86 | (time/do-at (time/date-time 1111) 87 | (let [whitelist (atom {"there.a" {"datatype" "string", "description" ""} 88 | "there.c" {"datatype" "string", "description" ""}}) 89 | handler (web/app->wrapped-handler "" (web/app queue whitelist {})) 90 | snapshot (json/encode {:fields {"there.a" "b" "there.c" "d"}}) 91 | snapshot-request (assoc (mock/request :post "/commands/snapshot") 92 | :body (ring-io/string-input-stream snapshot)) 93 | snapshot-response (handler snapshot-request) 94 | collection-request (mock/request :get "/collections/snapshots") 95 | collection-response (handler collection-request)] 96 | (is (= {"there.a" {"value" "b", "timestamp" "1111-01-01T00:00:00.000Z"} 97 | "there.c" {"value" "d", "timestamp" "1111-01-01T00:00:00.000Z"}} 98 | (-> collection-response 99 | :body 100 | json/decode 101 | first)))))))) 102 | 103 | (deftest send-command 104 | (testing "sends on command" 105 | (time/do-at (time/date-time 1111) 106 | (checkin-utils/with-mock-dujour 107 | (fn [dujour-app args] 108 | (let [[{:keys [telemetry-url]} result-args] (checkin-utils/add-promise dujour-app args) 109 | queue (:queue args) 110 | config {:global {:certs {:ssl-ca-cert "./dev-resources/puppetlabs/analytics/test/ca.pem"} 111 | :hostname (get args :certname)} 112 | :product {:update-server-url telemetry-url 113 | :name {:artifact-id "puppetserver" :group-id "puppet"} 114 | :version-path "/fake/version/path"} 115 | :analytics {:url "http://localhost:8553/analytics"} 116 | :queue queue} 117 | whitelist (atom {"there.a" {"datatype" "string", "description" ""} 118 | "there.c" {"datatype" "string", "description" ""}}) 119 | handler (web/app->wrapped-handler "" (web/app queue whitelist config)) 120 | snapshot (json/encode {:fields {"there.a" "b" "there.c" "d"}}) 121 | snapshot-request (assoc (mock/request :post "/commands/snapshot") 122 | :body (ring-io/string-input-stream snapshot)) 123 | _ (handler snapshot-request) 124 | send-request (mock/request :post "/commands/send") 125 | send-response (handler send-request) 126 | dujour-arguments (checkin-utils/check-promise result-args)] 127 | (is (= {"there.a" {"value" "b", "timestamp" "1111-01-01T00:00:00.000Z"} 128 | "there.c" {"value" "d", "timestamp" "1111-01-01T00:00:00.000Z"}} 129 | (get-in dujour-arguments ["self-service-analytics" "snapshots"]))) 130 | (is (= 200 (:status send-response))) 131 | (is (= "success" 132 | (:status (json/parse-string (:body send-response) true)))))))))) 133 | -------------------------------------------------------------------------------- /test/puppetlabs/analytics/core_test.clj: -------------------------------------------------------------------------------- 1 | (ns puppetlabs.analytics.core-test 2 | (:require [clj-time.coerce :as time.coerce] 3 | [clj-time.core :as time] 4 | [clojure.test :refer :all] 5 | [puppetlabs.analytics.core :as core] 6 | [puppetlabs.analytics.internal-api :as internal-api] 7 | [puppetlabs.analytics.storage :as storage] 8 | [puppetlabs.analytics.test-util :refer [with-queue]] 9 | [puppetlabs.kitchensink.core :as ks] 10 | [clj-time.coerce :as time.coerce] 11 | [clojure.string :as str])) 12 | 13 | (deftest test-entrypoint 14 | (testing "returns the entrypoint" 15 | (let [result (core/entrypoint {:scheme :https 16 | :uri "/analytics" 17 | :server-name "localish" 18 | :server-port "8675309"})] 19 | (is (= [:commands :version] (keys result))) 20 | (is (= (get-in result [:commands :event :id]) "https://localish:8675309/analytics/commands/event")) 21 | (is (= (get-in result [:commands :snapshot :id]) "https://localish:8675309/analytics/commands/snapshot"))))) 22 | 23 | (deftest test-get-self-service-analytics 24 | (testing "retrieves queued analytics" 25 | (let [fake-now (time/date-time 1234)] 26 | (with-queue queue 27 | (time/do-at 28 | fake-now 29 | (let [serialized-now (time.coerce/to-string fake-now) 30 | event {"event" "some.weird.analytic"} 31 | event2 {"event" "some.other.analytic" 32 | "metadata" {"some.crazy.metadata" true}} 33 | snapshot {"fields" {"some.snapshot" 5}} 34 | id1 (storage/store queue (internal-api/->internal-event event)) 35 | id2 (storage/store queue (internal-api/->internal-event event2)) 36 | id3 (storage/store queue (internal-api/->internal-snapshot snapshot)) 37 | result (core/get-self-service-analytics queue) 38 | expected [{"events" #{{"event" "some.weird.analytic" 39 | "timestamp" serialized-now} 40 | {"event" "some.other.analytic" 41 | "metadata" {"some.crazy.metadata" true} 42 | "timestamp" serialized-now}} 43 | "snapshots" {"some.snapshot" {"value" 5 44 | "timestamp" serialized-now}}} 45 | #{id1 id2 id3}]] 46 | (is (= expected 47 | (-> result 48 | (update-in [0 "events"] set) 49 | (update 1 set))))))))) 50 | 51 | (testing "returns empty when no entries are available" 52 | (with-queue queue 53 | (let [result (core/get-self-service-analytics queue)] 54 | (is (= [{"events" [], "snapshots" {}} []] result)))))) 55 | 56 | (deftest test-partition-entries 57 | (testing "partitions entries" 58 | (with-queue queue 59 | (let [fake-now (time/date-time 4321)] 60 | (time/do-at 61 | fake-now 62 | (let [event {"event" "some.weird.analytic"} 63 | event2 {"event" "some.other.analytic" 64 | "metadata" {"some.crazy.metadata" true}} 65 | snapshot {"fields" {"some.snapshot" 5}} 66 | id1 (storage/store queue (internal-api/->internal-event event)) 67 | id2 (storage/store queue (internal-api/->internal-event event2)) 68 | id3 (storage/store queue (internal-api/->internal-snapshot snapshot)) 69 | result (core/partition-entries queue)] 70 | (is (= [{"events" #{{"event" "some.weird.analytic" 71 | "timestamp" fake-now} 72 | {"event" "some.other.analytic" 73 | "metadata" {"some.crazy.metadata" true} 74 | "timestamp" fake-now}} 75 | "snapshots" {"some.snapshot" {"value" 5 76 | "timestamp" fake-now}}} 77 | #{id1 id2 id3}] 78 | (-> result 79 | (update-in [0 "events"] set) 80 | (update 1 set))))))))) 81 | 82 | (testing "only returns entries that were sent" 83 | (with-queue queue 84 | (let [fake-now (time/date-time 4321)] 85 | (time/do-at 86 | fake-now 87 | (let [event {"event" "some.weird.analytic"} 88 | event2 {"event" "some.other.analytic" 89 | "metadata" {"some.crazy.metadata" true}} 90 | snapshot1 {"fields" {"some.snapshot" 5}} 91 | snapshot2 {"fields" {"some.different.snapshot" 6}} 92 | id1 (storage/store queue (internal-api/->internal-event event)) 93 | id2 (storage/store queue (internal-api/->internal-event event2)) 94 | id3 (storage/store queue (internal-api/->internal-snapshot snapshot1)) 95 | result (core/partition-entries queue) 96 | _ (storage/store queue (internal-api/->internal-snapshot snapshot2))] 97 | (is (= #{id1 id2 id3} 98 | (-> result 99 | second 100 | set))))))))) 101 | 102 | (deftest combine-events 103 | (testing "adds new events by just concatenating them" 104 | (let [base-event-1 {"event" "1", "metadata" {}, "timestamp" (time/date-time 1000)} 105 | base-event-2 {"event" "2", "metadata" {}, "timestamp" (time/date-time 1001)} 106 | new-event-1 {"event" "12345" 107 | "metadata" {"whats" "up"} 108 | "timestamp" (time/date-time 1908)} 109 | new-event-2 {"event" "54321" 110 | "metadata" {"a" 1} 111 | "timestamp" (time/date-time 1929)}] 112 | (is (= {"events" [base-event-1 base-event-2 new-event-1 new-event-2] 113 | "snapshots" {}} 114 | (core/combine-events {"events" [base-event-1 base-event-2], "snapshots" {}} 115 | [new-event-1 new-event-2])))))) 116 | 117 | (deftest combine-snapshots 118 | (testing "adds new snapshots by taking the most recent of each snapshot" 119 | (let [base-uptime {"value" 1000, "timestamp" (time/date-time 500)} 120 | base-os {"value" "centos", "timestamp" (time/date-time 500)} 121 | base-arch {"value" "x64", "timestamp" (time/date-time 500)} ;; only in base 122 | new-uptime {"value" 1500, "timestamp" (time/date-time 1000)} 123 | new-ip {"value" "192.168.0.1", "timestamp" (time/date-time 1000)} ;; only in new 124 | outdated-os {"value" "debian", "timestamp" (time/date-time 200)}] 125 | (is (= {"events" [] 126 | "snapshots" {"uptime" new-uptime 127 | "os" base-os 128 | "arch" base-arch 129 | "ip" new-ip}} 130 | (core/combine-snapshots {"events" [] 131 | "snapshots" {"uptime" base-uptime 132 | "os" base-os 133 | "arch" base-arch}} 134 | {"uptime" new-uptime 135 | "os" outdated-os 136 | "ip" new-ip})))))) 137 | 138 | (deftest whitelist-snapshots 139 | (testing "rejects keys not in the whitelist" 140 | (let [whitelist {} 141 | snapshots {"a.b" {"value" "missing", "timestamp" (time/date-time 100)}} 142 | {:keys [accepted rejected]} (core/partition-snapshots-whitelist whitelist snapshots)] 143 | (is (= {} accepted)) 144 | (is (= {"a.b" "Not an expected field"} rejected)))) 145 | 146 | (testing "rejects keys of the wrong type" 147 | (let [whitelist {"c.d" {"datatype" "string" "description" "who knows"}} 148 | snapshots {"c.d" {"value" 3, "timestamp" (time/date-time 100)}} 149 | {:keys [accepted rejected]} (core/partition-snapshots-whitelist whitelist snapshots)] 150 | (is (= {} accepted)) 151 | (is (= {"c.d" "Expected a value of type string"} 152 | rejected))))) 153 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | THE ACCOMPANYING PROGRAM IS PROVIDED UNDER THE TERMS OF THIS ECLIPSE PUBLIC 2 | LICENSE ("AGREEMENT"). ANY USE, REPRODUCTION OR DISTRIBUTION OF THE PROGRAM 3 | CONSTITUTES RECIPIENT'S ACCEPTANCE OF THIS AGREEMENT. 4 | 5 | 1. DEFINITIONS 6 | 7 | "Contribution" means: 8 | 9 | a) in the case of the initial Contributor, the initial code and 10 | documentation distributed under this Agreement, and 11 | 12 | b) in the case of each subsequent Contributor: 13 | 14 | i) changes to the Program, and 15 | 16 | ii) additions to the Program; 17 | 18 | where such changes and/or additions to the Program originate from and are 19 | distributed by that particular Contributor. A Contribution 'originates' from 20 | a Contributor if it was added to the Program by such Contributor itself or 21 | anyone acting on such Contributor's behalf. Contributions do not include 22 | additions to the Program which: (i) are separate modules of software 23 | distributed in conjunction with the Program under their own license 24 | agreement, and (ii) are not derivative works of the Program. 25 | 26 | "Contributor" means any person or entity that distributes the Program. 27 | 28 | "Licensed Patents" mean patent claims licensable by a Contributor which are 29 | necessarily infringed by the use or sale of its Contribution alone or when 30 | combined with the Program. 31 | 32 | "Program" means the Contributions distributed in accordance with this 33 | Agreement. 34 | 35 | "Recipient" means anyone who receives the Program under this Agreement, 36 | including all Contributors. 37 | 38 | 2. GRANT OF RIGHTS 39 | 40 | a) Subject to the terms of this Agreement, each Contributor hereby grants 41 | Recipient a non-exclusive, worldwide, royalty-free copyright license to 42 | reproduce, prepare derivative works of, publicly display, publicly perform, 43 | distribute and sublicense the Contribution of such Contributor, if any, and 44 | such derivative works, in source code and object code form. 45 | 46 | b) Subject to the terms of this Agreement, each Contributor hereby grants 47 | Recipient a non-exclusive, worldwide, royalty-free patent license under 48 | Licensed Patents to make, use, sell, offer to sell, import and otherwise 49 | transfer the Contribution of such Contributor, if any, in source code and 50 | object code form. This patent license shall apply to the combination of the 51 | Contribution and the Program if, at the time the Contribution is added by the 52 | Contributor, such addition of the Contribution causes such combination to be 53 | covered by the Licensed Patents. The patent license shall not apply to any 54 | other combinations which include the Contribution. No hardware per se is 55 | licensed hereunder. 56 | 57 | c) Recipient understands that although each Contributor grants the licenses 58 | to its Contributions set forth herein, no assurances are provided by any 59 | Contributor that the Program does not infringe the patent or other 60 | intellectual property rights of any other entity. Each Contributor disclaims 61 | any liability to Recipient for claims brought by any other entity based on 62 | infringement of intellectual property rights or otherwise. As a condition to 63 | exercising the rights and licenses granted hereunder, each Recipient hereby 64 | assumes sole responsibility to secure any other intellectual property rights 65 | needed, if any. For example, if a third party patent license is required to 66 | allow Recipient to distribute the Program, it is Recipient's responsibility 67 | to acquire that license before distributing the Program. 68 | 69 | d) Each Contributor represents that to its knowledge it has sufficient 70 | copyright rights in its Contribution, if any, to grant the copyright license 71 | set forth in this Agreement. 72 | 73 | 3. REQUIREMENTS 74 | 75 | A Contributor may choose to distribute the Program in object code form under 76 | its own license agreement, provided that: 77 | 78 | a) it complies with the terms and conditions of this Agreement; and 79 | 80 | b) its license agreement: 81 | 82 | i) effectively disclaims on behalf of all Contributors all warranties and 83 | conditions, express and implied, including warranties or conditions of title 84 | and non-infringement, and implied warranties or conditions of merchantability 85 | and fitness for a particular purpose; 86 | 87 | ii) effectively excludes on behalf of all Contributors all liability for 88 | damages, including direct, indirect, special, incidental and consequential 89 | damages, such as lost profits; 90 | 91 | iii) states that any provisions which differ from this Agreement are offered 92 | by that Contributor alone and not by any other party; and 93 | 94 | iv) states that source code for the Program is available from such 95 | Contributor, and informs licensees how to obtain it in a reasonable manner on 96 | or through a medium customarily used for software exchange. 97 | 98 | When the Program is made available in source code form: 99 | 100 | a) it must be made available under this Agreement; and 101 | 102 | b) a copy of this Agreement must be included with each copy of the Program. 103 | 104 | Contributors may not remove or alter any copyright notices contained within 105 | the Program. 106 | 107 | Each Contributor must identify itself as the originator of its Contribution, 108 | if any, in a manner that reasonably allows subsequent Recipients to identify 109 | the originator of the Contribution. 110 | 111 | 4. COMMERCIAL DISTRIBUTION 112 | 113 | Commercial distributors of software may accept certain responsibilities with 114 | respect to end users, business partners and the like. While this license is 115 | intended to facilitate the commercial use of the Program, the Contributor who 116 | includes the Program in a commercial product offering should do so in a 117 | manner which does not create potential liability for other Contributors. 118 | Therefore, if a Contributor includes the Program in a commercial product 119 | offering, such Contributor ("Commercial Contributor") hereby agrees to defend 120 | and indemnify every other Contributor ("Indemnified Contributor") against any 121 | losses, damages and costs (collectively "Losses") arising from claims, 122 | lawsuits and other legal actions brought by a third party against the 123 | Indemnified Contributor to the extent caused by the acts or omissions of such 124 | Commercial Contributor in connection with its distribution of the Program in 125 | a commercial product offering. The obligations in this section do not apply 126 | to any claims or Losses relating to any actual or alleged intellectual 127 | property infringement. In order to qualify, an Indemnified Contributor must: 128 | a) promptly notify the Commercial Contributor in writing of such claim, and 129 | b) allow the Commercial Contributor to control, and cooperate with the 130 | Commercial Contributor in, the defense and any related settlement 131 | negotiations. The Indemnified Contributor may participate in any such claim 132 | at its own expense. 133 | 134 | For example, a Contributor might include the Program in a commercial product 135 | offering, Product X. That Contributor is then a Commercial Contributor. If 136 | that Commercial Contributor then makes performance claims, or offers 137 | warranties related to Product X, those performance claims and warranties are 138 | such Commercial Contributor's responsibility alone. Under this section, the 139 | Commercial Contributor would have to defend claims against the other 140 | Contributors related to those performance claims and warranties, and if a 141 | court requires any other Contributor to pay any damages as a result, the 142 | Commercial Contributor must pay those damages. 143 | 144 | 5. NO WARRANTY 145 | 146 | EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, THE PROGRAM IS PROVIDED ON 147 | AN "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, EITHER 148 | EXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION, ANY WARRANTIES OR 149 | CONDITIONS OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY OR FITNESS FOR A 150 | PARTICULAR PURPOSE. Each Recipient is solely responsible for determining the 151 | appropriateness of using and distributing the Program and assumes all risks 152 | associated with its exercise of rights under this Agreement , including but 153 | not limited to the risks and costs of program errors, compliance with 154 | applicable laws, damage to or loss of data, programs or equipment, and 155 | unavailability or interruption of operations. 156 | 157 | 6. DISCLAIMER OF LIABILITY 158 | 159 | EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, NEITHER RECIPIENT NOR ANY 160 | CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY DIRECT, INDIRECT, INCIDENTAL, 161 | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING WITHOUT LIMITATION 162 | LOST PROFITS), HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 163 | CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 164 | ARISING IN ANY WAY OUT OF THE USE OR DISTRIBUTION OF THE PROGRAM OR THE 165 | EXERCISE OF ANY RIGHTS GRANTED HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY 166 | OF SUCH DAMAGES. 167 | 168 | 7. GENERAL 169 | 170 | If any provision of this Agreement is invalid or unenforceable under 171 | applicable law, it shall not affect the validity or enforceability of the 172 | remainder of the terms of this Agreement, and without further action by the 173 | parties hereto, such provision shall be reformed to the minimum extent 174 | necessary to make such provision valid and enforceable. 175 | 176 | If Recipient institutes patent litigation against any entity (including a 177 | cross-claim or counterclaim in a lawsuit) alleging that the Program itself 178 | (excluding combinations of the Program with other software or hardware) 179 | infringes such Recipient's patent(s), then such Recipient's rights granted 180 | under Section 2(b) shall terminate as of the date such litigation is filed. 181 | 182 | All Recipient's rights under this Agreement shall terminate if it fails to 183 | comply with any of the material terms or conditions of this Agreement and 184 | does not cure such failure in a reasonable period of time after becoming 185 | aware of such noncompliance. If all Recipient's rights under this Agreement 186 | terminate, Recipient agrees to cease use and distribution of the Program as 187 | soon as reasonably practicable. However, Recipient's obligations under this 188 | Agreement and any licenses granted by Recipient relating to the Program shall 189 | continue and survive. 190 | 191 | Everyone is permitted to copy and distribute copies of this Agreement, but in 192 | order to avoid inconsistency the Agreement is copyrighted and may only be 193 | modified in the following manner. The Agreement Steward reserves the right to 194 | publish new versions (including revisions) of this Agreement from time to 195 | time. No one other than the Agreement Steward has the right to modify this 196 | Agreement. The Eclipse Foundation is the initial Agreement Steward. The 197 | Eclipse Foundation may assign the responsibility to serve as the Agreement 198 | Steward to a suitable separate entity. Each new version of the Agreement will 199 | be given a distinguishing version number. The Program (including 200 | Contributions) may always be distributed subject to the version of the 201 | Agreement under which it was received. In addition, after a new version of 202 | the Agreement is published, Contributor may elect to distribute the Program 203 | (including its Contributions) under the new version. Except as expressly 204 | stated in Sections 2(a) and 2(b) above, Recipient receives no rights or 205 | licenses to the intellectual property of any Contributor under this 206 | Agreement, whether expressly, by implication, estoppel or otherwise. All 207 | rights in the Program not expressly granted under this Agreement are 208 | reserved. 209 | 210 | This Agreement is governed by the laws of the State of New York and the 211 | intellectual property laws of the United States of America. No party to this 212 | Agreement will bring a legal action under this Agreement more than one year 213 | after the cause of action arose. Each party waives its rights to a jury trial 214 | in any resulting litigation. 215 | -------------------------------------------------------------------------------- /dev-resources/java.security.jdk8-fips: -------------------------------------------------------------------------------- 1 | # 2 | # This is the "master security properties file". 3 | # 4 | # An alternate java.security properties file may be specified 5 | # from the command line via the system property 6 | # 7 | # -Djava.security.properties= 8 | # 9 | # This properties file appends to the master security properties file. 10 | # If both properties files specify values for the same key, the value 11 | # from the command-line properties file is selected, as it is the last 12 | # one loaded. 13 | # 14 | # Also, if you specify 15 | # 16 | # -Djava.security.properties== (2 equals), 17 | # 18 | # then that properties file completely overrides the master security 19 | # properties file. 20 | # 21 | # To disable the ability to specify an additional properties file from 22 | # the command line, set the key security.overridePropertiesFile 23 | # to false in the master security properties file. It is set to true 24 | # by default. 25 | 26 | # In this file, various security properties are set for use by 27 | # java.security classes. This is where users can statically register 28 | # Cryptography Package Providers ("providers" for short). The term 29 | # "provider" refers to a package or set of packages that supply a 30 | # concrete implementation of a subset of the cryptography aspects of 31 | # the Java Security API. A provider may, for example, implement one or 32 | # more digital signature algorithms or message digest algorithms. 33 | # 34 | # Each provider must implement a subclass of the Provider class. 35 | # To register a provider in this master security properties file, 36 | # specify the Provider subclass name and priority in the format 37 | # 38 | # security.provider.= 39 | # 40 | # This declares a provider, and specifies its preference 41 | # order n. The preference order is the order in which providers are 42 | # searched for requested algorithms (when no specific provider is 43 | # requested). The order is 1-based; 1 is the most preferred, followed 44 | # by 2, and so on. 45 | # 46 | # must specify the subclass of the Provider class whose 47 | # constructor sets the values of various properties that are required 48 | # for the Java Security API to look up the algorithms or other 49 | # facilities implemented by the provider. 50 | # 51 | # There must be at least one provider specification in java.security. 52 | # There is a default provider that comes standard with the JDK. It 53 | # is called the "SUN" provider, and its Provider subclass 54 | # named Sun appears in the sun.security.provider package. Thus, the 55 | # "SUN" provider is registered via the following: 56 | # 57 | # security.provider.1=sun.security.provider.Sun 58 | # 59 | # (The number 1 is used for the default provider.) 60 | # 61 | # Note: Providers can be dynamically registered instead by calls to 62 | # either the addProvider or insertProviderAt method in the Security 63 | # class. 64 | 65 | # 66 | # List of providers and their preference orders (see above): 67 | # 68 | security.provider.1=org.bouncycastle.jcajce.provider.BouncyCastleFipsProvider 69 | security.provider.2=org.bouncycastle.jsse.provider.BouncyCastleJsseProvider fips:org.bouncycastle.jcajce.provider.BouncyCastleFipsProvider 70 | security.provider.3=sun.security.provider.Sun 71 | security.provider.4=sun.security.rsa.SunRsaSign 72 | #security.provider.5=sun.security.ec.SunEC 73 | #security.provider.6=com.sun.net.ssl.internal.ssl.Provider 74 | #security.provider.7=com.sun.crypto.provider.SunJCE 75 | #security.provider.8=sun.security.jgss.SunProvider 76 | #security.provider.9=com.sun.security.sasl.Provider 77 | #security.provider.10=org.jcp.xml.dsig.internal.dom.XMLDSigRI 78 | #security.provider.11=sun.security.smartcardio.SunPCSC 79 | 80 | # 81 | # Sun Provider SecureRandom seed source. 82 | # 83 | # Select the primary source of seed data for the "SHA1PRNG" and 84 | # "NativePRNG" SecureRandom implementations in the "Sun" provider. 85 | # (Other SecureRandom implementations might also use this property.) 86 | # 87 | # On Unix-like systems (for example, Solaris/Linux/MacOS), the 88 | # "NativePRNG" and "SHA1PRNG" implementations obtains seed data from 89 | # special device files such as file:/dev/random. 90 | # 91 | # On Windows systems, specifying the URLs "file:/dev/random" or 92 | # "file:/dev/urandom" will enable the native Microsoft CryptoAPI seeding 93 | # mechanism for SHA1PRNG. 94 | # 95 | # By default, an attempt is made to use the entropy gathering device 96 | # specified by the "securerandom.source" Security property. If an 97 | # exception occurs while accessing the specified URL: 98 | # 99 | # SHA1PRNG: 100 | # the traditional system/thread activity algorithm will be used. 101 | # 102 | # NativePRNG: 103 | # a default value of /dev/random will be used. If neither 104 | # are available, the implementation will be disabled. 105 | # "file" is the only currently supported protocol type. 106 | # 107 | # The entropy gathering device can also be specified with the System 108 | # property "java.security.egd". For example: 109 | # 110 | # % java -Djava.security.egd=file:/dev/random MainClass 111 | # 112 | # Specifying this System property will override the 113 | # "securerandom.source" Security property. 114 | # 115 | # In addition, if "file:/dev/random" or "file:/dev/urandom" is 116 | # specified, the "NativePRNG" implementation will be more preferred than 117 | # SHA1PRNG in the Sun provider. 118 | # 119 | securerandom.source=file:/dev/random 120 | 121 | # 122 | # A list of known strong SecureRandom implementations. 123 | # 124 | # To help guide applications in selecting a suitable strong 125 | # java.security.SecureRandom implementation, Java distributions should 126 | # indicate a list of known strong implementations using the property. 127 | # 128 | # This is a comma-separated list of algorithm and/or algorithm:provider 129 | # entries. 130 | # 131 | securerandom.strongAlgorithms=NativePRNGBlocking:SUN 132 | 133 | # 134 | # Class to instantiate as the javax.security.auth.login.Configuration 135 | # provider. 136 | # 137 | login.configuration.provider=sun.security.provider.ConfigFile 138 | 139 | # 140 | # Default login configuration file 141 | # 142 | #login.config.url.1=file:${user.home}/.java.login.config 143 | 144 | # 145 | # Class to instantiate as the system Policy. This is the name of the class 146 | # that will be used as the Policy object. 147 | # 148 | policy.provider=sun.security.provider.PolicyFile 149 | 150 | # The default is to have a single system-wide policy file, 151 | # and a policy file in the user's home directory. 152 | policy.url.1=file:${java.home}/lib/security/java.policy 153 | policy.url.2=file:${user.home}/.java.policy 154 | 155 | # whether or not we expand properties in the policy file 156 | # if this is set to false, properties (${...}) will not be expanded in policy 157 | # files. 158 | policy.expandProperties=true 159 | 160 | # whether or not we allow an extra policy to be passed on the command line 161 | # with -Djava.security.policy=somefile. Comment out this line to disable 162 | # this feature. 163 | policy.allowSystemProperty=true 164 | 165 | # whether or not we look into the IdentityScope for trusted Identities 166 | # when encountering a 1.1 signed JAR file. If the identity is found 167 | # and is trusted, we grant it AllPermission. 168 | policy.ignoreIdentityScope=false 169 | 170 | # 171 | # Default keystore type. 172 | # 173 | keystore.type=jks 174 | 175 | # 176 | # Controls compatibility mode for the JKS keystore type. 177 | # 178 | # When set to 'true', the JKS keystore type supports loading 179 | # keystore files in either JKS or PKCS12 format. When set to 'false' 180 | # it supports loading only JKS keystore files. 181 | # 182 | keystore.type.compat=true 183 | 184 | # 185 | # List of comma-separated packages that start with or equal this string 186 | # will cause a security exception to be thrown when 187 | # passed to checkPackageAccess unless the 188 | # corresponding RuntimePermission ("accessClassInPackage."+package) has 189 | # been granted. 190 | package.access=sun.,\ 191 | org.GNOME.Accessibility.,\ 192 | com.sun.xml.internal.,\ 193 | com.sun.imageio.,\ 194 | com.sun.istack.internal.,\ 195 | com.sun.jmx.,\ 196 | com.sun.media.sound.,\ 197 | com.sun.naming.internal.,\ 198 | com.sun.proxy.,\ 199 | com.sun.corba.se.,\ 200 | com.sun.org.apache.bcel.internal.,\ 201 | com.sun.org.apache.regexp.internal.,\ 202 | com.sun.org.apache.xerces.internal.,\ 203 | com.sun.org.apache.xpath.internal.,\ 204 | com.sun.org.apache.xalan.internal.extensions.,\ 205 | com.sun.org.apache.xalan.internal.lib.,\ 206 | com.sun.org.apache.xalan.internal.res.,\ 207 | com.sun.org.apache.xalan.internal.templates.,\ 208 | com.sun.org.apache.xalan.internal.utils.,\ 209 | com.sun.org.apache.xalan.internal.xslt.,\ 210 | com.sun.org.apache.xalan.internal.xsltc.cmdline.,\ 211 | com.sun.org.apache.xalan.internal.xsltc.compiler.,\ 212 | com.sun.org.apache.xalan.internal.xsltc.trax.,\ 213 | com.sun.org.apache.xalan.internal.xsltc.util.,\ 214 | com.sun.org.apache.xml.internal.res.,\ 215 | com.sun.org.apache.xml.internal.resolver.helpers.,\ 216 | com.sun.org.apache.xml.internal.resolver.readers.,\ 217 | com.sun.org.apache.xml.internal.security.,\ 218 | com.sun.org.apache.xml.internal.serializer.utils.,\ 219 | com.sun.org.apache.xml.internal.utils.,\ 220 | com.sun.org.glassfish.,\ 221 | com.oracle.xmlns.internal.,\ 222 | com.oracle.webservices.internal.,\ 223 | oracle.jrockit.jfr.,\ 224 | org.jcp.xml.dsig.internal.,\ 225 | jdk.internal.,\ 226 | jdk.nashorn.internal.,\ 227 | jdk.nashorn.tools.,\ 228 | jdk.xml.internal.,\ 229 | com.sun.activation.registries. 230 | 231 | # 232 | # List of comma-separated packages that start with or equal this string 233 | # will cause a security exception to be thrown when 234 | # passed to checkPackageDefinition unless the 235 | # corresponding RuntimePermission ("defineClassInPackage."+package) has 236 | # been granted. 237 | # 238 | # by default, none of the class loaders supplied with the JDK call 239 | # checkPackageDefinition. 240 | # 241 | package.definition=sun.,\ 242 | com.sun.xml.internal.,\ 243 | com.sun.imageio.,\ 244 | com.sun.istack.internal.,\ 245 | com.sun.jmx.,\ 246 | com.sun.media.sound.,\ 247 | com.sun.naming.internal.,\ 248 | com.sun.proxy.,\ 249 | com.sun.corba.se.,\ 250 | com.sun.org.apache.bcel.internal.,\ 251 | com.sun.org.apache.regexp.internal.,\ 252 | com.sun.org.apache.xerces.internal.,\ 253 | com.sun.org.apache.xpath.internal.,\ 254 | com.sun.org.apache.xalan.internal.extensions.,\ 255 | com.sun.org.apache.xalan.internal.lib.,\ 256 | com.sun.org.apache.xalan.internal.res.,\ 257 | com.sun.org.apache.xalan.internal.templates.,\ 258 | com.sun.org.apache.xalan.internal.utils.,\ 259 | com.sun.org.apache.xalan.internal.xslt.,\ 260 | com.sun.org.apache.xalan.internal.xsltc.cmdline.,\ 261 | com.sun.org.apache.xalan.internal.xsltc.compiler.,\ 262 | com.sun.org.apache.xalan.internal.xsltc.trax.,\ 263 | com.sun.org.apache.xalan.internal.xsltc.util.,\ 264 | com.sun.org.apache.xml.internal.res.,\ 265 | com.sun.org.apache.xml.internal.resolver.helpers.,\ 266 | com.sun.org.apache.xml.internal.resolver.readers.,\ 267 | com.sun.org.apache.xml.internal.security.,\ 268 | com.sun.org.apache.xml.internal.serializer.utils.,\ 269 | com.sun.org.apache.xml.internal.utils.,\ 270 | com.sun.org.glassfish.,\ 271 | com.oracle.xmlns.internal.,\ 272 | com.oracle.webservices.internal.,\ 273 | oracle.jrockit.jfr.,\ 274 | org.jcp.xml.dsig.internal.,\ 275 | jdk.internal.,\ 276 | jdk.nashorn.internal.,\ 277 | jdk.nashorn.tools.,\ 278 | jdk.xml.internal.,\ 279 | com.sun.activation.registries. 280 | 281 | # 282 | # Determines whether this properties file can be appended to 283 | # or overridden on the command line via -Djava.security.properties 284 | # 285 | security.overridePropertiesFile=true 286 | 287 | # 288 | # Determines the default key and trust manager factory algorithms for 289 | # the javax.net.ssl package. 290 | # 291 | ssl.KeyManagerFactory.algorithm=BCFKS 292 | ssl.TrustManagerFactory.algorithm=PKIX 293 | 294 | # 295 | # The Java-level namelookup cache policy for successful lookups: 296 | # 297 | # any negative value: caching forever 298 | # any positive value: the number of seconds to cache an address for 299 | # zero: do not cache 300 | # 301 | # default value is forever (FOREVER). For security reasons, this 302 | # caching is made forever when a security manager is set. When a security 303 | # manager is not set, the default behavior in this implementation 304 | # is to cache for 30 seconds. 305 | # 306 | # NOTE: setting this to anything other than the default value can have 307 | # serious security implications. Do not set it unless 308 | # you are sure you are not exposed to DNS spoofing attack. 309 | # 310 | #networkaddress.cache.ttl=-1 311 | 312 | # The Java-level namelookup cache policy for failed lookups: 313 | # 314 | # any negative value: cache forever 315 | # any positive value: the number of seconds to cache negative lookup results 316 | # zero: do not cache 317 | # 318 | # In some Microsoft Windows networking environments that employ 319 | # the WINS name service in addition to DNS, name service lookups 320 | # that fail may take a noticeably long time to return (approx. 5 seconds). 321 | # For this reason the default caching policy is to maintain these 322 | # results for 10 seconds. 323 | # 324 | # 325 | networkaddress.cache.negative.ttl=10 326 | 327 | # 328 | # Properties to configure OCSP for certificate revocation checking 329 | # 330 | 331 | # Enable OCSP 332 | # 333 | # By default, OCSP is not used for certificate revocation checking. 334 | # This property enables the use of OCSP when set to the value "true". 335 | # 336 | # NOTE: SocketPermission is required to connect to an OCSP responder. 337 | # 338 | # Example, 339 | # ocsp.enable=true 340 | 341 | # 342 | # Location of the OCSP responder 343 | # 344 | # By default, the location of the OCSP responder is determined implicitly 345 | # from the certificate being validated. This property explicitly specifies 346 | # the location of the OCSP responder. The property is used when the 347 | # Authority Information Access extension (defined in RFC 3280) is absent 348 | # from the certificate or when it requires overriding. 349 | # 350 | # Example, 351 | # ocsp.responderURL=http://ocsp.example.net:80 352 | 353 | # 354 | # Subject name of the OCSP responder's certificate 355 | # 356 | # By default, the certificate of the OCSP responder is that of the issuer 357 | # of the certificate being validated. This property identifies the certificate 358 | # of the OCSP responder when the default does not apply. Its value is a string 359 | # distinguished name (defined in RFC 2253) which identifies a certificate in 360 | # the set of certificates supplied during cert path validation. In cases where 361 | # the subject name alone is not sufficient to uniquely identify the certificate 362 | # then both the "ocsp.responderCertIssuerName" and 363 | # "ocsp.responderCertSerialNumber" properties must be used instead. When this 364 | # property is set then those two properties are ignored. 365 | # 366 | # Example, 367 | # ocsp.responderCertSubjectName="CN=OCSP Responder, O=XYZ Corp" 368 | 369 | # 370 | # Issuer name of the OCSP responder's certificate 371 | # 372 | # By default, the certificate of the OCSP responder is that of the issuer 373 | # of the certificate being validated. This property identifies the certificate 374 | # of the OCSP responder when the default does not apply. Its value is a string 375 | # distinguished name (defined in RFC 2253) which identifies a certificate in 376 | # the set of certificates supplied during cert path validation. When this 377 | # property is set then the "ocsp.responderCertSerialNumber" property must also 378 | # be set. When the "ocsp.responderCertSubjectName" property is set then this 379 | # property is ignored. 380 | # 381 | # Example, 382 | # ocsp.responderCertIssuerName="CN=Enterprise CA, O=XYZ Corp" 383 | 384 | # 385 | # Serial number of the OCSP responder's certificate 386 | # 387 | # By default, the certificate of the OCSP responder is that of the issuer 388 | # of the certificate being validated. This property identifies the certificate 389 | # of the OCSP responder when the default does not apply. Its value is a string 390 | # of hexadecimal digits (colon or space separators may be present) which 391 | # identifies a certificate in the set of certificates supplied during cert path 392 | # validation. When this property is set then the "ocsp.responderCertIssuerName" 393 | # property must also be set. When the "ocsp.responderCertSubjectName" property 394 | # is set then this property is ignored. 395 | # 396 | # Example, 397 | # ocsp.responderCertSerialNumber=2A:FF:00 398 | 399 | # 400 | # Policy for failed Kerberos KDC lookups: 401 | # 402 | # When a KDC is unavailable (network error, service failure, etc), it is 403 | # put inside a blacklist and accessed less often for future requests. The 404 | # value (case-insensitive) for this policy can be: 405 | # 406 | # tryLast 407 | # KDCs in the blacklist are always tried after those not on the list. 408 | # 409 | # tryLess[:max_retries,timeout] 410 | # KDCs in the blacklist are still tried by their order in the configuration, 411 | # but with smaller max_retries and timeout values. max_retries and timeout 412 | # are optional numerical parameters (default 1 and 5000, which means once 413 | # and 5 seconds). Please notes that if any of the values defined here is 414 | # more than what is defined in krb5.conf, it will be ignored. 415 | # 416 | # Whenever a KDC is detected as available, it is removed from the blacklist. 417 | # The blacklist is reset when krb5.conf is reloaded. You can add 418 | # refreshKrb5Config=true to a JAAS configuration file so that krb5.conf is 419 | # reloaded whenever a JAAS authentication is attempted. 420 | # 421 | # Example, 422 | # krb5.kdc.bad.policy = tryLast 423 | # krb5.kdc.bad.policy = tryLess:2,2000 424 | krb5.kdc.bad.policy = tryLast 425 | 426 | # Algorithm restrictions for certification path (CertPath) processing 427 | # 428 | # In some environments, certain algorithms or key lengths may be undesirable 429 | # for certification path building and validation. For example, "MD2" is 430 | # generally no longer considered to be a secure hash algorithm. This section 431 | # describes the mechanism for disabling algorithms based on algorithm name 432 | # and/or key length. This includes algorithms used in certificates, as well 433 | # as revocation information such as CRLs and signed OCSP Responses. 434 | # The syntax of the disabled algorithm string is described as follows: 435 | # DisabledAlgorithms: 436 | # " DisabledAlgorithm { , DisabledAlgorithm } " 437 | # 438 | # DisabledAlgorithm: 439 | # AlgorithmName [Constraint] { '&' Constraint } 440 | # 441 | # AlgorithmName: 442 | # (see below) 443 | # 444 | # Constraint: 445 | # KeySizeConstraint | CAConstraint | DenyAfterConstraint | 446 | # UsageConstraint 447 | # 448 | # KeySizeConstraint: 449 | # keySize Operator KeyLength 450 | # 451 | # Operator: 452 | # <= | < | == | != | >= | > 453 | # 454 | # KeyLength: 455 | # Integer value of the algorithm's key length in bits 456 | # 457 | # CAConstraint: 458 | # jdkCA 459 | # 460 | # DenyAfterConstraint: 461 | # denyAfter YYYY-MM-DD 462 | # 463 | # UsageConstraint: 464 | # usage [TLSServer] [TLSClient] [SignedJAR] 465 | # 466 | # The "AlgorithmName" is the standard algorithm name of the disabled 467 | # algorithm. See "Java Cryptography Architecture Standard Algorithm Name 468 | # Documentation" for information about Standard Algorithm Names. Matching 469 | # is performed using a case-insensitive sub-element matching rule. (For 470 | # example, in "SHA1withECDSA" the sub-elements are "SHA1" for hashing and 471 | # "ECDSA" for signatures.) If the assertion "AlgorithmName" is a 472 | # sub-element of the certificate algorithm name, the algorithm will be 473 | # rejected during certification path building and validation. For example, 474 | # the assertion algorithm name "DSA" will disable all certificate algorithms 475 | # that rely on DSA, such as NONEwithDSA, SHA1withDSA. However, the assertion 476 | # will not disable algorithms related to "ECDSA". 477 | # 478 | # A "Constraint" defines restrictions on the keys and/or certificates for 479 | # a specified AlgorithmName: 480 | # 481 | # KeySizeConstraint: 482 | # keySize Operator KeyLength 483 | # The constraint requires a key of a valid size range if the 484 | # "AlgorithmName" is of a key algorithm. The "KeyLength" indicates 485 | # the key size specified in number of bits. For example, 486 | # "RSA keySize <= 1024" indicates that any RSA key with key size less 487 | # than or equal to 1024 bits should be disabled, and 488 | # "RSA keySize < 1024, RSA keySize > 2048" indicates that any RSA key 489 | # with key size less than 1024 or greater than 2048 should be disabled. 490 | # This constraint is only used on algorithms that have a key size. 491 | # 492 | # CAConstraint: 493 | # jdkCA 494 | # This constraint prohibits the specified algorithm only if the 495 | # algorithm is used in a certificate chain that terminates at a marked 496 | # trust anchor in the lib/security/cacerts keystore. If the jdkCA 497 | # constraint is not set, then all chains using the specified algorithm 498 | # are restricted. jdkCA may only be used once in a DisabledAlgorithm 499 | # expression. 500 | # Example: To apply this constraint to SHA-1 certificates, include 501 | # the following: "SHA1 jdkCA" 502 | # 503 | # DenyAfterConstraint: 504 | # denyAfter YYYY-MM-DD 505 | # This constraint prohibits a certificate with the specified algorithm 506 | # from being used after the date regardless of the certificate's 507 | # validity. JAR files that are signed and timestamped before the 508 | # constraint date with certificates containing the disabled algorithm 509 | # will not be restricted. The date is processed in the UTC timezone. 510 | # This constraint can only be used once in a DisabledAlgorithm 511 | # expression. 512 | # Example: To deny usage of RSA 2048 bit certificates after Feb 3 2020, 513 | # use the following: "RSA keySize == 2048 & denyAfter 2020-02-03" 514 | # 515 | # UsageConstraint: 516 | # usage [TLSServer] [TLSClient] [SignedJAR] 517 | # This constraint prohibits the specified algorithm for 518 | # a specified usage. This should be used when disabling an algorithm 519 | # for all usages is not practical. 'TLSServer' restricts the algorithm 520 | # in TLS server certificate chains when server authentication is 521 | # performed. 'TLSClient' restricts the algorithm in TLS client 522 | # certificate chains when client authentication is performed. 523 | # 'SignedJAR' constrains use of certificates in signed jar files. 524 | # The usage type follows the keyword and more than one usage type can 525 | # be specified with a whitespace delimiter. 526 | # Example: "SHA1 usage TLSServer TLSClient" 527 | # 528 | # When an algorithm must satisfy more than one constraint, it must be 529 | # delimited by an ampersand '&'. For example, to restrict certificates in a 530 | # chain that terminate at a distribution provided trust anchor and contain 531 | # RSA keys that are less than or equal to 1024 bits, add the following 532 | # constraint: "RSA keySize <= 1024 & jdkCA". 533 | # 534 | # All DisabledAlgorithms expressions are processed in the order defined in the 535 | # property. This requires lower keysize constraints to be specified 536 | # before larger keysize constraints of the same algorithm. For example: 537 | # "RSA keySize < 1024 & jdkCA, RSA keySize < 2048". 538 | # 539 | # Note: The algorithm restrictions do not apply to trust anchors or 540 | # self-signed certificates. 541 | # 542 | # Note: This property is currently used by Oracle's PKIX implementation. It 543 | # is not guaranteed to be examined and used by other implementations. 544 | # 545 | # Example: 546 | # jdk.certpath.disabledAlgorithms=MD2, DSA, RSA keySize < 2048 547 | # 548 | # 549 | jdk.certpath.disabledAlgorithms=MD2, MD5, SHA1 jdkCA & usage TLSServer, \ 550 | RSA keySize < 1024, DSA keySize < 1024, EC keySize < 224 551 | 552 | # 553 | # Algorithm restrictions for signed JAR files 554 | # 555 | # In some environments, certain algorithms or key lengths may be undesirable 556 | # for signed JAR validation. For example, "MD2" is generally no longer 557 | # considered to be a secure hash algorithm. This section describes the 558 | # mechanism for disabling algorithms based on algorithm name and/or key length. 559 | # JARs signed with any of the disabled algorithms or key sizes will be treated 560 | # as unsigned. 561 | # 562 | # The syntax of the disabled algorithm string is described as follows: 563 | # DisabledAlgorithms: 564 | # " DisabledAlgorithm { , DisabledAlgorithm } " 565 | # 566 | # DisabledAlgorithm: 567 | # AlgorithmName [Constraint] { '&' Constraint } 568 | # 569 | # AlgorithmName: 570 | # (see below) 571 | # 572 | # Constraint: 573 | # KeySizeConstraint | DenyAfterConstraint 574 | # 575 | # KeySizeConstraint: 576 | # keySize Operator KeyLength 577 | # 578 | # DenyAfterConstraint: 579 | # denyAfter YYYY-MM-DD 580 | # 581 | # Operator: 582 | # <= | < | == | != | >= | > 583 | # 584 | # KeyLength: 585 | # Integer value of the algorithm's key length in bits 586 | # 587 | # Note: This property is currently used by the JDK Reference 588 | # implementation. It is not guaranteed to be examined and used by other 589 | # implementations. 590 | # 591 | # See "jdk.certpath.disabledAlgorithms" for syntax descriptions. 592 | # 593 | jdk.jar.disabledAlgorithms=MD2, MD5, RSA keySize < 1024, DSA keySize < 1024 594 | 595 | # 596 | # Algorithm restrictions for Secure Socket Layer/Transport Layer Security 597 | # (SSL/TLS) processing 598 | # 599 | # In some environments, certain algorithms or key lengths may be undesirable 600 | # when using SSL/TLS. This section describes the mechanism for disabling 601 | # algorithms during SSL/TLS security parameters negotiation, including 602 | # protocol version negotiation, cipher suites selection, peer authentication 603 | # and key exchange mechanisms. 604 | # 605 | # Disabled algorithms will not be negotiated for SSL/TLS connections, even 606 | # if they are enabled explicitly in an application. 607 | # 608 | # For PKI-based peer authentication and key exchange mechanisms, this list 609 | # of disabled algorithms will also be checked during certification path 610 | # building and validation, including algorithms used in certificates, as 611 | # well as revocation information such as CRLs and signed OCSP Responses. 612 | # This is in addition to the jdk.certpath.disabledAlgorithms property above. 613 | # 614 | # See the specification of "jdk.certpath.disabledAlgorithms" for the 615 | # syntax of the disabled algorithm string. 616 | # 617 | # Note: The algorithm restrictions do not apply to trust anchors or 618 | # self-signed certificates. 619 | # 620 | # Note: This property is currently used by the JDK Reference implementation. 621 | # It is not guaranteed to be examined and used by other implementations. 622 | # 623 | # Example: 624 | # jdk.tls.disabledAlgorithms=MD5, SSLv3, DSA, RSA keySize < 2048 625 | jdk.tls.disabledAlgorithms=SSLv3, RC4, DES, MD5withRSA, DH keySize < 1024, \ 626 | EC keySize < 224, 3DES_EDE_CBC, anon, NULL 627 | 628 | # Legacy algorithms for Secure Socket Layer/Transport Layer Security (SSL/TLS) 629 | # processing in JSSE implementation. 630 | # 631 | # In some environments, a certain algorithm may be undesirable but it 632 | # cannot be disabled because of its use in legacy applications. Legacy 633 | # algorithms may still be supported, but applications should not use them 634 | # as the security strength of legacy algorithms are usually not strong enough 635 | # in practice. 636 | # 637 | # During SSL/TLS security parameters negotiation, legacy algorithms will 638 | # not be negotiated unless there are no other candidates. 639 | # 640 | # The syntax of the legacy algorithms string is described as this Java 641 | # BNF-style: 642 | # LegacyAlgorithms: 643 | # " LegacyAlgorithm { , LegacyAlgorithm } " 644 | # 645 | # LegacyAlgorithm: 646 | # AlgorithmName (standard JSSE algorithm name) 647 | # 648 | # See the specification of security property "jdk.certpath.disabledAlgorithms" 649 | # for the syntax and description of the "AlgorithmName" notation. 650 | # 651 | # Per SSL/TLS specifications, cipher suites have the form: 652 | # SSL_KeyExchangeAlg_WITH_CipherAlg_MacAlg 653 | # or 654 | # TLS_KeyExchangeAlg_WITH_CipherAlg_MacAlg 655 | # 656 | # For example, the cipher suite TLS_RSA_WITH_AES_128_CBC_SHA uses RSA as the 657 | # key exchange algorithm, AES_128_CBC (128 bits AES cipher algorithm in CBC 658 | # mode) as the cipher (encryption) algorithm, and SHA-1 as the message digest 659 | # algorithm for HMAC. 660 | # 661 | # The LegacyAlgorithm can be one of the following standard algorithm names: 662 | # 1. JSSE cipher suite name, e.g., TLS_RSA_WITH_AES_128_CBC_SHA 663 | # 2. JSSE key exchange algorithm name, e.g., RSA 664 | # 3. JSSE cipher (encryption) algorithm name, e.g., AES_128_CBC 665 | # 4. JSSE message digest algorithm name, e.g., SHA 666 | # 667 | # See SSL/TLS specifications and "Java Cryptography Architecture Standard 668 | # Algorithm Name Documentation" for information about the algorithm names. 669 | # 670 | # Note: This property is currently used by the JDK Reference implementation. 671 | # It is not guaranteed to be examined and used by other implementations. 672 | # There is no guarantee the property will continue to exist or be of the 673 | # same syntax in future releases. 674 | # 675 | # Example: 676 | # jdk.tls.legacyAlgorithms=DH_anon, DES_CBC, SSL_RSA_WITH_RC4_128_MD5 677 | # 678 | jdk.tls.legacyAlgorithms= \ 679 | K_NULL, C_NULL, M_NULL, \ 680 | DH_anon, ECDH_anon, \ 681 | RC4_128, RC4_40, DES_CBC, DES40_CBC, \ 682 | 3DES_EDE_CBC 683 | 684 | # The pre-defined default finite field Diffie-Hellman ephemeral (DHE) 685 | # parameters for Transport Layer Security (SSL/TLS/DTLS) processing. 686 | # 687 | # In traditional SSL/TLS/DTLS connections where finite field DHE parameters 688 | # negotiation mechanism is not used, the server offers the client group 689 | # parameters, base generator g and prime modulus p, for DHE key exchange. 690 | # It is recommended to use dynamic group parameters. This property defines 691 | # a mechanism that allows you to specify custom group parameters. 692 | # 693 | # The syntax of this property string is described as this Java BNF-style: 694 | # DefaultDHEParameters: 695 | # DefinedDHEParameters { , DefinedDHEParameters } 696 | # 697 | # DefinedDHEParameters: 698 | # "{" DHEPrimeModulus , DHEBaseGenerator "}" 699 | # 700 | # DHEPrimeModulus: 701 | # HexadecimalDigits 702 | # 703 | # DHEBaseGenerator: 704 | # HexadecimalDigits 705 | # 706 | # HexadecimalDigits: 707 | # HexadecimalDigit { HexadecimalDigit } 708 | # 709 | # HexadecimalDigit: one of 710 | # 0 1 2 3 4 5 6 7 8 9 A B C D E F a b c d e f 711 | # 712 | # Whitespace characters are ignored. 713 | # 714 | # The "DefinedDHEParameters" defines the custom group parameters, prime 715 | # modulus p and base generator g, for a particular size of prime modulus p. 716 | # The "DHEPrimeModulus" defines the hexadecimal prime modulus p, and the 717 | # "DHEBaseGenerator" defines the hexadecimal base generator g of a group 718 | # parameter. It is recommended to use safe primes for the custom group 719 | # parameters. 720 | # 721 | # If this property is not defined or the value is empty, the underlying JSSE 722 | # provider's default group parameter is used for each connection. 723 | # 724 | # If the property value does not follow the grammar, or a particular group 725 | # parameter is not valid, the connection will fall back and use the 726 | # underlying JSSE provider's default group parameter. 727 | # 728 | # Note: This property is currently used by OpenJDK's JSSE implementation. It 729 | # is not guaranteed to be examined and used by other implementations. 730 | # 731 | # Example: 732 | # jdk.tls.server.defaultDHEParameters= 733 | # { \ 734 | # FFFFFFFF FFFFFFFF C90FDAA2 2168C234 C4C6628B 80DC1CD1 \ 735 | # 29024E08 8A67CC74 020BBEA6 3B139B22 514A0879 8E3404DD \ 736 | # EF9519B3 CD3A431B 302B0A6D F25F1437 4FE1356D 6D51C245 \ 737 | # E485B576 625E7EC6 F44C42E9 A637ED6B 0BFF5CB6 F406B7ED \ 738 | # EE386BFB 5A899FA5 AE9F2411 7C4B1FE6 49286651 ECE65381 \ 739 | # FFFFFFFF FFFFFFFF, 2} 740 | 741 | # Cryptographic Jurisdiction Policy defaults 742 | # 743 | # Import and export control rules on cryptographic software vary from 744 | # country to country. By default, the JDK provides two different sets of 745 | # cryptographic policy files: 746 | # 747 | # unlimited: These policy files contain no restrictions on cryptographic 748 | # strengths or algorithms. 749 | # 750 | # limited: These policy files contain more restricted cryptographic 751 | # strengths, and are still available if your country or 752 | # usage requires the traditional restrictive policy. 753 | # 754 | # The JDK JCE framework uses the unlimited policy files by default. 755 | # However the user may explicitly choose a set either by defining the 756 | # "crypto.policy" Security property or by installing valid JCE policy 757 | # jar files into the traditional JDK installation location. To better 758 | # support older JDK Update releases, the "crypto.policy" property is not 759 | # defined by default. See below for more information. 760 | # 761 | # The following logic determines which policy files are used: 762 | # 763 | # refers to the directory where the JRE was 764 | # installed and may be determined using the "java.home" 765 | # System property. 766 | # 767 | # 1. If the Security property "crypto.policy" has been defined, 768 | # then the following mechanism is used: 769 | # 770 | # The policy files are stored as jar files in subdirectories of 771 | # /lib/security/policy. Each directory contains a complete 772 | # set of policy files. 773 | # 774 | # The "crypto.policy" Security property controls the directory 775 | # selection, and thus the effective cryptographic policy. 776 | # 777 | # The default set of directories is: 778 | # 779 | # limited | unlimited 780 | # 781 | # 2. If the "crypto.policy" property is not set and the traditional 782 | # US_export_policy.jar and local_policy.jar files 783 | # (e.g. limited/unlimited) are found in the legacy 784 | # /lib/security directory, then the rules embedded within 785 | # those jar files will be used. This helps preserve compatibility 786 | # for users upgrading from an older installation. 787 | # 788 | # 3. If the jar files are not present in the legacy location 789 | # and the "crypto.policy" Security property is not defined, 790 | # then the JDK will use the unlimited settings (equivalent to 791 | # crypto.policy=unlimited) 792 | # 793 | # Please see the JCA documentation for additional information on these 794 | # files and formats. 795 | # 796 | # YOU ARE ADVISED TO CONSULT YOUR EXPORT/IMPORT CONTROL COUNSEL OR ATTORNEY 797 | # TO DETERMINE THE EXACT REQUIREMENTS. 798 | # 799 | # Please note that the JCE for Java SE, including the JCE framework, 800 | # cryptographic policy files, and standard JCE providers provided with 801 | # the Java SE, have been reviewed and approved for export as mass market 802 | # encryption item by the US Bureau of Industry and Security. 803 | # 804 | # Note: This property is currently used by the JDK Reference implementation. 805 | # It is not guaranteed to be examined and used by other implementations. 806 | # 807 | crypto.policy=unlimited 808 | 809 | # 810 | # The policy for the XML Signature secure validation mode. The mode is 811 | # enabled by setting the property "org.jcp.xml.dsig.secureValidation" to 812 | # true with the javax.xml.crypto.XMLCryptoContext.setProperty() method, 813 | # or by running the code with a SecurityManager. 814 | # 815 | # Policy: 816 | # Constraint {"," Constraint } 817 | # Constraint: 818 | # AlgConstraint | MaxTransformsConstraint | MaxReferencesConstraint | 819 | # ReferenceUriSchemeConstraint | KeySizeConstraint | OtherConstraint 820 | # AlgConstraint 821 | # "disallowAlg" Uri 822 | # MaxTransformsConstraint: 823 | # "maxTransforms" Integer 824 | # MaxReferencesConstraint: 825 | # "maxReferences" Integer 826 | # ReferenceUriSchemeConstraint: 827 | # "disallowReferenceUriSchemes" String { String } 828 | # KeySizeConstraint: 829 | # "minKeySize" KeyAlg Integer 830 | # OtherConstraint: 831 | # "noDuplicateIds" | "noRetrievalMethodLoops" 832 | # 833 | # For AlgConstraint, Uri is the algorithm URI String that is not allowed. 834 | # See the XML Signature Recommendation for more information on algorithm 835 | # URI Identifiers. For KeySizeConstraint, KeyAlg is the standard algorithm 836 | # name of the key type (ex: "RSA"). If the MaxTransformsConstraint, 837 | # MaxReferencesConstraint or KeySizeConstraint (for the same key type) is 838 | # specified more than once, only the last entry is enforced. 839 | # 840 | # Note: This property is currently used by the JDK Reference implementation. It 841 | # is not guaranteed to be examined and used by other implementations. 842 | # 843 | jdk.xml.dsig.secureValidationPolicy=\ 844 | disallowAlg http://www.w3.org/TR/1999/REC-xslt-19991116,\ 845 | disallowAlg http://www.w3.org/2001/04/xmldsig-more#rsa-md5,\ 846 | disallowAlg http://www.w3.org/2001/04/xmldsig-more#hmac-md5,\ 847 | disallowAlg http://www.w3.org/2001/04/xmldsig-more#md5,\ 848 | maxTransforms 5,\ 849 | maxReferences 30,\ 850 | disallowReferenceUriSchemes file http https,\ 851 | minKeySize RSA 1024,\ 852 | minKeySize DSA 1024,\ 853 | minKeySize EC 224,\ 854 | noDuplicateIds,\ 855 | noRetrievalMethodLoops 856 | 857 | # 858 | # Serialization process-wide filter 859 | # 860 | # A filter, if configured, is used by java.io.ObjectInputStream during 861 | # deserialization to check the contents of the stream. 862 | # A filter is configured as a sequence of patterns, each pattern is either 863 | # matched against the name of a class in the stream or defines a limit. 864 | # Patterns are separated by ";" (semicolon). 865 | # Whitespace is significant and is considered part of the pattern. 866 | # 867 | # If the system property jdk.serialFilter is also specified, it supersedes 868 | # the security property value defined here. 869 | # 870 | # If a pattern includes a "=", it sets a limit. 871 | # If a limit appears more than once the last value is used. 872 | # Limits are checked before classes regardless of the order in the sequence of patterns. 873 | # If any of the limits are exceeded, the filter status is REJECTED. 874 | # 875 | # maxdepth=value - the maximum depth of a graph 876 | # maxrefs=value - the maximum number of internal references 877 | # maxbytes=value - the maximum number of bytes in the input stream 878 | # maxarray=value - the maximum array length allowed 879 | # 880 | # Other patterns, from left to right, match the class or package name as 881 | # returned from Class.getName. 882 | # If the class is an array type, the class or package to be matched is the element type. 883 | # Arrays of any number of dimensions are treated the same as the element type. 884 | # For example, a pattern of "!example.Foo", rejects creation of any instance or 885 | # array of example.Foo. 886 | # 887 | # If the pattern starts with "!", the status is REJECTED if the remaining pattern 888 | # is matched; otherwise the status is ALLOWED if the pattern matches. 889 | # If the pattern ends with ".**" it matches any class in the package and all subpackages. 890 | # If the pattern ends with ".*" it matches any class in the package. 891 | # If the pattern ends with "*", it matches any class with the pattern as a prefix. 892 | # If the pattern is equal to the class name, it matches. 893 | # Otherwise, the status is UNDECIDED. 894 | # 895 | # Primitive types are not configurable with this filter. 896 | # 897 | #jdk.serialFilter=pattern;pattern 898 | 899 | # 900 | # RMI Registry Serial Filter 901 | # 902 | # The filter pattern uses the same format as jdk.serialFilter. 903 | # This filter can override the builtin filter if additional types need to be 904 | # allowed or rejected from the RMI Registry or to decrease limits but not 905 | # to increase limits. 906 | # If the limits (maxdepth, maxrefs, or maxbytes) are exceeded, the object is rejected. 907 | # 908 | # The maxdepth of any array passed to the RMI Registry is set to 909 | # 10000. The maximum depth of the graph is set to 20. 910 | # These limits can be reduced via the maxarray, maxdepth limits. 911 | # 912 | #sun.rmi.registry.registryFilter=pattern;pattern 913 | 914 | # 915 | # Array construction of any component type, including subarrays and arrays of 916 | # primitives, are allowed unless the length is greater than the maxarray limit. 917 | # The filter is applied to each array element. 918 | # 919 | # The built-in filter allows subclasses of allowed classes and 920 | # can approximately be represented as the pattern: 921 | # 922 | #sun.rmi.registry.registryFilter=\ 923 | # maxarray=1000000;\ 924 | # maxdepth=20;\ 925 | # java.lang.String;\ 926 | # java.lang.Number;\ 927 | # java.lang.reflect.Proxy;\ 928 | # java.rmi.Remote;\ 929 | # sun.rmi.server.UnicastRef;\ 930 | # sun.rmi.server.RMIClientSocketFactory;\ 931 | # sun.rmi.server.RMIServerSocketFactory;\ 932 | # java.rmi.activation.ActivationID;\ 933 | # java.rmi.server.UID 934 | # 935 | # RMI Distributed Garbage Collector (DGC) Serial Filter 936 | # 937 | # The filter pattern uses the same format as jdk.serialFilter. 938 | # This filter can override the builtin filter if additional types need to be 939 | # allowed or rejected from the RMI DGC. 940 | # 941 | # The builtin DGC filter can approximately be represented as the filter pattern: 942 | # 943 | #sun.rmi.transport.dgcFilter=\ 944 | # java.rmi.server.ObjID;\ 945 | # java.rmi.server.UID;\ 946 | # java.rmi.dgc.VMID;\ 947 | # java.rmi.dgc.Lease;\ 948 | # maxdepth=5;maxarray=10000 949 | 950 | # CORBA ORBIorTypeCheckRegistryFilter 951 | # Type check enhancement for ORB::string_to_object processing 952 | # 953 | # An IOR type check filter, if configured, is used by an ORB during 954 | # an ORB::string_to_object invocation to check the veracity of the type encoded 955 | # in the ior string. 956 | # 957 | # The filter pattern consists of a semi-colon separated list of class names. 958 | # The configured list contains the binary class names of the IDL interface types 959 | # corresponding to the IDL stub class to be instantiated. 960 | # As such, a filter specifies a list of IDL stub classes that will be 961 | # allowed by an ORB when an ORB::string_to_object is invoked. 962 | # It is used to specify a white list configuration of acceptable 963 | # IDL stub types which may be contained in a stringified IOR 964 | # parameter passed as input to an ORB::string_to_object method. 965 | # 966 | # Note: This property is currently used by the JDK Reference implementation. 967 | # It is not guaranteed to be examined and used by other implementations. 968 | # 969 | #com.sun.CORBA.ORBIorTypeCheckRegistryFilter=binary_class_name;binary_class_name 970 | 971 | # 972 | # JCEKS Encrypted Key Serial Filter 973 | # 974 | # This filter, if configured, is used by the JCEKS KeyStore during the 975 | # deserialization of the encrypted Key object stored inside a key entry. 976 | # If not configured or the filter result is UNDECIDED (i.e. none of the patterns 977 | # matches), the filter configured by jdk.serialFilter will be consulted. 978 | # 979 | # If the system property jceks.key.serialFilter is also specified, it supersedes 980 | # the security property value defined here. 981 | # 982 | # The filter pattern uses the same format as jdk.serialFilter. The default 983 | # pattern allows java.lang.Enum, java.security.KeyRep, java.security.KeyRep$Type, 984 | # and javax.crypto.spec.SecretKeySpec and rejects all the others. 985 | jceks.key.serialFilter = java.lang.Enum;java.security.KeyRep;\ 986 | java.security.KeyRep$Type;javax.crypto.spec.SecretKeySpec;!* 987 | 988 | # 989 | # Policies for distrusting Certificate Authorities (CAs). 990 | # 991 | # This is a comma separated value of one or more case-sensitive strings, each 992 | # of which represents a policy for determining if a CA should be distrusted. 993 | # The supported values are: 994 | # 995 | # 996 | # SYMANTEC_TLS : Distrust TLS Server certificates anchored by a Symantec 997 | # root CA and issued after April 16, 2019 unless issued by one of the 998 | # following subordinate CAs which have a later distrust date: 999 | # 1. Apple IST CA 2 - G1, SHA-256 fingerprint: 1000 | # AC2B922ECFD5E01711772FEA8ED372DE9D1E2245FCE3F57A9CDBEC77296A424B 1001 | # Distrust after December 31, 2019. 1002 | # 2. Apple IST CA 8 - G1, SHA-256 fingerprint: 1003 | # A4FE7C7F15155F3F0AEF7AAA83CF6E06DEB97CA3F909DF920AC1490882D488ED 1004 | # Distrust after December 31, 2019. 1005 | # Leading and trailing whitespace surrounding each value are ignored. 1006 | # Unknown values are ignored. If the property is commented out or set to the 1007 | # empty String, no policies are enforced. 1008 | # 1009 | # Note: This property is currently used by the JDK Reference implementation. 1010 | # It is not guaranteed to be supported by other SE implementations. Also, this 1011 | # property does not override other security properties which can restrict 1012 | # certificates such as jdk.tls.disabledAlgorithms or 1013 | # jdk.certpath.disabledAlgorithms; those restrictions are still enforced even 1014 | # if this property is not enabled. 1015 | # 1016 | jdk.security.caDistrustPolicies=SYMANTEC_TLS 1017 | -------------------------------------------------------------------------------- /dev-resources/java.security.jdk11-fips: -------------------------------------------------------------------------------- 1 | # 2 | # This is the "master security properties file". 3 | # 4 | # An alternate java.security properties file may be specified 5 | # from the command line via the system property 6 | # 7 | # -Djava.security.properties= 8 | # 9 | # This properties file appends to the master security properties file. 10 | # If both properties files specify values for the same key, the value 11 | # from the command-line properties file is selected, as it is the last 12 | # one loaded. 13 | # 14 | # Also, if you specify 15 | # 16 | # -Djava.security.properties== (2 equals), 17 | # 18 | # then that properties file completely overrides the master security 19 | # properties file. 20 | # 21 | # To disable the ability to specify an additional properties file from 22 | # the command line, set the key security.overridePropertiesFile 23 | # to false in the master security properties file. It is set to true 24 | # by default. 25 | 26 | # In this file, various security properties are set for use by 27 | # java.security classes. This is where users can statically register 28 | # Cryptography Package Providers ("providers" for short). The term 29 | # "provider" refers to a package or set of packages that supply a 30 | # concrete implementation of a subset of the cryptography aspects of 31 | # the Java Security API. A provider may, for example, implement one or 32 | # more digital signature algorithms or message digest algorithms. 33 | # 34 | # Each provider must implement a subclass of the Provider class. 35 | # To register a provider in this master security properties file, 36 | # specify the provider and priority in the format 37 | # 38 | # security.provider.= 39 | # 40 | # This declares a provider, and specifies its preference 41 | # order n. The preference order is the order in which providers are 42 | # searched for requested algorithms (when no specific provider is 43 | # requested). The order is 1-based; 1 is the most preferred, followed 44 | # by 2, and so on. 45 | # 46 | # must specify the name of the Provider as passed to its super 47 | # class java.security.Provider constructor. This is for providers loaded 48 | # through the ServiceLoader mechanism. 49 | # 50 | # must specify the subclass of the Provider class whose 51 | # constructor sets the values of various properties that are required 52 | # for the Java Security API to look up the algorithms or other 53 | # facilities implemented by the provider. This is for providers loaded 54 | # through classpath. 55 | # 56 | # Note: Providers can be dynamically registered instead by calls to 57 | # either the addProvider or insertProviderAt method in the Security 58 | # class. 59 | 60 | # 61 | # List of providers and their preference orders (see above): 62 | # 63 | security.provider.1=org.bouncycastle.jcajce.provider.BouncyCastleFipsProvider 64 | security.provider.2=org.bouncycastle.jsse.provider.BouncyCastleJsseProvider fips:org.bouncycastle.jcajce.provider.BouncyCastleFipsProvider 65 | security.provider.3=SUN 66 | security.provider.4=SunRsaSign 67 | #security.provider.5=SunEC 68 | #security.provider.6=SunJSSE 69 | #security.provider.7=SunJCE 70 | #security.provider.8=SunJGSS 71 | #security.provider.9=SunSASL 72 | #security.provider.10=XMLDSig 73 | #security.provider.11=SunPCSC 74 | #security.provider.12=JdkLDAP 75 | #security.provider.13=JdkSASL 76 | #security.provider.14=SunPKCS11 77 | 78 | # 79 | # A list of preferred providers for specific algorithms. These providers will 80 | # be searched for matching algorithms before the list of registered providers. 81 | # Entries containing errors (parsing, etc) will be ignored. Use the 82 | # -Djava.security.debug=jca property to debug these errors. 83 | # 84 | # The property is a comma-separated list of serviceType.algorithm:provider 85 | # entries. The serviceType (example: "MessageDigest") is optional, and if 86 | # not specified, the algorithm applies to all service types that support it. 87 | # The algorithm is the standard algorithm name or transformation. 88 | # Transformations can be specified in their full standard name 89 | # (ex: AES/CBC/PKCS5Padding), or as partial matches (ex: AES, AES/CBC). 90 | # The provider is the name of the provider. Any provider that does not 91 | # also appear in the registered list will be ignored. 92 | # 93 | # There is a special serviceType for this property only to group a set of 94 | # algorithms together. The type is "Group" and is followed by an algorithm 95 | # keyword. Groups are to simplify and lessen the entries on the property 96 | # line. Current groups are: 97 | # Group.SHA2 = SHA-224, SHA-256, SHA-384, SHA-512, SHA-512/224, SHA-512/256 98 | # Group.HmacSHA2 = HmacSHA224, HmacSHA256, HmacSHA384, HmacSHA512 99 | # Group.SHA2RSA = SHA224withRSA, SHA256withRSA, SHA384withRSA, SHA512withRSA 100 | # Group.SHA2DSA = SHA224withDSA, SHA256withDSA, SHA384withDSA, SHA512withDSA 101 | # Group.SHA2ECDSA = SHA224withECDSA, SHA256withECDSA, SHA384withECDSA, \ 102 | # SHA512withECDSA 103 | # Group.SHA3 = SHA3-224, SHA3-256, SHA3-384, SHA3-512 104 | # Group.HmacSHA3 = HmacSHA3-224, HmacSHA3-256, HmacSHA3-384, HmacSHA3-512 105 | # 106 | # Example: 107 | # jdk.security.provider.preferred=AES/GCM/NoPadding:SunJCE, \ 108 | # MessageDigest.SHA-256:SUN, Group.HmacSHA2:SunJCE 109 | # 110 | #jdk.security.provider.preferred= 111 | 112 | 113 | # 114 | # Sun Provider SecureRandom seed source. 115 | # 116 | # Select the primary source of seed data for the "NativePRNG", "SHA1PRNG" 117 | # and "DRBG" SecureRandom implementations in the "Sun" provider. 118 | # (Other SecureRandom implementations might also use this property.) 119 | # 120 | # On Unix-like systems (for example, Solaris/Linux/MacOS), the 121 | # "NativePRNG", "SHA1PRNG" and "DRBG" implementations obtains seed data from 122 | # special device files such as file:/dev/random. 123 | # 124 | # On Windows systems, specifying the URLs "file:/dev/random" or 125 | # "file:/dev/urandom" will enable the native Microsoft CryptoAPI seeding 126 | # mechanism for SHA1PRNG and DRBG. 127 | # 128 | # By default, an attempt is made to use the entropy gathering device 129 | # specified by the "securerandom.source" Security property. If an 130 | # exception occurs while accessing the specified URL: 131 | # 132 | # NativePRNG: 133 | # a default value of /dev/random will be used. If neither 134 | # are available, the implementation will be disabled. 135 | # "file" is the only currently supported protocol type. 136 | # 137 | # SHA1PRNG and DRBG: 138 | # the traditional system/thread activity algorithm will be used. 139 | # 140 | # The entropy gathering device can also be specified with the System 141 | # property "java.security.egd". For example: 142 | # 143 | # % java -Djava.security.egd=file:/dev/random MainClass 144 | # 145 | # Specifying this System property will override the 146 | # "securerandom.source" Security property. 147 | # 148 | # In addition, if "file:/dev/random" or "file:/dev/urandom" is 149 | # specified, the "NativePRNG" implementation will be more preferred than 150 | # DRBG and SHA1PRNG in the Sun provider. 151 | # 152 | securerandom.source=file:/dev/random 153 | 154 | # 155 | # A list of known strong SecureRandom implementations. 156 | # 157 | # To help guide applications in selecting a suitable strong 158 | # java.security.SecureRandom implementation, Java distributions should 159 | # indicate a list of known strong implementations using the property. 160 | # 161 | # This is a comma-separated list of algorithm and/or algorithm:provider 162 | # entries. 163 | # 164 | securerandom.strongAlgorithms=NativePRNGBlocking:SUN,DRBG:SUN 165 | 166 | # 167 | # Sun provider DRBG configuration and default instantiation request. 168 | # 169 | # NIST SP 800-90Ar1 lists several DRBG mechanisms. Each can be configured 170 | # with a DRBG algorithm name, and can be instantiated with a security strength, 171 | # prediction resistance support, etc. This property defines the configuration 172 | # and the default instantiation request of "DRBG" SecureRandom implementations 173 | # in the SUN provider. (Other DRBG implementations can also use this property.) 174 | # Applications can request different instantiation parameters like security 175 | # strength, capability, personalization string using one of the 176 | # getInstance(...,SecureRandomParameters,...) methods with a 177 | # DrbgParameters.Instantiation argument, but other settings such as the 178 | # mechanism and DRBG algorithm names are not currently configurable by any API. 179 | # 180 | # Please note that the SUN implementation of DRBG always supports reseeding. 181 | # 182 | # The value of this property is a comma-separated list of all configurable 183 | # aspects. The aspects can appear in any order but the same aspect can only 184 | # appear at most once. Its BNF-style definition is: 185 | # 186 | # Value: 187 | # aspect { "," aspect } 188 | # 189 | # aspect: 190 | # mech_name | algorithm_name | strength | capability | df 191 | # 192 | # // The DRBG mechanism to use. Default "Hash_DRBG" 193 | # mech_name: 194 | # "Hash_DRBG" | "HMAC_DRBG" | "CTR_DRBG" 195 | # 196 | # // The DRBG algorithm name. The "SHA-***" names are for Hash_DRBG and 197 | # // HMAC_DRBG, default "SHA-256". The "AES-***" names are for CTR_DRBG, 198 | # // default "AES-128" when using the limited cryptographic or "AES-256" 199 | # // when using the unlimited. 200 | # algorithm_name: 201 | # "SHA-224" | "SHA-512/224" | "SHA-256" | 202 | # "SHA-512/256" | "SHA-384" | "SHA-512" | 203 | # "AES-128" | "AES-192" | "AES-256" 204 | # 205 | # // Security strength requested. Default "128" 206 | # strength: 207 | # "112" | "128" | "192" | "256" 208 | # 209 | # // Prediction resistance and reseeding request. Default "none" 210 | # // "pr_and_reseed" - Both prediction resistance and reseeding 211 | # // support requested 212 | # // "reseed_only" - Only reseeding support requested 213 | # // "none" - Neither prediction resistance not reseeding 214 | # // support requested 215 | # pr: 216 | # "pr_and_reseed" | "reseed_only" | "none" 217 | # 218 | # // Whether a derivation function should be used. only applicable 219 | # // to CTR_DRBG. Default "use_df" 220 | # df: 221 | # "use_df" | "no_df" 222 | # 223 | # Examples, 224 | # securerandom.drbg.config=Hash_DRBG,SHA-224,112,none 225 | # securerandom.drbg.config=CTR_DRBG,AES-256,192,pr_and_reseed,use_df 226 | # 227 | # The default value is an empty string, which is equivalent to 228 | # securerandom.drbg.config=Hash_DRBG,SHA-256,128,none 229 | # 230 | securerandom.drbg.config= 231 | 232 | # 233 | # Class to instantiate as the javax.security.auth.login.Configuration 234 | # provider. 235 | # 236 | login.configuration.provider=sun.security.provider.ConfigFile 237 | 238 | # 239 | # Default login configuration file 240 | # 241 | #login.config.url.1=file:${user.home}/.java.login.config 242 | 243 | # 244 | # Class to instantiate as the system Policy. This is the name of the class 245 | # that will be used as the Policy object. The system class loader is used to 246 | # locate this class. 247 | # 248 | policy.provider=sun.security.provider.PolicyFile 249 | 250 | # The default is to have a single system-wide policy file, 251 | # and a policy file in the user's home directory. 252 | # 253 | policy.url.1=file:${java.home}/conf/security/java.policy 254 | policy.url.2=file:${user.home}/.java.policy 255 | 256 | # whether or not we expand properties in the policy file 257 | # if this is set to false, properties (${...}) will not be expanded in policy 258 | # files. 259 | # 260 | policy.expandProperties=true 261 | 262 | # whether or not we allow an extra policy to be passed on the command line 263 | # with -Djava.security.policy=somefile. Comment out this line to disable 264 | # this feature. 265 | # 266 | policy.allowSystemProperty=true 267 | 268 | # whether or not we look into the IdentityScope for trusted Identities 269 | # when encountering a 1.1 signed JAR file. If the identity is found 270 | # and is trusted, we grant it AllPermission. Note: the default policy 271 | # provider (sun.security.provider.PolicyFile) does not support this property. 272 | # 273 | policy.ignoreIdentityScope=false 274 | 275 | # 276 | # Default keystore type. 277 | # 278 | keystore.type=pkcs12 279 | 280 | # 281 | # Controls compatibility mode for JKS and PKCS12 keystore types. 282 | # 283 | # When set to 'true', both JKS and PKCS12 keystore types support loading 284 | # keystore files in either JKS or PKCS12 format. When set to 'false' the 285 | # JKS keystore type supports loading only JKS keystore files and the PKCS12 286 | # keystore type supports loading only PKCS12 keystore files. 287 | # 288 | keystore.type.compat=true 289 | 290 | # 291 | # List of comma-separated packages that start with or equal this string 292 | # will cause a security exception to be thrown when passed to the 293 | # SecurityManager::checkPackageAccess method unless the corresponding 294 | # RuntimePermission("accessClassInPackage."+package) has been granted. 295 | # 296 | package.access=sun.misc.,\ 297 | sun.reflect.,\ 298 | org.GNOME.Accessibility. 299 | 300 | # 301 | # List of comma-separated packages that start with or equal this string 302 | # will cause a security exception to be thrown when passed to the 303 | # SecurityManager::checkPackageDefinition method unless the corresponding 304 | # RuntimePermission("defineClassInPackage."+package) has been granted. 305 | # 306 | # By default, none of the class loaders supplied with the JDK call 307 | # checkPackageDefinition. 308 | # 309 | package.definition=sun.misc.,\ 310 | sun.reflect. 311 | 312 | # 313 | # Determines whether this properties file can be appended to 314 | # or overridden on the command line via -Djava.security.properties 315 | # 316 | security.overridePropertiesFile=true 317 | 318 | # 319 | # Determines the default key and trust manager factory algorithms for 320 | # the javax.net.ssl package. 321 | # 322 | ssl.KeyManagerFactory.algorithm=BCFKS 323 | ssl.TrustManagerFactory.algorithm=PKIX 324 | 325 | # 326 | # The Java-level namelookup cache policy for successful lookups: 327 | # 328 | # any negative value: caching forever 329 | # any positive value: the number of seconds to cache an address for 330 | # zero: do not cache 331 | # 332 | # default value is forever (FOREVER). For security reasons, this 333 | # caching is made forever when a security manager is set. When a security 334 | # manager is not set, the default behavior in this implementation 335 | # is to cache for 30 seconds. 336 | # 337 | # NOTE: setting this to anything other than the default value can have 338 | # serious security implications. Do not set it unless 339 | # you are sure you are not exposed to DNS spoofing attack. 340 | # 341 | #networkaddress.cache.ttl=-1 342 | 343 | # The Java-level namelookup cache policy for failed lookups: 344 | # 345 | # any negative value: cache forever 346 | # any positive value: the number of seconds to cache negative lookup results 347 | # zero: do not cache 348 | # 349 | # In some Microsoft Windows networking environments that employ 350 | # the WINS name service in addition to DNS, name service lookups 351 | # that fail may take a noticeably long time to return (approx. 5 seconds). 352 | # For this reason the default caching policy is to maintain these 353 | # results for 10 seconds. 354 | # 355 | networkaddress.cache.negative.ttl=10 356 | 357 | # 358 | # Properties to configure OCSP for certificate revocation checking 359 | # 360 | 361 | # Enable OCSP 362 | # 363 | # By default, OCSP is not used for certificate revocation checking. 364 | # This property enables the use of OCSP when set to the value "true". 365 | # 366 | # NOTE: SocketPermission is required to connect to an OCSP responder. 367 | # 368 | # Example, 369 | # ocsp.enable=true 370 | 371 | # 372 | # Location of the OCSP responder 373 | # 374 | # By default, the location of the OCSP responder is determined implicitly 375 | # from the certificate being validated. This property explicitly specifies 376 | # the location of the OCSP responder. The property is used when the 377 | # Authority Information Access extension (defined in RFC 5280) is absent 378 | # from the certificate or when it requires overriding. 379 | # 380 | # Example, 381 | # ocsp.responderURL=http://ocsp.example.net:80 382 | 383 | # 384 | # Subject name of the OCSP responder's certificate 385 | # 386 | # By default, the certificate of the OCSP responder is that of the issuer 387 | # of the certificate being validated. This property identifies the certificate 388 | # of the OCSP responder when the default does not apply. Its value is a string 389 | # distinguished name (defined in RFC 2253) which identifies a certificate in 390 | # the set of certificates supplied during cert path validation. In cases where 391 | # the subject name alone is not sufficient to uniquely identify the certificate 392 | # then both the "ocsp.responderCertIssuerName" and 393 | # "ocsp.responderCertSerialNumber" properties must be used instead. When this 394 | # property is set then those two properties are ignored. 395 | # 396 | # Example, 397 | # ocsp.responderCertSubjectName=CN=OCSP Responder, O=XYZ Corp 398 | 399 | # 400 | # Issuer name of the OCSP responder's certificate 401 | # 402 | # By default, the certificate of the OCSP responder is that of the issuer 403 | # of the certificate being validated. This property identifies the certificate 404 | # of the OCSP responder when the default does not apply. Its value is a string 405 | # distinguished name (defined in RFC 2253) which identifies a certificate in 406 | # the set of certificates supplied during cert path validation. When this 407 | # property is set then the "ocsp.responderCertSerialNumber" property must also 408 | # be set. When the "ocsp.responderCertSubjectName" property is set then this 409 | # property is ignored. 410 | # 411 | # Example, 412 | # ocsp.responderCertIssuerName=CN=Enterprise CA, O=XYZ Corp 413 | 414 | # 415 | # Serial number of the OCSP responder's certificate 416 | # 417 | # By default, the certificate of the OCSP responder is that of the issuer 418 | # of the certificate being validated. This property identifies the certificate 419 | # of the OCSP responder when the default does not apply. Its value is a string 420 | # of hexadecimal digits (colon or space separators may be present) which 421 | # identifies a certificate in the set of certificates supplied during cert path 422 | # validation. When this property is set then the "ocsp.responderCertIssuerName" 423 | # property must also be set. When the "ocsp.responderCertSubjectName" property 424 | # is set then this property is ignored. 425 | # 426 | # Example, 427 | # ocsp.responderCertSerialNumber=2A:FF:00 428 | 429 | # 430 | # Policy for failed Kerberos KDC lookups: 431 | # 432 | # When a KDC is unavailable (network error, service failure, etc), it is 433 | # put inside a blacklist and accessed less often for future requests. The 434 | # value (case-insensitive) for this policy can be: 435 | # 436 | # tryLast 437 | # KDCs in the blacklist are always tried after those not on the list. 438 | # 439 | # tryLess[:max_retries,timeout] 440 | # KDCs in the blacklist are still tried by their order in the configuration, 441 | # but with smaller max_retries and timeout values. max_retries and timeout 442 | # are optional numerical parameters (default 1 and 5000, which means once 443 | # and 5 seconds). Please notes that if any of the values defined here is 444 | # more than what is defined in krb5.conf, it will be ignored. 445 | # 446 | # Whenever a KDC is detected as available, it is removed from the blacklist. 447 | # The blacklist is reset when krb5.conf is reloaded. You can add 448 | # refreshKrb5Config=true to a JAAS configuration file so that krb5.conf is 449 | # reloaded whenever a JAAS authentication is attempted. 450 | # 451 | # Example, 452 | # krb5.kdc.bad.policy = tryLast 453 | # krb5.kdc.bad.policy = tryLess:2,2000 454 | # 455 | krb5.kdc.bad.policy = tryLast 456 | 457 | # 458 | # Algorithm restrictions for certification path (CertPath) processing 459 | # 460 | # In some environments, certain algorithms or key lengths may be undesirable 461 | # for certification path building and validation. For example, "MD2" is 462 | # generally no longer considered to be a secure hash algorithm. This section 463 | # describes the mechanism for disabling algorithms based on algorithm name 464 | # and/or key length. This includes algorithms used in certificates, as well 465 | # as revocation information such as CRLs and signed OCSP Responses. 466 | # The syntax of the disabled algorithm string is described as follows: 467 | # DisabledAlgorithms: 468 | # " DisabledAlgorithm { , DisabledAlgorithm } " 469 | # 470 | # DisabledAlgorithm: 471 | # AlgorithmName [Constraint] { '&' Constraint } 472 | # 473 | # AlgorithmName: 474 | # (see below) 475 | # 476 | # Constraint: 477 | # KeySizeConstraint | CAConstraint | DenyAfterConstraint | 478 | # UsageConstraint 479 | # 480 | # KeySizeConstraint: 481 | # keySize Operator KeyLength 482 | # 483 | # Operator: 484 | # <= | < | == | != | >= | > 485 | # 486 | # KeyLength: 487 | # Integer value of the algorithm's key length in bits 488 | # 489 | # CAConstraint: 490 | # jdkCA 491 | # 492 | # DenyAfterConstraint: 493 | # denyAfter YYYY-MM-DD 494 | # 495 | # UsageConstraint: 496 | # usage [TLSServer] [TLSClient] [SignedJAR] 497 | # 498 | # The "AlgorithmName" is the standard algorithm name of the disabled 499 | # algorithm. See "Java Cryptography Architecture Standard Algorithm Name 500 | # Documentation" for information about Standard Algorithm Names. Matching 501 | # is performed using a case-insensitive sub-element matching rule. (For 502 | # example, in "SHA1withECDSA" the sub-elements are "SHA1" for hashing and 503 | # "ECDSA" for signatures.) If the assertion "AlgorithmName" is a 504 | # sub-element of the certificate algorithm name, the algorithm will be 505 | # rejected during certification path building and validation. For example, 506 | # the assertion algorithm name "DSA" will disable all certificate algorithms 507 | # that rely on DSA, such as NONEwithDSA, SHA1withDSA. However, the assertion 508 | # will not disable algorithms related to "ECDSA". 509 | # 510 | # A "Constraint" defines restrictions on the keys and/or certificates for 511 | # a specified AlgorithmName: 512 | # 513 | # KeySizeConstraint: 514 | # keySize Operator KeyLength 515 | # The constraint requires a key of a valid size range if the 516 | # "AlgorithmName" is of a key algorithm. The "KeyLength" indicates 517 | # the key size specified in number of bits. For example, 518 | # "RSA keySize <= 1024" indicates that any RSA key with key size less 519 | # than or equal to 1024 bits should be disabled, and 520 | # "RSA keySize < 1024, RSA keySize > 2048" indicates that any RSA key 521 | # with key size less than 1024 or greater than 2048 should be disabled. 522 | # This constraint is only used on algorithms that have a key size. 523 | # 524 | # CAConstraint: 525 | # jdkCA 526 | # This constraint prohibits the specified algorithm only if the 527 | # algorithm is used in a certificate chain that terminates at a marked 528 | # trust anchor in the lib/security/cacerts keystore. If the jdkCA 529 | # constraint is not set, then all chains using the specified algorithm 530 | # are restricted. jdkCA may only be used once in a DisabledAlgorithm 531 | # expression. 532 | # Example: To apply this constraint to SHA-1 certificates, include 533 | # the following: "SHA1 jdkCA" 534 | # 535 | # DenyAfterConstraint: 536 | # denyAfter YYYY-MM-DD 537 | # This constraint prohibits a certificate with the specified algorithm 538 | # from being used after the date regardless of the certificate's 539 | # validity. JAR files that are signed and timestamped before the 540 | # constraint date with certificates containing the disabled algorithm 541 | # will not be restricted. The date is processed in the UTC timezone. 542 | # This constraint can only be used once in a DisabledAlgorithm 543 | # expression. 544 | # Example: To deny usage of RSA 2048 bit certificates after Feb 3 2020, 545 | # use the following: "RSA keySize == 2048 & denyAfter 2020-02-03" 546 | # 547 | # UsageConstraint: 548 | # usage [TLSServer] [TLSClient] [SignedJAR] 549 | # This constraint prohibits the specified algorithm for 550 | # a specified usage. This should be used when disabling an algorithm 551 | # for all usages is not practical. 'TLSServer' restricts the algorithm 552 | # in TLS server certificate chains when server authentication is 553 | # performed. 'TLSClient' restricts the algorithm in TLS client 554 | # certificate chains when client authentication is performed. 555 | # 'SignedJAR' constrains use of certificates in signed jar files. 556 | # The usage type follows the keyword and more than one usage type can 557 | # be specified with a whitespace delimiter. 558 | # Example: "SHA1 usage TLSServer TLSClient" 559 | # 560 | # When an algorithm must satisfy more than one constraint, it must be 561 | # delimited by an ampersand '&'. For example, to restrict certificates in a 562 | # chain that terminate at a distribution provided trust anchor and contain 563 | # RSA keys that are less than or equal to 1024 bits, add the following 564 | # constraint: "RSA keySize <= 1024 & jdkCA". 565 | # 566 | # All DisabledAlgorithms expressions are processed in the order defined in the 567 | # property. This requires lower keysize constraints to be specified 568 | # before larger keysize constraints of the same algorithm. For example: 569 | # "RSA keySize < 1024 & jdkCA, RSA keySize < 2048". 570 | # 571 | # Note: The algorithm restrictions do not apply to trust anchors or 572 | # self-signed certificates. 573 | # 574 | # Note: This property is currently used by Oracle's PKIX implementation. It 575 | # is not guaranteed to be examined and used by other implementations. 576 | # 577 | # Example: 578 | # jdk.certpath.disabledAlgorithms=MD2, DSA, RSA keySize < 2048 579 | # 580 | # 581 | jdk.certpath.disabledAlgorithms=MD2, MD5, SHA1 jdkCA & usage TLSServer, \ 582 | RSA keySize < 1024, DSA keySize < 1024, EC keySize < 224 583 | 584 | # 585 | # Algorithm restrictions for signed JAR files 586 | # 587 | # In some environments, certain algorithms or key lengths may be undesirable 588 | # for signed JAR validation. For example, "MD2" is generally no longer 589 | # considered to be a secure hash algorithm. This section describes the 590 | # mechanism for disabling algorithms based on algorithm name and/or key length. 591 | # JARs signed with any of the disabled algorithms or key sizes will be treated 592 | # as unsigned. 593 | # 594 | # The syntax of the disabled algorithm string is described as follows: 595 | # DisabledAlgorithms: 596 | # " DisabledAlgorithm { , DisabledAlgorithm } " 597 | # 598 | # DisabledAlgorithm: 599 | # AlgorithmName [Constraint] { '&' Constraint } 600 | # 601 | # AlgorithmName: 602 | # (see below) 603 | # 604 | # Constraint: 605 | # KeySizeConstraint | DenyAfterConstraint 606 | # 607 | # KeySizeConstraint: 608 | # keySize Operator KeyLength 609 | # 610 | # DenyAfterConstraint: 611 | # denyAfter YYYY-MM-DD 612 | # 613 | # Operator: 614 | # <= | < | == | != | >= | > 615 | # 616 | # KeyLength: 617 | # Integer value of the algorithm's key length in bits 618 | # 619 | # Note: This property is currently used by the JDK Reference 620 | # implementation. It is not guaranteed to be examined and used by other 621 | # implementations. 622 | # 623 | # See "jdk.certpath.disabledAlgorithms" for syntax descriptions. 624 | # 625 | jdk.jar.disabledAlgorithms=MD2, MD5, RSA keySize < 1024, \ 626 | DSA keySize < 1024 627 | 628 | # 629 | # Algorithm restrictions for Secure Socket Layer/Transport Layer Security 630 | # (SSL/TLS/DTLS) processing 631 | # 632 | # In some environments, certain algorithms or key lengths may be undesirable 633 | # when using SSL/TLS/DTLS. This section describes the mechanism for disabling 634 | # algorithms during SSL/TLS/DTLS security parameters negotiation, including 635 | # protocol version negotiation, cipher suites selection, peer authentication 636 | # and key exchange mechanisms. 637 | # 638 | # Disabled algorithms will not be negotiated for SSL/TLS connections, even 639 | # if they are enabled explicitly in an application. 640 | # 641 | # For PKI-based peer authentication and key exchange mechanisms, this list 642 | # of disabled algorithms will also be checked during certification path 643 | # building and validation, including algorithms used in certificates, as 644 | # well as revocation information such as CRLs and signed OCSP Responses. 645 | # This is in addition to the jdk.certpath.disabledAlgorithms property above. 646 | # 647 | # See the specification of "jdk.certpath.disabledAlgorithms" for the 648 | # syntax of the disabled algorithm string. 649 | # 650 | # Note: The algorithm restrictions do not apply to trust anchors or 651 | # self-signed certificates. 652 | # 653 | # Note: This property is currently used by the JDK Reference implementation. 654 | # It is not guaranteed to be examined and used by other implementations. 655 | # 656 | # Example: 657 | # jdk.tls.disabledAlgorithms=MD5, SSLv3, DSA, RSA keySize < 2048 658 | jdk.tls.disabledAlgorithms=SSLv3, RC4, DES, MD5withRSA, DH keySize < 1024, \ 659 | EC keySize < 224, 3DES_EDE_CBC, anon, NULL 660 | 661 | # 662 | # Legacy algorithms for Secure Socket Layer/Transport Layer Security (SSL/TLS) 663 | # processing in JSSE implementation. 664 | # 665 | # In some environments, a certain algorithm may be undesirable but it 666 | # cannot be disabled because of its use in legacy applications. Legacy 667 | # algorithms may still be supported, but applications should not use them 668 | # as the security strength of legacy algorithms are usually not strong enough 669 | # in practice. 670 | # 671 | # During SSL/TLS security parameters negotiation, legacy algorithms will 672 | # not be negotiated unless there are no other candidates. 673 | # 674 | # The syntax of the legacy algorithms string is described as this Java 675 | # BNF-style: 676 | # LegacyAlgorithms: 677 | # " LegacyAlgorithm { , LegacyAlgorithm } " 678 | # 679 | # LegacyAlgorithm: 680 | # AlgorithmName (standard JSSE algorithm name) 681 | # 682 | # See the specification of security property "jdk.certpath.disabledAlgorithms" 683 | # for the syntax and description of the "AlgorithmName" notation. 684 | # 685 | # Per SSL/TLS specifications, cipher suites have the form: 686 | # SSL_KeyExchangeAlg_WITH_CipherAlg_MacAlg 687 | # or 688 | # TLS_KeyExchangeAlg_WITH_CipherAlg_MacAlg 689 | # 690 | # For example, the cipher suite TLS_RSA_WITH_AES_128_CBC_SHA uses RSA as the 691 | # key exchange algorithm, AES_128_CBC (128 bits AES cipher algorithm in CBC 692 | # mode) as the cipher (encryption) algorithm, and SHA-1 as the message digest 693 | # algorithm for HMAC. 694 | # 695 | # The LegacyAlgorithm can be one of the following standard algorithm names: 696 | # 1. JSSE cipher suite name, e.g., TLS_RSA_WITH_AES_128_CBC_SHA 697 | # 2. JSSE key exchange algorithm name, e.g., RSA 698 | # 3. JSSE cipher (encryption) algorithm name, e.g., AES_128_CBC 699 | # 4. JSSE message digest algorithm name, e.g., SHA 700 | # 701 | # See SSL/TLS specifications and "Java Cryptography Architecture Standard 702 | # Algorithm Name Documentation" for information about the algorithm names. 703 | # 704 | # Note: If a legacy algorithm is also restricted through the 705 | # jdk.tls.disabledAlgorithms property or the 706 | # java.security.AlgorithmConstraints API (See 707 | # javax.net.ssl.SSLParameters.setAlgorithmConstraints()), 708 | # then the algorithm is completely disabled and will not be negotiated. 709 | # 710 | # Note: This property is currently used by the JDK Reference implementation. 711 | # It is not guaranteed to be examined and used by other implementations. 712 | # There is no guarantee the property will continue to exist or be of the 713 | # same syntax in future releases. 714 | # 715 | # Example: 716 | # jdk.tls.legacyAlgorithms=DH_anon, DES_CBC, SSL_RSA_WITH_RC4_128_MD5 717 | # 718 | jdk.tls.legacyAlgorithms= \ 719 | K_NULL, C_NULL, M_NULL, \ 720 | DH_anon, ECDH_anon, \ 721 | RC4_128, RC4_40, DES_CBC, DES40_CBC, \ 722 | 3DES_EDE_CBC 723 | 724 | # 725 | # The pre-defined default finite field Diffie-Hellman ephemeral (DHE) 726 | # parameters for Transport Layer Security (SSL/TLS/DTLS) processing. 727 | # 728 | # In traditional SSL/TLS/DTLS connections where finite field DHE parameters 729 | # negotiation mechanism is not used, the server offers the client group 730 | # parameters, base generator g and prime modulus p, for DHE key exchange. 731 | # It is recommended to use dynamic group parameters. This property defines 732 | # a mechanism that allows you to specify custom group parameters. 733 | # 734 | # The syntax of this property string is described as this Java BNF-style: 735 | # DefaultDHEParameters: 736 | # DefinedDHEParameters { , DefinedDHEParameters } 737 | # 738 | # DefinedDHEParameters: 739 | # "{" DHEPrimeModulus , DHEBaseGenerator "}" 740 | # 741 | # DHEPrimeModulus: 742 | # HexadecimalDigits 743 | # 744 | # DHEBaseGenerator: 745 | # HexadecimalDigits 746 | # 747 | # HexadecimalDigits: 748 | # HexadecimalDigit { HexadecimalDigit } 749 | # 750 | # HexadecimalDigit: one of 751 | # 0 1 2 3 4 5 6 7 8 9 A B C D E F a b c d e f 752 | # 753 | # Whitespace characters are ignored. 754 | # 755 | # The "DefinedDHEParameters" defines the custom group parameters, prime 756 | # modulus p and base generator g, for a particular size of prime modulus p. 757 | # The "DHEPrimeModulus" defines the hexadecimal prime modulus p, and the 758 | # "DHEBaseGenerator" defines the hexadecimal base generator g of a group 759 | # parameter. It is recommended to use safe primes for the custom group 760 | # parameters. 761 | # 762 | # If this property is not defined or the value is empty, the underlying JSSE 763 | # provider's default group parameter is used for each connection. 764 | # 765 | # If the property value does not follow the grammar, or a particular group 766 | # parameter is not valid, the connection will fall back and use the 767 | # underlying JSSE provider's default group parameter. 768 | # 769 | # Note: This property is currently used by OpenJDK's JSSE implementation. It 770 | # is not guaranteed to be examined and used by other implementations. 771 | # 772 | # Example: 773 | # jdk.tls.server.defaultDHEParameters= 774 | # { \ 775 | # FFFFFFFF FFFFFFFF C90FDAA2 2168C234 C4C6628B 80DC1CD1 \ 776 | # 29024E08 8A67CC74 020BBEA6 3B139B22 514A0879 8E3404DD \ 777 | # EF9519B3 CD3A431B 302B0A6D F25F1437 4FE1356D 6D51C245 \ 778 | # E485B576 625E7EC6 F44C42E9 A637ED6B 0BFF5CB6 F406B7ED \ 779 | # EE386BFB 5A899FA5 AE9F2411 7C4B1FE6 49286651 ECE65381 \ 780 | # FFFFFFFF FFFFFFFF, 2} 781 | 782 | # 783 | # TLS key limits on symmetric cryptographic algorithms 784 | # 785 | # This security property sets limits on algorithms key usage in TLS 1.3. 786 | # When the amount of data encrypted exceeds the algorithm value listed below, 787 | # a KeyUpdate message will trigger a key change. This is for symmetric ciphers 788 | # with TLS 1.3 only. 789 | # 790 | # The syntax for the property is described below: 791 | # KeyLimits: 792 | # " KeyLimit { , KeyLimit } " 793 | # 794 | # WeakKeyLimit: 795 | # AlgorithmName Action Length 796 | # 797 | # AlgorithmName: 798 | # A full algorithm transformation. 799 | # 800 | # Action: 801 | # KeyUpdate 802 | # 803 | # Length: 804 | # The amount of encrypted data in a session before the Action occurs 805 | # This value may be an integer value in bytes, or as a power of two, 2^29. 806 | # 807 | # KeyUpdate: 808 | # The TLS 1.3 KeyUpdate handshake process begins when the Length amount 809 | # is fulfilled. 810 | # 811 | # Note: This property is currently used by OpenJDK's JSSE implementation. It 812 | # is not guaranteed to be examined and used by other implementations. 813 | # 814 | jdk.tls.keyLimits=AES/GCM/NoPadding KeyUpdate 2^37 815 | 816 | # 817 | # Cryptographic Jurisdiction Policy defaults 818 | # 819 | # Import and export control rules on cryptographic software vary from 820 | # country to country. By default, Java provides two different sets of 821 | # cryptographic policy files[1]: 822 | # 823 | # unlimited: These policy files contain no restrictions on cryptographic 824 | # strengths or algorithms 825 | # 826 | # limited: These policy files contain more restricted cryptographic 827 | # strengths 828 | # 829 | # The default setting is determined by the value of the "crypto.policy" 830 | # Security property below. If your country or usage requires the 831 | # traditional restrictive policy, the "limited" Java cryptographic 832 | # policy is still available and may be appropriate for your environment. 833 | # 834 | # If you have restrictions that do not fit either use case mentioned 835 | # above, Java provides the capability to customize these policy files. 836 | # The "crypto.policy" security property points to a subdirectory 837 | # within /conf/security/policy/ which can be customized. 838 | # Please see the /conf/security/policy/README.txt file or consult 839 | # the Java Security Guide/JCA documentation for more information. 840 | # 841 | # YOU ARE ADVISED TO CONSULT YOUR EXPORT/IMPORT CONTROL COUNSEL OR ATTORNEY 842 | # TO DETERMINE THE EXACT REQUIREMENTS. 843 | # 844 | # [1] Please note that the JCE for Java SE, including the JCE framework, 845 | # cryptographic policy files, and standard JCE providers provided with 846 | # the Java SE, have been reviewed and approved for export as mass market 847 | # encryption item by the US Bureau of Industry and Security. 848 | # 849 | # Note: This property is currently used by the JDK Reference implementation. 850 | # It is not guaranteed to be examined and used by other implementations. 851 | # 852 | crypto.policy=unlimited 853 | 854 | # 855 | # The policy for the XML Signature secure validation mode. The mode is 856 | # enabled by setting the property "org.jcp.xml.dsig.secureValidation" to 857 | # true with the javax.xml.crypto.XMLCryptoContext.setProperty() method, 858 | # or by running the code with a SecurityManager. 859 | # 860 | # Policy: 861 | # Constraint {"," Constraint } 862 | # Constraint: 863 | # AlgConstraint | MaxTransformsConstraint | MaxReferencesConstraint | 864 | # ReferenceUriSchemeConstraint | KeySizeConstraint | OtherConstraint 865 | # AlgConstraint 866 | # "disallowAlg" Uri 867 | # MaxTransformsConstraint: 868 | # "maxTransforms" Integer 869 | # MaxReferencesConstraint: 870 | # "maxReferences" Integer 871 | # ReferenceUriSchemeConstraint: 872 | # "disallowReferenceUriSchemes" String { String } 873 | # KeySizeConstraint: 874 | # "minKeySize" KeyAlg Integer 875 | # OtherConstraint: 876 | # "noDuplicateIds" | "noRetrievalMethodLoops" 877 | # 878 | # For AlgConstraint, Uri is the algorithm URI String that is not allowed. 879 | # See the XML Signature Recommendation for more information on algorithm 880 | # URI Identifiers. For KeySizeConstraint, KeyAlg is the standard algorithm 881 | # name of the key type (ex: "RSA"). If the MaxTransformsConstraint, 882 | # MaxReferencesConstraint or KeySizeConstraint (for the same key type) is 883 | # specified more than once, only the last entry is enforced. 884 | # 885 | # Note: This property is currently used by the JDK Reference implementation. It 886 | # is not guaranteed to be examined and used by other implementations. 887 | # 888 | jdk.xml.dsig.secureValidationPolicy=\ 889 | disallowAlg http://www.w3.org/TR/1999/REC-xslt-19991116,\ 890 | disallowAlg http://www.w3.org/2001/04/xmldsig-more#rsa-md5,\ 891 | disallowAlg http://www.w3.org/2001/04/xmldsig-more#hmac-md5,\ 892 | disallowAlg http://www.w3.org/2001/04/xmldsig-more#md5,\ 893 | maxTransforms 5,\ 894 | maxReferences 30,\ 895 | disallowReferenceUriSchemes file http https,\ 896 | minKeySize RSA 1024,\ 897 | minKeySize DSA 1024,\ 898 | minKeySize EC 224,\ 899 | noDuplicateIds,\ 900 | noRetrievalMethodLoops 901 | 902 | # 903 | # Serialization process-wide filter 904 | # 905 | # A filter, if configured, is used by java.io.ObjectInputStream during 906 | # deserialization to check the contents of the stream. 907 | # A filter is configured as a sequence of patterns, each pattern is either 908 | # matched against the name of a class in the stream or defines a limit. 909 | # Patterns are separated by ";" (semicolon). 910 | # Whitespace is significant and is considered part of the pattern. 911 | # 912 | # If the system property jdk.serialFilter is also specified, it supersedes 913 | # the security property value defined here. 914 | # 915 | # If a pattern includes a "=", it sets a limit. 916 | # If a limit appears more than once the last value is used. 917 | # Limits are checked before classes regardless of the order in the 918 | # sequence of patterns. 919 | # If any of the limits are exceeded, the filter status is REJECTED. 920 | # 921 | # maxdepth=value - the maximum depth of a graph 922 | # maxrefs=value - the maximum number of internal references 923 | # maxbytes=value - the maximum number of bytes in the input stream 924 | # maxarray=value - the maximum array length allowed 925 | # 926 | # Other patterns, from left to right, match the class or package name as 927 | # returned from Class.getName. 928 | # If the class is an array type, the class or package to be matched is the 929 | # element type. 930 | # Arrays of any number of dimensions are treated the same as the element type. 931 | # For example, a pattern of "!example.Foo", rejects creation of any instance or 932 | # array of example.Foo. 933 | # 934 | # If the pattern starts with "!", the status is REJECTED if the remaining 935 | # pattern is matched; otherwise the status is ALLOWED if the pattern matches. 936 | # If the pattern contains "/", the non-empty prefix up to the "/" is the 937 | # module name; 938 | # if the module name matches the module name of the class then 939 | # the remaining pattern is matched with the class name. 940 | # If there is no "/", the module name is not compared. 941 | # If the pattern ends with ".**" it matches any class in the package and all 942 | # subpackages. 943 | # If the pattern ends with ".*" it matches any class in the package. 944 | # If the pattern ends with "*", it matches any class with the pattern as a 945 | # prefix. 946 | # If the pattern is equal to the class name, it matches. 947 | # Otherwise, the status is UNDECIDED. 948 | # 949 | #jdk.serialFilter=pattern;pattern 950 | 951 | # 952 | # RMI Registry Serial Filter 953 | # 954 | # The filter pattern uses the same format as jdk.serialFilter. 955 | # This filter can override the builtin filter if additional types need to be 956 | # allowed or rejected from the RMI Registry or to decrease limits but not 957 | # to increase limits. 958 | # If the limits (maxdepth, maxrefs, or maxbytes) are exceeded, the object is rejected. 959 | # 960 | # Each non-array type is allowed or rejected if it matches one of the patterns, 961 | # evaluated from left to right, and is otherwise allowed. Arrays of any 962 | # component type, including subarrays and arrays of primitives, are allowed. 963 | # 964 | # Array construction of any component type, including subarrays and arrays of 965 | # primitives, are allowed unless the length is greater than the maxarray limit. 966 | # The filter is applied to each array element. 967 | # 968 | # Note: This property is currently used by the JDK Reference implementation. 969 | # It is not guaranteed to be examined and used by other implementations. 970 | # 971 | # The built-in filter allows subclasses of allowed classes and 972 | # can approximately be represented as the pattern: 973 | # 974 | #sun.rmi.registry.registryFilter=\ 975 | # maxarray=1000000;\ 976 | # maxdepth=20;\ 977 | # java.lang.String;\ 978 | # java.lang.Number;\ 979 | # java.lang.reflect.Proxy;\ 980 | # java.rmi.Remote;\ 981 | # sun.rmi.server.UnicastRef;\ 982 | # sun.rmi.server.RMIClientSocketFactory;\ 983 | # sun.rmi.server.RMIServerSocketFactory;\ 984 | # java.rmi.activation.ActivationID;\ 985 | # java.rmi.server.UID 986 | # 987 | # RMI Distributed Garbage Collector (DGC) Serial Filter 988 | # 989 | # The filter pattern uses the same format as jdk.serialFilter. 990 | # This filter can override the builtin filter if additional types need to be 991 | # allowed or rejected from the RMI DGC. 992 | # 993 | # Note: This property is currently used by the JDK Reference implementation. 994 | # It is not guaranteed to be examined and used by other implementations. 995 | # 996 | # The builtin DGC filter can approximately be represented as the filter pattern: 997 | # 998 | #sun.rmi.transport.dgcFilter=\ 999 | # java.rmi.server.ObjID;\ 1000 | # java.rmi.server.UID;\ 1001 | # java.rmi.dgc.VMID;\ 1002 | # java.rmi.dgc.Lease;\ 1003 | # maxdepth=5;maxarray=10000 1004 | 1005 | # CORBA ORBIorTypeCheckRegistryFilter 1006 | # Type check enhancement for ORB::string_to_object processing 1007 | # 1008 | # An IOR type check filter, if configured, is used by an ORB during 1009 | # an ORB::string_to_object invocation to check the veracity of the type encoded 1010 | # in the ior string. 1011 | # 1012 | # The filter pattern consists of a semi-colon separated list of class names. 1013 | # The configured list contains the binary class names of the IDL interface types 1014 | # corresponding to the IDL stub class to be instantiated. 1015 | # As such, a filter specifies a list of IDL stub classes that will be 1016 | # allowed by an ORB when an ORB::string_to_object is invoked. 1017 | # It is used to specify a white list configuration of acceptable 1018 | # IDL stub types which may be contained in a stringified IOR 1019 | # parameter passed as input to an ORB::string_to_object method. 1020 | # 1021 | # Note: This property is currently used by the JDK Reference implementation. 1022 | # It is not guaranteed to be examined and used by other implementations. 1023 | # 1024 | #com.sun.CORBA.ORBIorTypeCheckRegistryFilter=binary_class_name;binary_class_name 1025 | 1026 | # 1027 | # JCEKS Encrypted Key Serial Filter 1028 | # 1029 | # This filter, if configured, is used by the JCEKS KeyStore during the 1030 | # deserialization of the encrypted Key object stored inside a key entry. 1031 | # If not configured or the filter result is UNDECIDED (i.e. none of the patterns 1032 | # matches), the filter configured by jdk.serialFilter will be consulted. 1033 | # 1034 | # If the system property jceks.key.serialFilter is also specified, it supersedes 1035 | # the security property value defined here. 1036 | # 1037 | # The filter pattern uses the same format as jdk.serialFilter. The default 1038 | # pattern allows java.lang.Enum, java.security.KeyRep, java.security.KeyRep$Type, 1039 | # and javax.crypto.spec.SecretKeySpec and rejects all the others. 1040 | jceks.key.serialFilter = java.base/java.lang.Enum;java.base/java.security.KeyRep;\ 1041 | java.base/java.security.KeyRep$Type;java.base/javax.crypto.spec.SecretKeySpec;!* 1042 | 1043 | # 1044 | # Enhanced exception message information 1045 | # 1046 | # By default, exception messages should not include potentially sensitive 1047 | # information such as file names, host names, or port numbers. This property 1048 | # accepts one or more comma separated values, each of which represents a 1049 | # category of enhanced exception message information to enable. Values are 1050 | # case-insensitive. Leading and trailing whitespaces, surrounding each value, 1051 | # are ignored. Unknown values are ignored. 1052 | # 1053 | # NOTE: Use caution before setting this property. Setting this property 1054 | # exposes sensitive information in Exceptions, which could, for example, 1055 | # propagate to untrusted code or be emitted in stack traces that are 1056 | # inadvertently disclosed and made accessible over a public network. 1057 | # 1058 | # The categories are: 1059 | # 1060 | # hostInfo - IOExceptions thrown by java.net.Socket and the socket types in the 1061 | # java.nio.channels package will contain enhanced exception 1062 | # message information 1063 | # 1064 | # The property setting in this file can be overridden by a system property of 1065 | # the same name, with the same syntax and possible values. 1066 | # 1067 | #jdk.includeInExceptions=hostInfo 1068 | 1069 | # 1070 | # Policies for distrusting Certificate Authorities (CAs). 1071 | # 1072 | # This is a comma separated value of one or more case-sensitive strings, each 1073 | # of which represents a policy for determining if a CA should be distrusted. 1074 | # The supported values are: 1075 | # 1076 | # SYMANTEC_TLS : Distrust TLS Server certificates anchored by a Symantec 1077 | # root CA and issued after April 16, 2019 unless issued by one of the 1078 | # following subordinate CAs which have a later distrust date: 1079 | # 1. Apple IST CA 2 - G1, SHA-256 fingerprint: 1080 | # AC2B922ECFD5E01711772FEA8ED372DE9D1E2245FCE3F57A9CDBEC77296A424B 1081 | # Distrust after December 31, 2019. 1082 | # 2. Apple IST CA 8 - G1, SHA-256 fingerprint: 1083 | # A4FE7C7F15155F3F0AEF7AAA83CF6E06DEB97CA3F909DF920AC1490882D488ED 1084 | # Distrust after December 31, 2019. 1085 | # 1086 | # Leading and trailing whitespace surrounding each value are ignored. 1087 | # Unknown values are ignored. If the property is commented out or set to the 1088 | # empty String, no policies are enforced. 1089 | # 1090 | # Note: This property is currently used by the JDK Reference implementation. 1091 | # It is not guaranteed to be supported by other SE implementations. Also, this 1092 | # property does not override other security properties which can restrict 1093 | # certificates such as jdk.tls.disabledAlgorithms or 1094 | # jdk.certpath.disabledAlgorithms; those restrictions are still enforced even 1095 | # if this property is not enabled. 1096 | # 1097 | jdk.security.caDistrustPolicies=SYMANTEC_TLS 1098 | 1099 | --------------------------------------------------------------------------------