├── 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 |
--------------------------------------------------------------------------------