You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@nifi.apache.org by ym...@apache.org on 2016/11/15 03:41:53 UTC
[1/3] nifi git commit: NIFI-2654 Enabled encryption coverage for
login-identity-providers.xml.
Repository: nifi
Updated Branches:
refs/heads/master 8ad312516 -> 59fea1cb4
http://git-wip-us.apache.org/repos/asf/nifi/blob/59fea1cb/nifi-toolkit/nifi-toolkit-encrypt-config/src/test/resources/login-identity-providers-populated-multiline.xml
----------------------------------------------------------------------
diff --git a/nifi-toolkit/nifi-toolkit-encrypt-config/src/test/resources/login-identity-providers-populated-multiline.xml b/nifi-toolkit/nifi-toolkit-encrypt-config/src/test/resources/login-identity-providers-populated-multiline.xml
new file mode 100644
index 0000000..b9f64a9
--- /dev/null
+++ b/nifi-toolkit/nifi-toolkit-encrypt-config/src/test/resources/login-identity-providers-populated-multiline.xml
@@ -0,0 +1,111 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+ http://www.apache.org/licenses/LICENSE-2.0
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<!--
+ This file lists the login identity providers to use when running securely. In order
+ to use a specific provider it must be configured here and it's identifier
+ must be specified in the nifi.properties file.
+-->
+<loginIdentityProviders>
+ <!--
+ Identity Provider for users logging in with username/password against an LDAP server.
+
+ 'Authentication Strategy' - How the connection to the LDAP server is authenticated. Possible
+ values are ANONYMOUS, SIMPLE, or START_TLS.
+
+ 'Manager DN' - The DN of the manager that is used to bind to the LDAP server to search for users.
+ 'Manager Password' - The password of the manager that is used to bind to the LDAP server to
+ search for users.
+
+ 'TLS - Keystore' - Path to the Keystore that is used when connecting to LDAP using START_TLS.
+ 'TLS - Keystore Password' - Password for the Keystore that is used when connecting to LDAP
+ using START_TLS.
+ 'TLS - Keystore Type' - Type of the Keystore that is used when connecting to LDAP using
+ START_TLS (i.e. JKS or PKCS12).
+ 'TLS - Truststore' - Path to the Truststore that is used when connecting to LDAP using START_TLS.
+ 'TLS - Truststore Password' - Password for the Truststore that is used when connecting to
+ LDAP using START_TLS.
+ 'TLS - Truststore Type' - Type of the Truststore that is used when connecting to LDAP using
+ START_TLS (i.e. JKS or PKCS12).
+ 'TLS - Client Auth' - Client authentication policy when connecting to LDAP using START_TLS.
+ Possible values are REQUIRED, WANT, NONE.
+ 'TLS - Protocol' - Protocol to use when connecting to LDAP using START_TLS. (i.e. TLS,
+ TLSv1.1, TLSv1.2, etc).
+ 'TLS - Shutdown Gracefully' - Specifies whether the TLS should be shut down gracefully
+ before the target context is closed. Defaults to false.
+
+ 'Referral Strategy' - Strategy for handling referrals. Possible values are FOLLOW, IGNORE, THROW.
+ 'Connect Timeout' - Duration of connect timeout. (i.e. 10 secs).
+ 'Read Timeout' - Duration of read timeout. (i.e. 10 secs).
+
+ 'Url' - Url of the LDAP servier (i.e. ldap://<hostname>:<port>).
+ 'User Search Base' - Base DN for searching for users (i.e. CN=Users,DC=example,DC=com).
+ 'User Search Filter' - Filter for searching for users against the 'User Search Base'.
+ (i.e. sAMAccountName={0}). The user specified name is inserted into '{0}'.
+
+ 'Authentication Expiration' - The duration of how long the user authentication is valid
+ for. If the user never logs out, they will be required to log back in following
+ this duration.
+ -->
+ <provider>
+ <identifier>ldap-provider</identifier>
+ <class>org.apache.nifi.ldap.LdapProvider</class>
+ <property name="Authentication Strategy">START_TLS</property>
+
+ <property name="Manager DN"></property>
+ <property name="Manager Password">
+ thisIsABadPassword
+ </property>
+
+ <property name="TLS - Keystore"></property>
+ <property
+ name="TLS - Keystore Password">thisIsABadPassword
+ </property>
+ <property name="TLS - Keystore Type"></property>
+ <property name="TLS - Truststore"></property>
+ <property name=
+ "TLS - Truststore Password">
+ thisIsABadPassword</property>
+ <property name="TLS - Truststore Type"></property>
+ <property name="TLS - Client Auth"></property>
+ <property name="TLS - Protocol"></property>
+ <property name="TLS - Shutdown Gracefully"></property>
+
+ <property name="Referral Strategy">FOLLOW</property>
+ <property name="Connect Timeout">10 secs</property>
+ <property name="Read Timeout">10 secs</property>
+
+ <property name="Url"></property>
+ <property name="User Search Base"></property>
+ <property name="User Search Filter"></property>
+
+ <property name="Authentication Expiration">12 hours</property>
+ </provider>
+
+ <!--
+ Identity Provider for users logging in with username/password against a Kerberos KDC server.
+
+ 'Default Realm' - Default realm to provide when user enters incomplete user principal (i.e. NIFI.APACHE.ORG).
+ 'Authentication Expiration' - The duration of how long the user authentication is valid for. If the user never logs out, they will be required to log back in following this duration.
+ -->
+ <!-- To enable the kerberos-provider remove 2 lines. This is 1 of 2.
+ <provider>
+ <identifier>kerberos-provider</identifier>
+ <class>org.apache.nifi.kerberos.KerberosProvider</class>
+ <property name="Default Realm">NIFI.APACHE.ORG</property>
+ <property name="Authentication Expiration">12 hours</property>
+ </provider>
+ To enable the kerberos-provider remove 2 lines. This is 2 of 2. -->
+</loginIdentityProviders>
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/nifi/blob/59fea1cb/nifi-toolkit/nifi-toolkit-encrypt-config/src/test/resources/login-identity-providers-populated-multiple-per-line.xml
----------------------------------------------------------------------
diff --git a/nifi-toolkit/nifi-toolkit-encrypt-config/src/test/resources/login-identity-providers-populated-multiple-per-line.xml b/nifi-toolkit/nifi-toolkit-encrypt-config/src/test/resources/login-identity-providers-populated-multiple-per-line.xml
new file mode 100644
index 0000000..2514863
--- /dev/null
+++ b/nifi-toolkit/nifi-toolkit-encrypt-config/src/test/resources/login-identity-providers-populated-multiple-per-line.xml
@@ -0,0 +1,101 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+ http://www.apache.org/licenses/LICENSE-2.0
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<!--
+ This file lists the login identity providers to use when running securely. In order
+ to use a specific provider it must be configured here and it's identifier
+ must be specified in the nifi.properties file.
+-->
+<loginIdentityProviders>
+ <!--
+ Identity Provider for users logging in with username/password against an LDAP server.
+
+ 'Authentication Strategy' - How the connection to the LDAP server is authenticated. Possible
+ values are ANONYMOUS, SIMPLE, or START_TLS.
+
+ 'Manager DN' - The DN of the manager that is used to bind to the LDAP server to search for users.
+ 'Manager Password' - The password of the manager that is used to bind to the LDAP server to
+ search for users.
+
+ 'TLS - Keystore' - Path to the Keystore that is used when connecting to LDAP using START_TLS.
+ 'TLS - Keystore Password' - Password for the Keystore that is used when connecting to LDAP
+ using START_TLS.
+ 'TLS - Keystore Type' - Type of the Keystore that is used when connecting to LDAP using
+ START_TLS (i.e. JKS or PKCS12).
+ 'TLS - Truststore' - Path to the Truststore that is used when connecting to LDAP using START_TLS.
+ 'TLS - Truststore Password' - Password for the Truststore that is used when connecting to
+ LDAP using START_TLS.
+ 'TLS - Truststore Type' - Type of the Truststore that is used when connecting to LDAP using
+ START_TLS (i.e. JKS or PKCS12).
+ 'TLS - Client Auth' - Client authentication policy when connecting to LDAP using START_TLS.
+ Possible values are REQUIRED, WANT, NONE.
+ 'TLS - Protocol' - Protocol to use when connecting to LDAP using START_TLS. (i.e. TLS,
+ TLSv1.1, TLSv1.2, etc).
+ 'TLS - Shutdown Gracefully' - Specifies whether the TLS should be shut down gracefully
+ before the target context is closed. Defaults to false.
+
+ 'Referral Strategy' - Strategy for handling referrals. Possible values are FOLLOW, IGNORE, THROW.
+ 'Connect Timeout' - Duration of connect timeout. (i.e. 10 secs).
+ 'Read Timeout' - Duration of read timeout. (i.e. 10 secs).
+
+ 'Url' - Url of the LDAP servier (i.e. ldap://<hostname>:<port>).
+ 'User Search Base' - Base DN for searching for users (i.e. CN=Users,DC=example,DC=com).
+ 'User Search Filter' - Filter for searching for users against the 'User Search Base'.
+ (i.e. sAMAccountName={0}). The user specified name is inserted into '{0}'.
+
+ 'Authentication Expiration' - The duration of how long the user authentication is valid
+ for. If the user never logs out, they will be required to log back in following
+ this duration.
+ -->
+ <provider>
+ <identifier>ldap-provider</identifier>
+ <class>org.apache.nifi.ldap.LdapProvider</class>
+ <property name="Authentication Strategy">START_TLS</property>
+
+ <property name="Manager DN">someuser</property>
+ <property name="Manager Password" encryption="none">thisIsABadPassword</property><property name="TLS - Keystore"></property><property name="TLS - Keystore Password" encryption="">thisIsABadPassword</property><property name="TLS - Keystore Type"></property>
+ <property name="TLS - Truststore"></property>
+ <property name="TLS - Truststore Password">thisIsABadPassword</property>
+ <property name="TLS - Truststore Type"></property>
+ <property name="TLS - Client Auth"></property>
+ <property name="TLS - Protocol"></property>
+ <property name="TLS - Shutdown Gracefully"></property>
+
+ <property name="Referral Strategy">FOLLOW</property>
+ <property name="Connect Timeout">10 secs</property>
+ <property name="Read Timeout">10 secs</property>
+
+ <property name="Url"></property>
+ <property name="User Search Base"></property>
+ <property name="User Search Filter"></property>
+
+ <property name="Authentication Expiration">12 hours</property>
+ </provider>
+
+ <!--
+ Identity Provider for users logging in with username/password against a Kerberos KDC server.
+
+ 'Default Realm' - Default realm to provide when user enters incomplete user principal (i.e. NIFI.APACHE.ORG).
+ 'Authentication Expiration' - The duration of how long the user authentication is valid for. If the user never logs out, they will be required to log back in following this duration.
+ -->
+ <!-- To enable the kerberos-provider remove 2 lines. This is 1 of 2.
+ <provider>
+ <identifier>kerberos-provider</identifier>
+ <class>org.apache.nifi.kerberos.KerberosProvider</class>
+ <property name="Default Realm">NIFI.APACHE.ORG</property>
+ <property name="Authentication Expiration">12 hours</property>
+ </provider>
+ To enable the kerberos-provider remove 2 lines. This is 2 of 2. -->
+</loginIdentityProviders>
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/nifi/blob/59fea1cb/nifi-toolkit/nifi-toolkit-encrypt-config/src/test/resources/login-identity-providers-populated-single-line.xml
----------------------------------------------------------------------
diff --git a/nifi-toolkit/nifi-toolkit-encrypt-config/src/test/resources/login-identity-providers-populated-single-line.xml b/nifi-toolkit/nifi-toolkit-encrypt-config/src/test/resources/login-identity-providers-populated-single-line.xml
new file mode 100644
index 0000000..d208164
--- /dev/null
+++ b/nifi-toolkit/nifi-toolkit-encrypt-config/src/test/resources/login-identity-providers-populated-single-line.xml
@@ -0,0 +1,101 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+ http://www.apache.org/licenses/LICENSE-2.0
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<!--
+ This file lists the login identity providers to use when running securely. In order
+ to use a specific provider it must be configured here and it's identifier
+ must be specified in the nifi.properties file.
+-->
+<loginIdentityProviders>
+ <!--
+ Identity Provider for users logging in with username/password against an LDAP server.
+
+ 'Authentication Strategy' - How the connection to the LDAP server is authenticated. Possible
+ values are ANONYMOUS, SIMPLE, or START_TLS.
+
+ 'Manager DN' - The DN of the manager that is used to bind to the LDAP server to search for users.
+ 'Manager Password' - The password of the manager that is used to bind to the LDAP server to
+ search for users.
+
+ 'TLS - Keystore' - Path to the Keystore that is used when connecting to LDAP using START_TLS.
+ 'TLS - Keystore Password' - Password for the Keystore that is used when connecting to LDAP
+ using START_TLS.
+ 'TLS - Keystore Type' - Type of the Keystore that is used when connecting to LDAP using
+ START_TLS (i.e. JKS or PKCS12).
+ 'TLS - Truststore' - Path to the Truststore that is used when connecting to LDAP using START_TLS.
+ 'TLS - Truststore Password' - Password for the Truststore that is used when connecting to
+ LDAP using START_TLS.
+ 'TLS - Truststore Type' - Type of the Truststore that is used when connecting to LDAP using
+ START_TLS (i.e. JKS or PKCS12).
+ 'TLS - Client Auth' - Client authentication policy when connecting to LDAP using START_TLS.
+ Possible values are REQUIRED, WANT, NONE.
+ 'TLS - Protocol' - Protocol to use when connecting to LDAP using START_TLS. (i.e. TLS,
+ TLSv1.1, TLSv1.2, etc).
+ 'TLS - Shutdown Gracefully' - Specifies whether the TLS should be shut down gracefully
+ before the target context is closed. Defaults to false.
+
+ 'Referral Strategy' - Strategy for handling referrals. Possible values are FOLLOW, IGNORE, THROW.
+ 'Connect Timeout' - Duration of connect timeout. (i.e. 10 secs).
+ 'Read Timeout' - Duration of read timeout. (i.e. 10 secs).
+
+ 'Url' - Url of the LDAP servier (i.e. ldap://<hostname>:<port>).
+ 'User Search Base' - Base DN for searching for users (i.e. CN=Users,DC=example,DC=com).
+ 'User Search Filter' - Filter for searching for users against the 'User Search Base'.
+ (i.e. sAMAccountName={0}). The user specified name is inserted into '{0}'.
+
+ 'Authentication Expiration' - The duration of how long the user authentication is valid
+ for. If the user never logs out, they will be required to log back in following
+ this duration.
+ -->
+ <provider>
+ <identifier>ldap-provider</identifier>
+ <class>org.apache.nifi.ldap.LdapProvider</class>
+ <property name="Authentication Strategy">START_TLS</property>
+
+ <property name="Manager DN"></property><property name="Manager Password">thisIsABadPassword</property>
+
+ <property name="TLS - Keystore"></property>
+ <property name="TLS - Keystore Password">thisIsABadPassword</property><property name="TLS - Keystore Type"></property>
+ <property name="TLS - Truststore"></property><property name="TLS - Truststore Password">thisIsABadPassword</property><property name="TLS - Truststore Type"></property>
+ <property name="TLS - Client Auth"></property>
+ <property name="TLS - Protocol"></property>
+ <property name="TLS - Shutdown Gracefully"></property>
+
+ <property name="Referral Strategy">FOLLOW</property>
+ <property name="Connect Timeout">10 secs</property>
+ <property name="Read Timeout">10 secs</property>
+
+ <property name="Url"></property>
+ <property name="User Search Base"></property>
+ <property name="User Search Filter"></property>
+
+ <property name="Authentication Expiration">12 hours</property>
+ </provider>
+
+ <!--
+ Identity Provider for users logging in with username/password against a Kerberos KDC server.
+
+ 'Default Realm' - Default realm to provide when user enters incomplete user principal (i.e. NIFI.APACHE.ORG).
+ 'Authentication Expiration' - The duration of how long the user authentication is valid for. If the user never logs out, they will be required to log back in following this duration.
+ -->
+ <!-- To enable the kerberos-provider remove 2 lines. This is 1 of 2.
+ <provider>
+ <identifier>kerberos-provider</identifier>
+ <class>org.apache.nifi.kerberos.KerberosProvider</class>
+ <property name="Default Realm">NIFI.APACHE.ORG</property>
+ <property name="Authentication Expiration">12 hours</property>
+ </provider>
+ To enable the kerberos-provider remove 2 lines. This is 2 of 2. -->
+</loginIdentityProviders>
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/nifi/blob/59fea1cb/nifi-toolkit/nifi-toolkit-encrypt-config/src/test/resources/login-identity-providers-populated.xml
----------------------------------------------------------------------
diff --git a/nifi-toolkit/nifi-toolkit-encrypt-config/src/test/resources/login-identity-providers-populated.xml b/nifi-toolkit/nifi-toolkit-encrypt-config/src/test/resources/login-identity-providers-populated.xml
new file mode 100644
index 0000000..5522c73
--- /dev/null
+++ b/nifi-toolkit/nifi-toolkit-encrypt-config/src/test/resources/login-identity-providers-populated.xml
@@ -0,0 +1,105 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+ http://www.apache.org/licenses/LICENSE-2.0
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<!--
+ This file lists the login identity providers to use when running securely. In order
+ to use a specific provider it must be configured here and it's identifier
+ must be specified in the nifi.properties file.
+-->
+<loginIdentityProviders>
+ <!--
+ Identity Provider for users logging in with username/password against an LDAP server.
+
+ 'Authentication Strategy' - How the connection to the LDAP server is authenticated. Possible
+ values are ANONYMOUS, SIMPLE, or START_TLS.
+
+ 'Manager DN' - The DN of the manager that is used to bind to the LDAP server to search for users.
+ 'Manager Password' - The password of the manager that is used to bind to the LDAP server to
+ search for users.
+
+ 'TLS - Keystore' - Path to the Keystore that is used when connecting to LDAP using START_TLS.
+ 'TLS - Keystore Password' - Password for the Keystore that is used when connecting to LDAP
+ using START_TLS.
+ 'TLS - Keystore Type' - Type of the Keystore that is used when connecting to LDAP using
+ START_TLS (i.e. JKS or PKCS12).
+ 'TLS - Truststore' - Path to the Truststore that is used when connecting to LDAP using START_TLS.
+ 'TLS - Truststore Password' - Password for the Truststore that is used when connecting to
+ LDAP using START_TLS.
+ 'TLS - Truststore Type' - Type of the Truststore that is used when connecting to LDAP using
+ START_TLS (i.e. JKS or PKCS12).
+ 'TLS - Client Auth' - Client authentication policy when connecting to LDAP using START_TLS.
+ Possible values are REQUIRED, WANT, NONE.
+ 'TLS - Protocol' - Protocol to use when connecting to LDAP using START_TLS. (i.e. TLS,
+ TLSv1.1, TLSv1.2, etc).
+ 'TLS - Shutdown Gracefully' - Specifies whether the TLS should be shut down gracefully
+ before the target context is closed. Defaults to false.
+
+ 'Referral Strategy' - Strategy for handling referrals. Possible values are FOLLOW, IGNORE, THROW.
+ 'Connect Timeout' - Duration of connect timeout. (i.e. 10 secs).
+ 'Read Timeout' - Duration of read timeout. (i.e. 10 secs).
+
+ 'Url' - Url of the LDAP servier (i.e. ldap://<hostname>:<port>).
+ 'User Search Base' - Base DN for searching for users (i.e. CN=Users,DC=example,DC=com).
+ 'User Search Filter' - Filter for searching for users against the 'User Search Base'.
+ (i.e. sAMAccountName={0}). The user specified name is inserted into '{0}'.
+
+ 'Authentication Expiration' - The duration of how long the user authentication is valid
+ for. If the user never logs out, they will be required to log back in following
+ this duration.
+ -->
+ <provider>
+ <identifier>ldap-provider</identifier>
+ <class>org.apache.nifi.ldap.LdapProvider</class>
+ <property name="Authentication Strategy">START_TLS</property>
+
+ <property name="Manager DN">someuser</property>
+ <property name="Manager Password">thisIsABadPassword</property>
+
+ <property name="TLS - Keystore"></property>
+ <property name="TLS - Keystore Password">thisIsABadPassword</property>
+ <property name="TLS - Keystore Type"></property>
+ <property name="TLS - Truststore"></property>
+ <property name="TLS - Truststore Password">thisIsABadPassword</property>
+ <property name="TLS - Truststore Type"></property>
+ <property name="TLS - Client Auth"></property>
+ <property name="TLS - Protocol"></property>
+ <property name="TLS - Shutdown Gracefully"></property>
+
+ <property name="Referral Strategy">FOLLOW</property>
+ <property name="Connect Timeout">10 secs</property>
+ <property name="Read Timeout">10 secs</property>
+
+ <property name="Url"></property>
+ <property name="User Search Base"></property>
+ <property name="User Search Filter"></property>
+
+ <property name="Authentication Expiration">12 hours</property>
+ </provider>
+
+ <!--
+ Identity Provider for users logging in with username/password against a Kerberos KDC server.
+
+ 'Default Realm' - Default realm to provide when user enters incomplete user principal (i.e. NIFI.APACHE.ORG).
+ 'Authentication Expiration' - The duration of how long the user authentication is valid for. If the user never logs out, they will be required to log back in following this duration.
+ -->
+ <!-- To enable the kerberos-provider remove 2 lines. This is 1 of 2.
+ <provider>
+ <identifier>kerberos-provider</identifier>
+ <class>org.apache.nifi.kerberos.KerberosProvider</class>
+ <property name="Default Realm">NIFI.APACHE.ORG</property>
+ <property name="Authentication Expiration">12 hours</property>
+ </provider>
+ To enable the kerberos-provider remove 2 lines. This is 2 of 2. -->
+</loginIdentityProviders>
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/nifi/blob/59fea1cb/nifi-toolkit/nifi-toolkit-encrypt-config/src/test/resources/login-identity-providers.xml
----------------------------------------------------------------------
diff --git a/nifi-toolkit/nifi-toolkit-encrypt-config/src/test/resources/login-identity-providers.xml b/nifi-toolkit/nifi-toolkit-encrypt-config/src/test/resources/login-identity-providers.xml
new file mode 100644
index 0000000..7e2a3e1
--- /dev/null
+++ b/nifi-toolkit/nifi-toolkit-encrypt-config/src/test/resources/login-identity-providers.xml
@@ -0,0 +1,105 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+ http://www.apache.org/licenses/LICENSE-2.0
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<!--
+ This file lists the login identity providers to use when running securely. In order
+ to use a specific provider it must be configured here and it's identifier
+ must be specified in the nifi.properties file.
+-->
+<loginIdentityProviders>
+ <!--
+ Identity Provider for users logging in with username/password against an LDAP server.
+
+ 'Authentication Strategy' - How the connection to the LDAP server is authenticated. Possible
+ values are ANONYMOUS, SIMPLE, or START_TLS.
+
+ 'Manager DN' - The DN of the manager that is used to bind to the LDAP server to search for users.
+ 'Manager Password' - The password of the manager that is used to bind to the LDAP server to
+ search for users.
+
+ 'TLS - Keystore' - Path to the Keystore that is used when connecting to LDAP using START_TLS.
+ 'TLS - Keystore Password' - Password for the Keystore that is used when connecting to LDAP
+ using START_TLS.
+ 'TLS - Keystore Type' - Type of the Keystore that is used when connecting to LDAP using
+ START_TLS (i.e. JKS or PKCS12).
+ 'TLS - Truststore' - Path to the Truststore that is used when connecting to LDAP using START_TLS.
+ 'TLS - Truststore Password' - Password for the Truststore that is used when connecting to
+ LDAP using START_TLS.
+ 'TLS - Truststore Type' - Type of the Truststore that is used when connecting to LDAP using
+ START_TLS (i.e. JKS or PKCS12).
+ 'TLS - Client Auth' - Client authentication policy when connecting to LDAP using START_TLS.
+ Possible values are REQUIRED, WANT, NONE.
+ 'TLS - Protocol' - Protocol to use when connecting to LDAP using START_TLS. (i.e. TLS,
+ TLSv1.1, TLSv1.2, etc).
+ 'TLS - Shutdown Gracefully' - Specifies whether the TLS should be shut down gracefully
+ before the target context is closed. Defaults to false.
+
+ 'Referral Strategy' - Strategy for handling referrals. Possible values are FOLLOW, IGNORE, THROW.
+ 'Connect Timeout' - Duration of connect timeout. (i.e. 10 secs).
+ 'Read Timeout' - Duration of read timeout. (i.e. 10 secs).
+
+ 'Url' - Url of the LDAP servier (i.e. ldap://<hostname>:<port>).
+ 'User Search Base' - Base DN for searching for users (i.e. CN=Users,DC=example,DC=com).
+ 'User Search Filter' - Filter for searching for users against the 'User Search Base'.
+ (i.e. sAMAccountName={0}). The user specified name is inserted into '{0}'.
+
+ 'Authentication Expiration' - The duration of how long the user authentication is valid
+ for. If the user never logs out, they will be required to log back in following
+ this duration.
+ -->
+ <provider>
+ <identifier>ldap-provider</identifier>
+ <class>org.apache.nifi.ldap.LdapProvider</class>
+ <property name="Authentication Strategy">START_TLS</property>
+
+ <property name="Manager DN"></property>
+ <property name="Manager Password"></property>
+
+ <property name="TLS - Keystore"></property>
+ <property name="TLS - Keystore Password"></property>
+ <property name="TLS - Keystore Type"></property>
+ <property name="TLS - Truststore"></property>
+ <property name="TLS - Truststore Password"></property>
+ <property name="TLS - Truststore Type"></property>
+ <property name="TLS - Client Auth"></property>
+ <property name="TLS - Protocol"></property>
+ <property name="TLS - Shutdown Gracefully"></property>
+
+ <property name="Referral Strategy">FOLLOW</property>
+ <property name="Connect Timeout">10 secs</property>
+ <property name="Read Timeout">10 secs</property>
+
+ <property name="Url"></property>
+ <property name="User Search Base"></property>
+ <property name="User Search Filter"></property>
+
+ <property name="Authentication Expiration">12 hours</property>
+ </provider>
+
+ <!--
+ Identity Provider for users logging in with username/password against a Kerberos KDC server.
+
+ 'Default Realm' - Default realm to provide when user enters incomplete user principal (i.e. NIFI.APACHE.ORG).
+ 'Authentication Expiration' - The duration of how long the user authentication is valid for. If the user never logs out, they will be required to log back in following this duration.
+ -->
+ <!-- To enable the kerberos-provider remove 2 lines. This is 1 of 2.
+ <provider>
+ <identifier>kerberos-provider</identifier>
+ <class>org.apache.nifi.kerberos.KerberosProvider</class>
+ <property name="Default Realm">NIFI.APACHE.ORG</property>
+ <property name="Authentication Expiration">12 hours</property>
+ </provider>
+ To enable the kerberos-provider remove 2 lines. This is 2 of 2. -->
+</loginIdentityProviders>
\ No newline at end of file
[3/3] nifi git commit: NIFI-2654 Enabled encryption coverage for
login-identity-providers.xml.
Posted by ym...@apache.org.
NIFI-2654 Enabled encryption coverage for login-identity-providers.xml.
Squashed commits:
[5dd22a9] NIFI-2654 Updated administration guide with login-identity-providers.xml flags.
Exposed master key retrieval code in NiFiPropertiesLoader.
Added logic to decrypt login identity providers XML configuration.
Updated login-identity-providers.xsd to include encryption scheme attribute.
Added unit tests. (+18 squashed commits)
Squashed commits:
[57c815f] NIFI-2654 Resolved issue where empty LIP property elements could not be encrypted.
Added unit test and resource.
[27d7309] NIFI-2654 Wired in serialization logic to write logic for LIP.
Added comprehensive unit test for LIP & NFP in same test.
[b450eb2] NIFI-2654 Finalized logic for preserving comments in LIP parsing.
[5aa6c9c] NIFI-2654 Added logic for maintaining XML formatting (comments and whitespace) for LIP.
Added unit tests (w/o encryption works; w/ does not).
[b53461f] NIFI-2654 Added unit test for full tool invocation migrating a login-identity-providers.xml file and updating file and bootstrap.conf with key.
[2d9686c] NIFI-2654 Updated tool description and various logging statements.
Added unit test for full tool invocation encrypting a login-identity-providers.xml file and updating file and bootstrap.conf with key.
[8c67cb2] NIFI-2654 Added logic to encrypt LIP XML content.
Added unit tests.
[8682d19] NIFI-2654 Added logic to handle "empty" (commented) LIP files.
Added unit tests.
[077230e] NIFI-2654 Fixed logic to decrypt multiline and multiple-per-line XML elements.
Added unit tests and resources.
[d5bb8da] NIFI-2654 Ignored unit test for unreadable conf directory because directory was causing Maven build issues.
Removed test resources.
[7e50506] NIFI-2654 Fixed AESSensitivePropertyProvider bug handling cipher text with whitespace.
Added unit test.
[b69a661] NIFI-2654 Fixed AESSensitivePropertyProviderFactoryTest to reflect absence of key causes errors.
[6f821b9] NIFI-2654 Added standard password to arbitrary encryption test for use in test resources.
[d289ffa] NIFI-2654 Added LIP XML decryption.
Added unit tests.
[a482245] NIFI-2654 Added LIP test resources.
[7204df4] NIFI-2654 Changed logic to only perform properties encryption when file path is provided.
[729e1df] NIFI-2654 Removed population of default file locations for bootstrap.conf, nifi.properties, and login-identity-providers.xml as not all files may be desired.
Added/updated unit tests.
[7dba5ef] NIFI-2654 Started LIP work (arguments & parsing).
Added unit tests.
Signed-off-by: Yolanda M. Davis <ym...@apache.org>
This closes #1216
Project: http://git-wip-us.apache.org/repos/asf/nifi/repo
Commit: http://git-wip-us.apache.org/repos/asf/nifi/commit/59fea1cb
Tree: http://git-wip-us.apache.org/repos/asf/nifi/tree/59fea1cb
Diff: http://git-wip-us.apache.org/repos/asf/nifi/diff/59fea1cb
Branch: refs/heads/master
Commit: 59fea1cb4ed440ad0e68d96a412792c3e4551309
Parents: 8ad3125
Author: Andy LoPresto <al...@apache.org>
Authored: Mon Nov 7 20:36:59 2016 -0800
Committer: Yolanda M. Davis <ym...@apache.org>
Committed: Mon Nov 14 22:39:06 2016 -0500
----------------------------------------------------------------------
.../src/main/asciidoc/administration-guide.adoc | 41 +-
.../AESSensitivePropertyProvider.java | 2 +
.../nifi/properties/NiFiPropertiesLoader.java | 8 +-
...SSensitivePropertyProviderFactoryTest.groovy | 20 +-
.../AESSensitivePropertyProviderTest.groovy | 30 +
.../NiFiPropertiesLoaderGroovyTest.groovy | 2 +
.../unreadable_conf/bootstrap.conf | 74 --
.../unreadable_conf/nifi.properties | 14 -
.../LoginIdentityProviderFactoryBean.java | 69 +-
.../src/main/xsd/login-identity-providers.xsd | 3 +-
.../LoginIdentityProviderFactoryBeanTest.groovy | 141 ++++
.../nifi/properties/ConfigEncryptionTool.groovy | 253 +++++-
.../properties/ConfigEncryptionToolTest.groovy | 766 ++++++++++++++++++-
.../bootstrap_with_master_key_128.conf | 74 ++
...n-identity-providers-commented-populated.xml | 107 +++
.../login-identity-providers-commented.xml | 107 +++
...login-identity-providers-populated-empty.xml | 105 +++
...-providers-populated-encrypted-multiline.xml | 110 +++
...rs-populated-encrypted-multiple-per-line.xml | 101 +++
...n-identity-providers-populated-encrypted.xml | 105 +++
...n-identity-providers-populated-multiline.xml | 111 +++
...ty-providers-populated-multiple-per-line.xml | 101 +++
...identity-providers-populated-single-line.xml | 101 +++
.../login-identity-providers-populated.xml | 105 +++
.../test/resources/login-identity-providers.xml | 105 +++
25 files changed, 2491 insertions(+), 164 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/nifi/blob/59fea1cb/nifi-docs/src/main/asciidoc/administration-guide.adoc
----------------------------------------------------------------------
diff --git a/nifi-docs/src/main/asciidoc/administration-guide.adoc b/nifi-docs/src/main/asciidoc/administration-guide.adoc
index 2ce6564..be2e684 100644
--- a/nifi-docs/src/main/asciidoc/administration-guide.adoc
+++ b/nifi-docs/src/main/asciidoc/administration-guide.adoc
@@ -987,17 +987,19 @@ The default encryption algorithm utilized is AES/GCM 128/256-bit. 128-bit is use
You can use the following command line options with the `encrypt-config` tool:
-* `-b,--bootstrapConf <arg>` The bootstrap.conf file to persist master key
-* `-e,--oldKey <arg>` The old raw hexadecimal key to use during key migration
-* `-h,--help` Prints this usage message
-* `-k,--key <arg>` The raw hexadecimal key to use to encrypt the sensitive properties
-* `-m,--migrate` If provided, the sensitive properties will be re-encrypted with a new key
-* `-n,--niFiProperties <arg>` The nifi.properties file containing unprotected config values (will be overwritten)
-* `-o,--outputNiFiProperties <arg>` The destination nifi.properties file containing protected config values (will not modify input nifi.properties)
-* `-p,--password <arg>` The password from which to derive the key to use to encrypt the sensitive properties
-* `-r,--useRawKey` If provided, the secure console will prompt for the raw key value in hexadecimal form
-* `-v,--verbose` Sets verbose mode (default false)
-* `-w,--oldPassword <arg>` The old password from which to derive the key during migration
+* `-b,--bootstrapConf <arg>` The bootstrap.conf file to persist master key
+* `-e,--oldKey <arg>` The old raw hexadecimal key to use during key migration
+* `-h,--help` Prints this usage message
+* `-k,--key <arg>` The raw hexadecimal key to use to encrypt the sensitive properties
+* `-m,--migrate` If provided, the sensitive properties will be re-encrypted with a new key
+* `-n,--niFiProperties <arg>` The nifi.properties file containing unprotected config values (will be overwritten)
+* `-o,--outputNiFiProperties <arg>` The destination nifi.properties file containing protected config values (will not modify input nifi.properties)
+* `-p,--password <arg>` The password from which to derive the key to use to encrypt the sensitive properties
+* `-r,--useRawKey` If provided, the secure console will prompt for the raw key value in hexadecimal form
+* `-v,--verbose` Sets verbose mode (default false)
+* `-w,--oldPassword <arg>` The old password from which to derive the key during migration
+* `-l,--loginIdentityProviders <arg>` The login-identity-providers.xml file containing unprotected config values (will be overwritten)
+* `-i,--outputLoginIdentityProviders <arg>` The destination login-identity-providers.xml file containing protected config values (will not modify input login-identity-providers.xml)
As an example of how the tool works, assume that you have installed the tool on a machine supporting 256-bit encryption and with the following existing values in the 'nifi.properties' file:
@@ -1058,6 +1060,23 @@ Sensitive configuration values are encrypted by the tool by default, however you
If the 'nifi.properties' file already has valid protected values, those property values are not modified by the tool.
+When applied to 'login-identity-providers.xml', the property elements are updated with an `encryption` attribute:
+
+----
+<!-- LDAP Provider -->
+<provider>
+ <identifier>ldap-provider</identifier>
+ <class>org.apache.nifi.ldap.LdapProvider</class>
+ <property name="Authentication Strategy">START_TLS</property>
+ <property name="Manager DN">someuser</property>
+ <property name="Manager Password" encryption="aes/gcm/128">q4r7WIgN0MaxdAKM||SGgdCTPGSFEcuH4RraMYEdeyVbOx93abdWTVSWvh1w+klA</property>
+ <property name="TLS - Keystore"></property>
+ <property name="TLS - Keystore Password" encryption="aes/gcm/128">Uah59TWX+Ru5GY5p||B44RT/LJtC08QWA5ehQf01JxIpf0qSJUzug25UwkF5a50g</property>
+ <property name="TLS - Keystore Type"></property>
+ ...
+ </provider>
+----
+
In order to change the key used to encrypt the sensitive values, indicate *migration mode* using the `-m` or `--migrate` flag, provide the new key or password using the `-k` or `-p` flags as usual, and provide the existing key or password using `-e` or `-w` respectively. This will allow the toolkit to decrypt the existing values and re-encrypt them, and update `bootstrap.conf` with the new key. Only one of the key or password needs to be specified for each phase (old vs. new), and any combination is sufficient:
* old key -> new key
http://git-wip-us.apache.org/repos/asf/nifi/blob/59fea1cb/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-properties-loader/src/main/java/org/apache/nifi/properties/AESSensitivePropertyProvider.java
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-properties-loader/src/main/java/org/apache/nifi/properties/AESSensitivePropertyProvider.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-properties-loader/src/main/java/org/apache/nifi/properties/AESSensitivePropertyProvider.java
index 770d55d..1df398e 100644
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-properties-loader/src/main/java/org/apache/nifi/properties/AESSensitivePropertyProvider.java
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-properties-loader/src/main/java/org/apache/nifi/properties/AESSensitivePropertyProvider.java
@@ -217,6 +217,8 @@ public class AESSensitivePropertyProvider implements SensitivePropertyProvider {
throw new IllegalArgumentException("The cipher text does not contain the delimiter " + DELIMITER + " -- it should be of the form Base64(IV) || Base64(cipherText)");
}
+ protectedValue = protectedValue.trim();
+
final String IV_B64 = protectedValue.substring(0, protectedValue.indexOf(DELIMITER));
byte[] iv = Base64.decode(IV_B64);
if (iv.length < IV_LENGTH) {
http://git-wip-us.apache.org/repos/asf/nifi/blob/59fea1cb/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-properties-loader/src/main/java/org/apache/nifi/properties/NiFiPropertiesLoader.java
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-properties-loader/src/main/java/org/apache/nifi/properties/NiFiPropertiesLoader.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-properties-loader/src/main/java/org/apache/nifi/properties/NiFiPropertiesLoader.java
index 7f89b3d..20b5191 100644
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-properties-loader/src/main/java/org/apache/nifi/properties/NiFiPropertiesLoader.java
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-properties-loader/src/main/java/org/apache/nifi/properties/NiFiPropertiesLoader.java
@@ -102,7 +102,13 @@ public class NiFiPropertiesLoader {
}
}
- private static String extractKeyFromBootstrapFile() throws IOException {
+ /**
+ * Returns the key (if any) used to encrypt sensitive properties, extracted from {@code $NIFI_HOME/conf/bootstrap.conf}.
+ *
+ * @return the key in hexadecimal format
+ * @throws IOException if the file is not readable
+ */
+ public static String extractKeyFromBootstrapFile() throws IOException {
// Guess at location of bootstrap.conf file from nifi.properties file
String defaultNiFiPropertiesPath = getDefaultFilePath();
File propertiesFile = new File(defaultNiFiPropertiesPath);
http://git-wip-us.apache.org/repos/asf/nifi/blob/59fea1cb/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-properties-loader/src/test/groovy/org/apache/nifi/properties/AESSensitivePropertyProviderFactoryTest.groovy
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-properties-loader/src/test/groovy/org/apache/nifi/properties/AESSensitivePropertyProviderFactoryTest.groovy b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-properties-loader/src/test/groovy/org/apache/nifi/properties/AESSensitivePropertyProviderFactoryTest.groovy
index e18ac93..115fca6 100644
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-properties-loader/src/test/groovy/org/apache/nifi/properties/AESSensitivePropertyProviderFactoryTest.groovy
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-properties-loader/src/test/groovy/org/apache/nifi/properties/AESSensitivePropertyProviderFactoryTest.groovy
@@ -56,17 +56,18 @@ class AESSensitivePropertyProviderFactoryTest extends GroovyTestCase {
@Ignore("This is resolved in PR 1216")
@Test
- public void testShouldGetProviderWithoutKey() throws Exception {
+ public void testShouldNotGetProviderWithoutKey() throws Exception {
// Arrange
SensitivePropertyProviderFactory factory = new AESSensitivePropertyProviderFactory()
// Act
- SensitivePropertyProvider provider = factory.getProvider()
+ def msg = shouldFail(SensitivePropertyProtectionException) {
+ SensitivePropertyProvider provider = factory.getProvider()
+ }
+ logger.expected(msg)
// Assert
- assert provider instanceof AESSensitivePropertyProvider
- assert !provider.@key
- assert !provider.@cipher
+ assert msg == "The provider factory cannot generate providers without a key"
}
@Test
@@ -90,11 +91,12 @@ class AESSensitivePropertyProviderFactoryTest extends GroovyTestCase {
SensitivePropertyProviderFactory factory = new AESSensitivePropertyProviderFactory("")
// Act
- SensitivePropertyProvider provider = factory.getProvider()
+ def msg = shouldFail(SensitivePropertyProtectionException) {
+ SensitivePropertyProvider provider = factory.getProvider()
+ }
+ logger.expected(msg)
// Assert
- assert provider instanceof AESSensitivePropertyProvider
- assert !provider.@key
- assert !provider.@cipher
+ assert msg == "The provider factory cannot generate providers without a key"
}
}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/nifi/blob/59fea1cb/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-properties-loader/src/test/groovy/org/apache/nifi/properties/AESSensitivePropertyProviderTest.groovy
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-properties-loader/src/test/groovy/org/apache/nifi/properties/AESSensitivePropertyProviderTest.groovy b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-properties-loader/src/test/groovy/org/apache/nifi/properties/AESSensitivePropertyProviderTest.groovy
index 3ca35f2..4c5a34d 100644
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-properties-loader/src/test/groovy/org/apache/nifi/properties/AESSensitivePropertyProviderTest.groovy
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-properties-loader/src/test/groovy/org/apache/nifi/properties/AESSensitivePropertyProviderTest.groovy
@@ -239,6 +239,36 @@ class AESSensitivePropertyProviderTest extends GroovyTestCase {
}
@Test
+ public void testShouldUnprotectValueWithWhitespace() throws Exception {
+ // Arrange
+ final String PLAINTEXT = "This is a plaintext value"
+
+ Map<Integer, Cipher> encryptionCiphers = KEY_SIZES.collectEntries { int keySize ->
+ byte[] iv = new byte[IV_LENGTH]
+ secureRandom.nextBytes(iv)
+ [(keySize): getCipher(true, keySize, iv)]
+ }
+
+ Map<Integer, String> CIPHER_TEXTS = encryptionCiphers.collectEntries { Map.Entry<Integer, Cipher> e ->
+ String iv = encoder.encodeToString(e.value.getIV())
+ String cipherText = encoder.encodeToString(e.value.doFinal(PLAINTEXT.getBytes(StandardCharsets.UTF_8)))
+ [(e.key): "${iv}||${cipherText}"]
+ }
+ CIPHER_TEXTS.each { key, ct -> logger.expected("Cipher text for ${key} length key: ${ct}") }
+
+ // Act
+ Map<Integer, String> plaintexts = CIPHER_TEXTS.collectEntries { int keySize, String cipherText ->
+ SensitivePropertyProvider spp = new AESSensitivePropertyProvider(Hex.decode(getKeyOfSize(keySize)))
+ logger.info("Initialized ${spp.name} with key size ${keySize}")
+ [(keySize): spp.unprotect("\t" + cipherText + "\n")]
+ }
+ plaintexts.each { ks, pt -> logger.info("Decrypted for ${ks} length key: ${pt}") }
+
+ // Assert
+ assert plaintexts.every { int ks, String pt -> pt == PLAINTEXT }
+ }
+
+ @Test
public void testShouldHandleUnprotectMalformedValue() throws Exception {
// Arrange
final String PLAINTEXT = "This is a plaintext value"
http://git-wip-us.apache.org/repos/asf/nifi/blob/59fea1cb/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-properties-loader/src/test/groovy/org/apache/nifi/properties/NiFiPropertiesLoaderGroovyTest.groovy
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-properties-loader/src/test/groovy/org/apache/nifi/properties/NiFiPropertiesLoaderGroovyTest.groovy b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-properties-loader/src/test/groovy/org/apache/nifi/properties/NiFiPropertiesLoaderGroovyTest.groovy
index eb1f081..980f86f 100644
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-properties-loader/src/test/groovy/org/apache/nifi/properties/NiFiPropertiesLoaderGroovyTest.groovy
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-properties-loader/src/test/groovy/org/apache/nifi/properties/NiFiPropertiesLoaderGroovyTest.groovy
@@ -22,6 +22,7 @@ import org.junit.After
import org.junit.AfterClass
import org.junit.Before
import org.junit.BeforeClass
+import org.junit.Ignore
import org.junit.Test
import org.junit.runner.RunWith
import org.junit.runners.JUnit4
@@ -349,6 +350,7 @@ class NiFiPropertiesLoaderGroovyTest extends GroovyTestCase {
Files.setPosixFilePermissions(unreadableFile.toPath(), originalPermissions)
}
+ @Ignore("Unreadable conf directory breaks build")
@Test
public void testShouldNotExtractKeyFromUnreadableConfDir() throws Exception {
// Arrange
http://git-wip-us.apache.org/repos/asf/nifi/blob/59fea1cb/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-properties-loader/src/test/resources/bootstrap_tests/unreadable_conf/bootstrap.conf
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-properties-loader/src/test/resources/bootstrap_tests/unreadable_conf/bootstrap.conf b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-properties-loader/src/test/resources/bootstrap_tests/unreadable_conf/bootstrap.conf
deleted file mode 100755
index 9225126..0000000
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-properties-loader/src/test/resources/bootstrap_tests/unreadable_conf/bootstrap.conf
+++ /dev/null
@@ -1,74 +0,0 @@
-#
-# Licensed to the Apache Software Foundation (ASF) under one or more
-# contributor license agreements. See the NOTICE file distributed with
-# this work for additional information regarding copyright ownership.
-# The ASF licenses this file to You under the Apache License, Version 2.0
-# (the "License"); you may not use this file except in compliance with
-# the License. You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-
-# Java command to use when running NiFi
-java=java
-
-# Username to use when running NiFi. This value will be ignored on Windows.
-run.as=
-
-# Configure where NiFi's lib and conf directories live
-lib.dir=./lib
-conf.dir=./conf
-
-# How long to wait after telling NiFi to shutdown before explicitly killing the Process
-graceful.shutdown.seconds=20
-
-# Disable JSR 199 so that we can use JSP's without running a JDK
-java.arg.1=-Dorg.apache.jasper.compiler.disablejsr199=true
-
-# JVM memory settings
-java.arg.2=-Xms512m
-java.arg.3=-Xmx512m
-
-# Enable Remote Debugging
-#java.arg.debug=-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=8000
-
-java.arg.4=-Djava.net.preferIPv4Stack=true
-
-# allowRestrictedHeaders is required for Cluster/Node communications to work properly
-java.arg.5=-Dsun.net.http.allowRestrictedHeaders=true
-java.arg.6=-Djava.protocol.handler.pkgs=sun.net.www.protocol
-
-# The G1GC is still considered experimental but has proven to be very advantageous in providing great
-# performance without significant "stop-the-world" delays.
-java.arg.13=-XX:+UseG1GC
-
-#Set headless mode by default
-java.arg.14=-Djava.awt.headless=true
-
-# Master key in hexadecimal format for encrypted sensitive configuration values
-nifi.bootstrap.sensitive.key=0123456789ABCDEFFEDCBA98765432100123456789ABCDEFFEDCBA9876543210
-
-###
-# Notification Services for notifying interested parties when NiFi is stopped, started, dies
-###
-
-# XML File that contains the definitions of the notification services
-notification.services.file=./conf/bootstrap-notification-services.xml
-
-# In the case that we are unable to send a notification for an event, how many times should we retry?
-notification.max.attempts=5
-
-# Comma-separated list of identifiers that are present in the notification.services.file; which services should be used to notify when NiFi is started?
-#nifi.start.notification.services=email-notification
-
-# Comma-separated list of identifiers that are present in the notification.services.file; which services should be used to notify when NiFi is stopped?
-#nifi.stop.notification.services=email-notification
-
-# Comma-separated list of identifiers that are present in the notification.services.file; which services should be used to notify when NiFi dies?
-#nifi.dead.notification.services=email-notification
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/nifi/blob/59fea1cb/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-properties-loader/src/test/resources/bootstrap_tests/unreadable_conf/nifi.properties
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-properties-loader/src/test/resources/bootstrap_tests/unreadable_conf/nifi.properties b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-properties-loader/src/test/resources/bootstrap_tests/unreadable_conf/nifi.properties
deleted file mode 100644
index ae1e83e..0000000
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-properties-loader/src/test/resources/bootstrap_tests/unreadable_conf/nifi.properties
+++ /dev/null
@@ -1,14 +0,0 @@
-# Licensed to the Apache Software Foundation (ASF) under one or more
-# contributor license agreements. See the NOTICE file distributed with
-# this work for additional information regarding copyright ownership.
-# The ASF licenses this file to You under the Apache License, Version 2.0
-# (the "License"); you may not use this file except in compliance with
-# the License. You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
http://git-wip-us.apache.org/repos/asf/nifi/blob/59fea1cb/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/main/java/org/apache/nifi/web/security/spring/LoginIdentityProviderFactoryBean.java
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/main/java/org/apache/nifi/web/security/spring/LoginIdentityProviderFactoryBean.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/main/java/org/apache/nifi/web/security/spring/LoginIdentityProviderFactoryBean.java
index 26fae82..ee978db 100644
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/main/java/org/apache/nifi/web/security/spring/LoginIdentityProviderFactoryBean.java
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/main/java/org/apache/nifi/web/security/spring/LoginIdentityProviderFactoryBean.java
@@ -16,6 +16,22 @@
*/
package org.apache.nifi.web.security.spring;
+import java.io.File;
+import java.io.IOException;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Field;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.util.HashMap;
+import java.util.Map;
+import javax.xml.XMLConstants;
+import javax.xml.bind.JAXBContext;
+import javax.xml.bind.JAXBElement;
+import javax.xml.bind.JAXBException;
+import javax.xml.bind.Unmarshaller;
+import javax.xml.transform.stream.StreamSource;
+import javax.xml.validation.Schema;
+import javax.xml.validation.SchemaFactory;
import org.apache.commons.lang3.StringUtils;
import org.apache.nifi.authentication.AuthenticationResponse;
import org.apache.nifi.authentication.LoginCredentials;
@@ -31,6 +47,11 @@ import org.apache.nifi.authentication.generated.Property;
import org.apache.nifi.authentication.generated.Provider;
import org.apache.nifi.nar.ExtensionManager;
import org.apache.nifi.nar.NarCloseable;
+import org.apache.nifi.properties.AESSensitivePropertyProviderFactory;
+import org.apache.nifi.properties.NiFiPropertiesLoader;
+import org.apache.nifi.properties.SensitivePropertyProtectionException;
+import org.apache.nifi.properties.SensitivePropertyProvider;
+import org.apache.nifi.properties.SensitivePropertyProviderFactory;
import org.apache.nifi.util.NiFiProperties;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -38,22 +59,6 @@ import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.FactoryBean;
import org.xml.sax.SAXException;
-import javax.xml.XMLConstants;
-import javax.xml.bind.JAXBContext;
-import javax.xml.bind.JAXBElement;
-import javax.xml.bind.JAXBException;
-import javax.xml.bind.Unmarshaller;
-import javax.xml.transform.stream.StreamSource;
-import javax.xml.validation.Schema;
-import javax.xml.validation.SchemaFactory;
-import java.io.File;
-import java.lang.reflect.Constructor;
-import java.lang.reflect.Field;
-import java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.Method;
-import java.util.HashMap;
-import java.util.Map;
-
/**
*
*/
@@ -64,6 +69,9 @@ public class LoginIdentityProviderFactoryBean implements FactoryBean, Disposable
private static final String JAXB_GENERATED_PATH = "org.apache.nifi.authentication.generated";
private static final JAXBContext JAXB_CONTEXT = initializeJaxbContext();
+ private static SensitivePropertyProviderFactory SENSITIVE_PROPERTY_PROVIDER_FACTORY;
+ private static SensitivePropertyProvider SENSITIVE_PROPERTY_PROVIDER;
+
/**
* Load the JAXBContext.
*/
@@ -185,12 +193,39 @@ public class LoginIdentityProviderFactoryBean implements FactoryBean, Disposable
final Map<String, String> providerProperties = new HashMap<>();
for (final Property property : provider.getProperty()) {
- providerProperties.put(property.getName(), property.getValue());
+ if (!StringUtils.isBlank(property.getEncryption())) {
+ String decryptedValue = decryptValue(property.getValue(), property.getEncryption());
+ providerProperties.put(property.getName(), decryptedValue);
+ } else {
+ providerProperties.put(property.getName(), property.getValue());
+ }
}
return new StandardLoginIdentityProviderConfigurationContext(provider.getIdentifier(), providerProperties);
}
+ private String decryptValue(String cipherText, String encryptionScheme) throws SensitivePropertyProtectionException {
+ initializeSensitivePropertyProvider(encryptionScheme);
+ return SENSITIVE_PROPERTY_PROVIDER.unprotect(cipherText);
+ }
+
+ private static void initializeSensitivePropertyProvider(String encryptionScheme) throws SensitivePropertyProtectionException {
+ if (SENSITIVE_PROPERTY_PROVIDER == null || !SENSITIVE_PROPERTY_PROVIDER.getIdentifierKey().equalsIgnoreCase(encryptionScheme)) {
+ try {
+ String keyHex = getMasterKey();
+ SENSITIVE_PROPERTY_PROVIDER_FACTORY = new AESSensitivePropertyProviderFactory(keyHex);
+ SENSITIVE_PROPERTY_PROVIDER = SENSITIVE_PROPERTY_PROVIDER_FACTORY.getProvider();
+ } catch (IOException e) {
+ logger.error("Error extracting master key from bootstrap.conf for login identity provider decryption", e);
+ throw new SensitivePropertyProtectionException("Could not read master key from bootstrap.conf");
+ }
+ }
+ }
+
+ private static String getMasterKey() throws IOException {
+ return NiFiPropertiesLoader.extractKeyFromBootstrapFile();
+ }
+
private void performMethodInjection(final LoginIdentityProvider instance, final Class loginIdentityProviderClass)
throws IllegalAccessException, IllegalArgumentException, InvocationTargetException {
http://git-wip-us.apache.org/repos/asf/nifi/blob/59fea1cb/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/main/xsd/login-identity-providers.xsd
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/main/xsd/login-identity-providers.xsd b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/main/xsd/login-identity-providers.xsd
index 628f390..12a85ca 100644
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/main/xsd/login-identity-providers.xsd
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/main/xsd/login-identity-providers.xsd
@@ -27,7 +27,8 @@
<xs:complexType name="Property">
<xs:simpleContent>
<xs:extension base="xs:string">
- <xs:attribute name="name" type="NonEmptyStringType"></xs:attribute>
+ <xs:attribute name="name" type="NonEmptyStringType"/>
+ <xs:attribute name="encryption" type="xs:string"/>
</xs:extension>
</xs:simpleContent>
</xs:complexType>
http://git-wip-us.apache.org/repos/asf/nifi/blob/59fea1cb/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/test/groovy/org/apache/nifi/web/security/spring/LoginIdentityProviderFactoryBeanTest.groovy
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/test/groovy/org/apache/nifi/web/security/spring/LoginIdentityProviderFactoryBeanTest.groovy b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/test/groovy/org/apache/nifi/web/security/spring/LoginIdentityProviderFactoryBeanTest.groovy
new file mode 100644
index 0000000..13eab19
--- /dev/null
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/test/groovy/org/apache/nifi/web/security/spring/LoginIdentityProviderFactoryBeanTest.groovy
@@ -0,0 +1,141 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.nifi.web.security.spring
+
+import org.apache.nifi.authentication.generated.Property
+import org.apache.nifi.authentication.generated.Provider
+import org.apache.nifi.properties.AESSensitivePropertyProvider
+import org.bouncycastle.jce.provider.BouncyCastleProvider
+import org.junit.After
+import org.junit.AfterClass
+import org.junit.Before
+import org.junit.BeforeClass
+import org.junit.Ignore
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.junit.runners.JUnit4
+import org.slf4j.Logger
+import org.slf4j.LoggerFactory
+
+import javax.crypto.Cipher
+import java.security.Security
+
+@RunWith(JUnit4.class)
+class LoginIdentityProviderFactoryBeanTest extends GroovyTestCase {
+ private static final Logger logger = LoggerFactory.getLogger(LoginIdentityProviderFactoryBeanTest.class)
+
+ // These blocks configure the constant values depending on JCE policies of the machine running the tests
+ private static final String KEY_HEX_128 = "0123456789ABCDEFFEDCBA9876543210"
+ private static final String KEY_HEX_256 = KEY_HEX_128 * 2
+ public static final String KEY_HEX = isUnlimitedStrengthCryptoAvailable() ? KEY_HEX_256 : KEY_HEX_128
+
+ private static final String CIPHER_TEXT_128 = "6pqdM1urBEPHtj+L||ds0Z7RpqOA2321c/+7iPMfxDrqmH5Qx6UwQG0eIYB//3Ng"
+ private static final String CIPHER_TEXT_256 = "TepMCD7v3LAMF0KX||ydSRWPRl1/JXgTsZtfzCnDXu7a0lTLysjPL2I06EPUCHzw"
+ public static final String CIPHER_TEXT = isUnlimitedStrengthCryptoAvailable() ? CIPHER_TEXT_256 : CIPHER_TEXT_128
+
+ private static final String ENCRYPTION_SCHEME_128 = "aes/gcm/128"
+ private static final String ENCRYPTION_SCHEME_256 = "aes/gcm/256"
+ public static
+ final String ENCRYPTION_SCHEME = isUnlimitedStrengthCryptoAvailable() ? ENCRYPTION_SCHEME_256 : ENCRYPTION_SCHEME_128
+
+ private static final String PASSWORD = "thisIsABadPassword"
+
+ @BeforeClass
+ public static void setUpOnce() throws Exception {
+ Security.addProvider(new BouncyCastleProvider())
+
+ logger.metaClass.methodMissing = { String name, args ->
+ logger.info("[${name?.toUpperCase()}] ${(args as List).join(" ")}")
+ }
+ }
+
+ @AfterClass
+ public static void tearDownOnce() throws Exception {
+ }
+
+ @Before
+ public void setUp() throws Exception {
+ LoginIdentityProviderFactoryBean.SENSITIVE_PROPERTY_PROVIDER = new AESSensitivePropertyProvider(KEY_HEX)
+ }
+
+ @After
+ public void tearDown() throws Exception {
+ LoginIdentityProviderFactoryBean.SENSITIVE_PROPERTY_PROVIDER = null
+ LoginIdentityProviderFactoryBean.SENSITIVE_PROPERTY_PROVIDER_FACTORY = null
+ }
+
+ private static boolean isUnlimitedStrengthCryptoAvailable() {
+ Cipher.getMaxAllowedKeyLength("AES") > 128
+ }
+
+ private static int getKeyLength(String keyHex = KEY_HEX) {
+ keyHex?.size() * 4
+ }
+
+ @Ignore("Can't test without overloading static metaClass method")
+ @Test
+ void testShouldInitializeSensitivePropertyProvider() {
+ // Arrange
+ assert !LoginIdentityProviderFactoryBean.SENSITIVE_PROPERTY_PROVIDER
+ assert !LoginIdentityProviderFactoryBean.SENSITIVE_PROPERTY_PROVIDER_FACTORY
+
+ logger.info("Encryption scheme: ${ENCRYPTION_SCHEME}")
+
+ // Act
+ LoginIdentityProviderFactoryBean.initializeSensitivePropertyProvider(ENCRYPTION_SCHEME)
+
+ // Assert
+ assert LoginIdentityProviderFactoryBean.SENSITIVE_PROPERTY_PROVIDER
+ assert LoginIdentityProviderFactoryBean.SENSITIVE_PROPERTY_PROVIDER_FACTORY
+ assert LoginIdentityProviderFactoryBean.SENSITIVE_PROPERTY_PROVIDER.getIdentifierKey() == ENCRYPTION_SCHEME
+ }
+
+ @Test
+ void testShouldDecryptValue() {
+ // Arrange
+ logger.info("Encryption scheme: ${ENCRYPTION_SCHEME}")
+ logger.info("Cipher text: ${CIPHER_TEXT}")
+
+ // Act
+ String decrypted = new LoginIdentityProviderFactoryBean().decryptValue(CIPHER_TEXT, ENCRYPTION_SCHEME)
+ logger.info("Decrypted ${CIPHER_TEXT} -> ${decrypted}")
+
+ // Assert
+ assert decrypted == PASSWORD
+ }
+
+ @Test
+ void testShouldLoadEncryptedLoginIdentityProviderConfiguration() {
+ // Arrange
+ Provider encryptedProvider = new Provider()
+ encryptedProvider.identifier ="ldap-provider"
+ encryptedProvider.clazz = "org.apache.nifi.ldap.LdapProvider"
+ def managerPasswordName = "Manager Password"
+ Property managerPasswordProperty = new Property(name: managerPasswordName, value: CIPHER_TEXT, encryption: ENCRYPTION_SCHEME)
+ encryptedProvider.property = [managerPasswordProperty]
+
+ logger.info("Manager Password property: ${managerPasswordProperty.dump()}")
+ def bean = new LoginIdentityProviderFactoryBean()
+
+ // Act
+ def context = bean.loadLoginIdentityProviderConfiguration(encryptedProvider)
+ logger.info("Loaded context: ${context.dump()}")
+
+ // Assert
+ assert context.getProperty(managerPasswordName) == PASSWORD
+ }
+}
http://git-wip-us.apache.org/repos/asf/nifi/blob/59fea1cb/nifi-toolkit/nifi-toolkit-encrypt-config/src/main/groovy/org/apache/nifi/properties/ConfigEncryptionTool.groovy
----------------------------------------------------------------------
diff --git a/nifi-toolkit/nifi-toolkit-encrypt-config/src/main/groovy/org/apache/nifi/properties/ConfigEncryptionTool.groovy b/nifi-toolkit/nifi-toolkit-encrypt-config/src/main/groovy/org/apache/nifi/properties/ConfigEncryptionTool.groovy
index 30a682c..dc11df4 100644
--- a/nifi-toolkit/nifi-toolkit-encrypt-config/src/main/groovy/org/apache/nifi/properties/ConfigEncryptionTool.groovy
+++ b/nifi-toolkit/nifi-toolkit-encrypt-config/src/main/groovy/org/apache/nifi/properties/ConfigEncryptionTool.groovy
@@ -17,6 +17,7 @@
package org.apache.nifi.properties
import groovy.io.GroovyPrintWriter
+import groovy.xml.XmlUtil
import org.apache.commons.cli.CommandLine
import org.apache.commons.cli.CommandLineParser
import org.apache.commons.cli.DefaultParser
@@ -46,23 +47,30 @@ class ConfigEncryptionTool {
public String niFiPropertiesPath
public String outputNiFiPropertiesPath
public String loginIdentityProvidersPath
+ public String outputLoginIdentityProvidersPath
private String keyHex
private String migrationKeyHex
private String password
private String migrationPassword
+
private NiFiProperties niFiProperties
+ private String loginIdentityProviders
private boolean usingPassword = true
private boolean usingPasswordMigration = true
private boolean migration = false
private boolean isVerbose = false
+ private boolean handlingNiFiProperties = false
+ private boolean handlingLoginIdentityProviders = false
private static final String HELP_ARG = "help"
private static final String VERBOSE_ARG = "verbose"
private static final String BOOTSTRAP_CONF_ARG = "bootstrapConf"
private static final String NIFI_PROPERTIES_ARG = "niFiProperties"
+ private static final String LOGIN_IDENTITY_PROVIDERS_ARG = "loginIdentityProviders"
private static final String OUTPUT_NIFI_PROPERTIES_ARG = "outputNiFiProperties"
+ private static final String OUTPUT_LOGIN_IDENTITY_PROVIDERS_ARG = "outputLoginIdentityProviders"
private static final String KEY_ARG = "key"
private static final String PASSWORD_ARG = "password"
private static final String KEY_MIGRATION_ARG = "oldKey"
@@ -87,7 +95,9 @@ class ConfigEncryptionTool {
private static final String FOOTER = buildFooter()
private static
- final String DEFAULT_DESCRIPTION = "This tool reads from a nifi.properties file with plain sensitive configuration values, prompts the user for a master key, and encrypts each value. It will replace the plain value with the protected value in the same file (or write to a new nifi.properties file if specified)."
+ final String DEFAULT_DESCRIPTION = "This tool reads from a nifi.properties and/or login-identity-providers.xml file with plain sensitive configuration values, prompts the user for a master key, and encrypts each value. It will replace the plain value with the protected value in the same file (or write to a new file if specified)."
+ static private final String LDAP_PROVIDER_REGEX = /<provider>\s*<identifier>\s*ldap-provider[\s\S]*?<\/provider>/
+ static private final String XML_DECLARATION_REGEX = /<\?xml version="1.0" encoding="UTF-8"\?>/
private static String buildHeader(String description = DEFAULT_DESCRIPTION) {
"${SEP}${description}${SEP * 2}"
@@ -111,8 +121,10 @@ class ConfigEncryptionTool {
options.addOption("h", HELP_ARG, false, "Prints this usage message")
options.addOption("v", VERBOSE_ARG, false, "Sets verbose mode (default false)")
options.addOption("n", NIFI_PROPERTIES_ARG, true, "The nifi.properties file containing unprotected config values (will be overwritten)")
+ options.addOption("l", LOGIN_IDENTITY_PROVIDERS_ARG, true, "The login-identity-providers.xml file containing unprotected config values (will be overwritten)")
options.addOption("b", BOOTSTRAP_CONF_ARG, true, "The bootstrap.conf file to persist master key")
options.addOption("o", OUTPUT_NIFI_PROPERTIES_ARG, true, "The destination nifi.properties file containing protected config values (will not modify input nifi.properties)")
+ options.addOption("i", OUTPUT_LOGIN_IDENTITY_PROVIDERS_ARG, true, "The destination login-identity-providers.xml file containing protected config values (will not modify input login-identity-providers.xml)")
options.addOption("k", KEY_ARG, true, "The raw hexadecimal key to use to encrypt the sensitive properties")
options.addOption("e", KEY_MIGRATION_ARG, true, "The old raw hexadecimal key to use during key migration")
options.addOption("p", PASSWORD_ARG, true, "The password from which to derive the key to use to encrypt the sensitive properties")
@@ -141,6 +153,7 @@ class ConfigEncryptionTool {
throw new CommandLineParseException(errorMessage, exitCode);
}
+ // TODO: Refactor component steps into methods
protected CommandLine parse(String[] args) throws CommandLineParseException {
CommandLineParser parser = new DefaultParser()
CommandLine commandLine
@@ -152,15 +165,49 @@ class ConfigEncryptionTool {
isVerbose = commandLine.hasOption(VERBOSE_ARG)
- bootstrapConfPath = commandLine.getOptionValue(BOOTSTRAP_CONF_ARG, determineDefaultBootstrapConfPath())
- niFiPropertiesPath = commandLine.getOptionValue(NIFI_PROPERTIES_ARG, determineDefaultNiFiPropertiesPath())
- outputNiFiPropertiesPath = commandLine.getOptionValue(OUTPUT_NIFI_PROPERTIES_ARG, niFiPropertiesPath)
+ bootstrapConfPath = commandLine.getOptionValue(BOOTSTRAP_CONF_ARG)
+
+ if (commandLine.hasOption(NIFI_PROPERTIES_ARG)) {
+ if (isVerbose) {
+ logger.info("Handling encryption of nifi.properties")
+ }
+ niFiPropertiesPath = commandLine.getOptionValue(NIFI_PROPERTIES_ARG)
+ outputNiFiPropertiesPath = commandLine.getOptionValue(OUTPUT_NIFI_PROPERTIES_ARG, niFiPropertiesPath)
+ handlingNiFiProperties = true
- if (niFiPropertiesPath == outputNiFiPropertiesPath) {
- // TODO: Add confirmation pause and provide -y flag to offer no-interaction mode?
- logger.warn("The source nifi.properties and destination nifi.properties are identical [${outputNiFiPropertiesPath}] so the original will be overwritten")
+ if (niFiPropertiesPath == outputNiFiPropertiesPath) {
+ // TODO: Add confirmation pause and provide -y flag to offer no-interaction mode?
+ logger.warn("The source nifi.properties and destination nifi.properties are identical [${outputNiFiPropertiesPath}] so the original will be overwritten")
+ }
}
+ if (commandLine.hasOption(LOGIN_IDENTITY_PROVIDERS_ARG)) {
+ if (isVerbose) {
+ logger.info("Handling encryption of login-identity-providers.xml")
+ }
+ loginIdentityProvidersPath = commandLine.getOptionValue(LOGIN_IDENTITY_PROVIDERS_ARG)
+ outputLoginIdentityProvidersPath = commandLine.getOptionValue(OUTPUT_LOGIN_IDENTITY_PROVIDERS_ARG, loginIdentityProvidersPath)
+ handlingLoginIdentityProviders = true
+
+ if (loginIdentityProvidersPath == outputLoginIdentityProvidersPath) {
+ // TODO: Add confirmation pause and provide -y flag to offer no-interaction mode?
+ logger.warn("The source login-identity-providers.xml and destination login-identity-providers.xml are identical [${outputLoginIdentityProvidersPath}] so the original will be overwritten")
+ }
+ }
+
+ if (isVerbose) {
+ logger.info(" bootstrap.conf: \t${bootstrapConfPath}")
+ logger.info("(src) nifi.properties: \t${niFiPropertiesPath}")
+ logger.info("(dest) nifi.properties: \t${outputNiFiPropertiesPath}")
+ logger.info("(src) login-identity-providers.xml: \t${loginIdentityProvidersPath}")
+ logger.info("(dest) login-identity-providers.xml: \t${outputLoginIdentityProvidersPath}")
+ }
+
+ // TODO: Implement in NIFI-2655
+// if (!commandLine.hasOption(NIFI_PROPERTIES_ARG) && !commandLine.hasOption(LOGIN_IDENTITY_PROVIDERS_ARG)) {
+// printUsageAndThrow("One of '-n'/'--${NIFI_PROPERTIES_ARG}' or '-l'/'--${LOGIN_IDENTITY_PROVIDERS_ARG}' must be provided", ExitCode.INVALID_ARGS)
+// }
+
if (commandLine.hasOption(MIGRATION_ARG)) {
migration = true
if (isVerbose) {
@@ -169,7 +216,7 @@ class ConfigEncryptionTool {
if (commandLine.hasOption(PASSWORD_MIGRATION_ARG)) {
usingPasswordMigration = true
if (commandLine.hasOption(KEY_MIGRATION_ARG)) {
- printUsageAndThrow("Only one of ${PASSWORD_MIGRATION_ARG} and ${KEY_MIGRATION_ARG} can be used", ExitCode.INVALID_ARGS)
+ printUsageAndThrow("Only one of '-w'/'--${PASSWORD_MIGRATION_ARG}' and '-e'/'--${KEY_MIGRATION_ARG}' can be used", ExitCode.INVALID_ARGS)
} else {
migrationPassword = commandLine.getOptionValue(PASSWORD_MIGRATION_ARG)
}
@@ -179,14 +226,14 @@ class ConfigEncryptionTool {
}
} else {
if (commandLine.hasOption(PASSWORD_MIGRATION_ARG) || commandLine.hasOption(KEY_MIGRATION_ARG)) {
- printUsageAndThrow("${PASSWORD_MIGRATION_ARG} and ${KEY_MIGRATION_ARG} are ignored unless ${MIGRATION_ARG} is enabled", ExitCode.INVALID_ARGS)
+ printUsageAndThrow("'-w'/'--${PASSWORD_MIGRATION_ARG}' and '-e'/'--${KEY_MIGRATION_ARG}' are ignored unless '-m'/'--${MIGRATION_ARG}' is enabled", ExitCode.INVALID_ARGS)
}
}
if (commandLine.hasOption(PASSWORD_ARG)) {
usingPassword = true
if (commandLine.hasOption(KEY_ARG)) {
- printUsageAndThrow("Only one of ${PASSWORD_ARG} and ${KEY_ARG} can be used", ExitCode.INVALID_ARGS)
+ printUsageAndThrow("Only one of '-p'/'--${PASSWORD_ARG}' and '-k'/'--${KEY_ARG}' can be used", ExitCode.INVALID_ARGS)
} else {
password = commandLine.getOptionValue(PASSWORD_ARG)
}
@@ -311,6 +358,111 @@ class ConfigEncryptionTool {
}
/**
+ * Loads the login identity providers configuration from the provided file path.
+ *
+ * @param existingKeyHex the key used to encrypt the configs (defaults to the current key)
+ *
+ * @return the file content
+ * @throw IOException if the login-identity-providers.xml file cannot be read
+ */
+ private String loadLoginIdentityProviders(String existingKeyHex = keyHex) throws IOException {
+ File loginIdentityProvidersFile
+ if (loginIdentityProvidersPath && (loginIdentityProvidersFile = new File(loginIdentityProvidersPath)).exists()) {
+ try {
+ String xmlContent = loginIdentityProvidersFile.text
+ List<String> lines = loginIdentityProvidersFile.readLines()
+ logger.info("Loaded LoginIdentityProviders content (${lines.size()} lines)")
+ String decryptedXmlContent = decryptLoginIdentityProviders(xmlContent, existingKeyHex)
+// String decryptedXmlContent = ConfigEncryptionUtility.decryptLoginIdentityProviders(xmlContent)
+ return decryptedXmlContent
+ } catch (RuntimeException e) {
+ if (isVerbose) {
+ logger.error("Encountered an error", e)
+ }
+ throw new IOException("Cannot load LoginIdentityProviders from [${loginIdentityProvidersPath}]", e)
+ }
+ } else {
+ printUsageAndThrow("Cannot load LoginIdentityProviders from [${loginIdentityProvidersPath}]", ExitCode.ERROR_READING_NIFI_PROPERTIES)
+ }
+ }
+
+ String decryptLoginIdentityProviders(String encryptedXml, String existingKeyHex = keyHex) {
+ AESSensitivePropertyProvider sensitivePropertyProvider = new AESSensitivePropertyProvider(existingKeyHex)
+
+ try {
+ def doc = new XmlSlurper().parseText(encryptedXml)
+ def passwords = doc.provider.find { it.identifier == 'ldap-provider' }.property.findAll {
+ it.@name =~ "Password" && it.@encryption =~ "aes/gcm/\\d{3}"
+ }
+
+ if (passwords.isEmpty()) {
+ if (isVerbose) {
+ logger.info("No encrypted password property elements found in login-identity-providers.xml")
+ }
+ return encryptedXml
+ }
+
+ passwords.each { password ->
+ if (isVerbose) {
+ logger.info("Attempting to decrypt ${password.text()}")
+ }
+ String decryptedValue = sensitivePropertyProvider.unprotect(password.text().trim())
+ password.replaceNode {
+ property(name: password.@name, encryption: "none", decryptedValue)
+ }
+ }
+
+ // Does not preserve whitespace formatting or comments
+ String updatedXml = XmlUtil.serialize(doc)
+ logger.info("Updated XML content: ${updatedXml}")
+ updatedXml
+ } catch (Exception e) {
+ printUsageAndThrow("Cannot decrypt login identity providers XML content", ExitCode.SERVICE_ERROR)
+ }
+ }
+
+ String encryptLoginIdentityProviders(String plainXml, String newKeyHex = keyHex) {
+ AESSensitivePropertyProvider sensitivePropertyProvider = new AESSensitivePropertyProvider(newKeyHex)
+
+ // TODO: Switch to XmlParser & XmlNodePrinter to maintain "empty" element structure
+ try {
+ def doc = new XmlSlurper().parseText(plainXml)
+ // Only operate on un-encrypted passwords
+ def passwords = doc.provider.find { it.identifier == 'ldap-provider' }
+ .property.findAll {
+ it.@name =~ "Password" && (it.@encryption == "none" || it.@encryption == "") && it.text()
+ }
+
+ if (passwords.isEmpty()) {
+ if (isVerbose) {
+ logger.info("No unencrypted password property elements found in login-identity-providers.xml")
+ }
+ return plainXml
+ }
+
+ passwords.each { password ->
+ if (isVerbose) {
+ logger.info("Attempting to encrypt ${password.name()}")
+ }
+ String encryptedValue = sensitivePropertyProvider.protect(password.text().trim())
+ password.replaceNode {
+ property(name: password.@name, encryption: sensitivePropertyProvider.identifierKey, encryptedValue)
+ }
+ }
+
+ // Does not preserve whitespace formatting or comments
+ String updatedXml = XmlUtil.serialize(doc)
+ logger.info("Updated XML content: ${updatedXml}")
+ updatedXml
+ } catch (Exception e) {
+ if (isVerbose) {
+ logger.error("Encountered exception", e)
+ }
+ printUsageAndThrow("Cannot encrypt login identity providers XML content", ExitCode.SERVICE_ERROR)
+ }
+ }
+
+ /**
* Accepts a {@link NiFiProperties} instance, iterates over all non-empty sensitive properties which are not already marked as protected, encrypts them using the master key, and updates the property with the protected value. Additionally, adds a new sibling property {@code x.y.z.protected=aes/gcm/{128,256}} for each indicating the encryption scheme used.
*
* @param plainProperties the NiFiProperties instance containing the raw values
@@ -427,6 +579,39 @@ class ConfigEncryptionTool {
}
/**
+ * Writes the contents of the login identity providers configuration file with encrypted values to the output {@code login-identity-providers.xml} file.
+ *
+ * @throw IOException if there is a problem reading or writing the login-identity-providers.xml file
+ */
+ private void writeLoginIdentityProviders() throws IOException {
+ if (!outputLoginIdentityProvidersPath) {
+ throw new IllegalArgumentException("Cannot write encrypted properties to empty login-identity-providers.xml path")
+ }
+
+ File outputLoginIdentityProvidersFile = new File(outputLoginIdentityProvidersPath)
+
+ if (isSafeToWrite(outputLoginIdentityProvidersFile)) {
+ try {
+ String updatedXmlContent
+ File loginIdentityProvidersFile = new File(loginIdentityProvidersPath)
+ if (loginIdentityProvidersFile.exists() && loginIdentityProvidersFile.canRead()) {
+ // Instead of just writing the XML content to a file, this method attempts to maintain the structure of the original file and preserves comments
+ updatedXmlContent = serializeLoginIdentityProvidersAndPreserveFormat(loginIdentityProviders, loginIdentityProvidersFile).join("\n")
+ }
+
+ // Write the updated values back to the file
+ outputLoginIdentityProvidersFile.text = updatedXmlContent
+ } catch (IOException e) {
+ def msg = "Encountered an exception updating the login-identity-providers.xml file with the encrypted values"
+ logger.error(msg, e)
+ throw e
+ }
+ } else {
+ throw new IOException("The login-identity-providers.xml file at ${outputLoginIdentityProvidersPath} must be writable by the user running this tool")
+ }
+ }
+
+ /**
* Writes the contents of the {@link NiFiProperties} instance with encrypted values to the output {@code nifi.properties} file.
*
* @throw IOException if there is a problem reading or writing the nifi.properties file
@@ -502,6 +687,21 @@ class ConfigEncryptionTool {
out.toString().split("\n")
}
+
+ private
+ static List<String> serializeLoginIdentityProvidersAndPreserveFormat(String xmlContent, File originalLoginIdentityProvidersFile) {
+ def parsedXml = new XmlSlurper().parseText(xmlContent)
+ def provider = parsedXml.provider.find { it.identifier == "ldap-provider" }
+ def serializedProvider = new XmlUtil().serialize(provider)
+ // Remove XML declaration from top
+ serializedProvider = serializedProvider.replaceFirst(XML_DECLARATION_REGEX, "")
+
+ // Find the provider element of the new XML in the file contents
+ String fileContents = originalLoginIdentityProvidersFile.text
+ fileContents = fileContents.replaceFirst(LDAP_PROVIDER_REGEX, serializedProvider)
+ fileContents.split("\n")
+ }
+
/**
* Helper method which returns true if it is "safe" to write to the provided file.
*
@@ -527,6 +727,11 @@ class ConfigEncryptionTool {
"${niFiToolkitPath ? niFiToolkitPath + "/" : ""}conf/nifi.properties"
}
+ private static String determineDefaultLoginIdentityProvidersPath() {
+ String niFiToolkitPath = System.getenv(NIFI_TOOLKIT_HOME) ?: ""
+ "${niFiToolkitPath ? niFiToolkitPath + "/" : ""}conf/login-identity-providers.xml"
+ }
+
private static String deriveKeyFromPassword(String password) {
password = password?.trim()
if (!password || password.length() < MIN_PASSWORD_LENGTH) {
@@ -600,12 +805,23 @@ class ConfigEncryptionTool {
}
String existingKeyHex = tool.migrationKeyHex ?: tool.keyHex
- try {
- tool.niFiProperties = tool.loadNiFiProperties(existingKeyHex)
- } catch (Exception e) {
- tool.printUsageAndThrow("Cannot migrate key if no previous encryption occurred", ExitCode.ERROR_READING_NIFI_PROPERTIES)
+ if (tool.handlingNiFiProperties) {
+ try {
+ tool.niFiProperties = tool.loadNiFiProperties(existingKeyHex)
+ } catch (Exception e) {
+ tool.printUsageAndThrow("Cannot migrate key if no previous encryption occurred", ExitCode.ERROR_READING_NIFI_PROPERTIES)
+ }
+ tool.niFiProperties = tool.encryptSensitiveProperties(tool.niFiProperties)
+ }
+
+ if (tool.handlingLoginIdentityProviders) {
+ try {
+ tool.loginIdentityProviders = tool.loadLoginIdentityProviders(existingKeyHex)
+ } catch (Exception e) {
+ tool.printUsageAndThrow("Cannot migrate key if no previous encryption occurred", ExitCode.ERROR_INCORRECT_NUMBER_OF_PASSWORDS)
+ }
+ tool.loginIdentityProviders = tool.encryptLoginIdentityProviders(tool.loginIdentityProviders)
}
- tool.niFiProperties = tool.encryptSensitiveProperties(tool.niFiProperties)
} catch (CommandLineParseException e) {
if (e.exitCode == ExitCode.HELP) {
System.exit(ExitCode.HELP.ordinal())
@@ -622,7 +838,12 @@ class ConfigEncryptionTool {
// Do this as part of a transaction?
synchronized (this) {
tool.writeKeyToBootstrapConf()
- tool.writeNiFiProperties()
+ if (tool.handlingNiFiProperties) {
+ tool.writeNiFiProperties()
+ }
+ if (tool.handlingLoginIdentityProviders) {
+ tool.writeLoginIdentityProviders()
+ }
}
} catch (Exception e) {
if (tool.isVerbose) {
[2/3] nifi git commit: NIFI-2654 Enabled encryption coverage for
login-identity-providers.xml.
Posted by ym...@apache.org.
http://git-wip-us.apache.org/repos/asf/nifi/blob/59fea1cb/nifi-toolkit/nifi-toolkit-encrypt-config/src/test/groovy/org/apache/nifi/properties/ConfigEncryptionToolTest.groovy
----------------------------------------------------------------------
diff --git a/nifi-toolkit/nifi-toolkit-encrypt-config/src/test/groovy/org/apache/nifi/properties/ConfigEncryptionToolTest.groovy b/nifi-toolkit/nifi-toolkit-encrypt-config/src/test/groovy/org/apache/nifi/properties/ConfigEncryptionToolTest.groovy
index c1521d7..1784748 100644
--- a/nifi-toolkit/nifi-toolkit-encrypt-config/src/test/groovy/org/apache/nifi/properties/ConfigEncryptionToolTest.groovy
+++ b/nifi-toolkit/nifi-toolkit-encrypt-config/src/test/groovy/org/apache/nifi/properties/ConfigEncryptionToolTest.groovy
@@ -25,6 +25,7 @@ import org.apache.nifi.util.console.TextDevice
import org.apache.nifi.util.console.TextDevices
import org.bouncycastle.jce.provider.BouncyCastleProvider
import org.junit.After
+import org.junit.AfterClass
import org.junit.Assume
import org.junit.Before
import org.junit.BeforeClass
@@ -60,10 +61,15 @@ class ConfigEncryptionToolTest extends GroovyTestCase {
public static final String KEY_HEX = isUnlimitedStrengthCryptoAvailable() ? KEY_HEX_256 : KEY_HEX_128
private static final String PASSWORD = "thisIsABadPassword"
// From ConfigEncryptionTool.deriveKeyFromPassword("thisIsABadPassword")
- private static final String PASSWORD_KEY_HEX_256 = "2C576A9585DB862F5ECBEE5B4FFFCCA14B18D8365968D7081651006507AD2BDE"
+ private static
+ final String PASSWORD_KEY_HEX_256 = "2C576A9585DB862F5ECBEE5B4FFFCCA14B18D8365968D7081651006507AD2BDE"
private static final String PASSWORD_KEY_HEX_128 = "2C576A9585DB862F5ECBEE5B4FFFCCA1"
- private static final String PASSWORD_KEY_HEX = isUnlimitedStrengthCryptoAvailable() ? PASSWORD_KEY_HEX_256 : PASSWORD_KEY_HEX_128
+ private static
+ final String PASSWORD_KEY_HEX = isUnlimitedStrengthCryptoAvailable() ? PASSWORD_KEY_HEX_256 : PASSWORD_KEY_HEX_128
+
+ private static final int LIP_PASSWORD_LINE_COUNT = 3
+ private final String PASSWORD_PROP_REGEX = "<property[^>]* name=\".* Password\""
@BeforeClass
public static void setUpOnce() throws Exception {
@@ -72,6 +78,14 @@ class ConfigEncryptionToolTest extends GroovyTestCase {
logger.metaClass.methodMissing = { String name, args ->
logger.info("[${name?.toUpperCase()}] ${(args as List).join(" ")}")
}
+
+ setupTmpDir()
+ }
+
+ @AfterClass
+ public static void tearDownOnce() throws Exception {
+ File tmpDir = new File("target/tmp/")
+ tmpDir.delete()
}
@Before
@@ -87,6 +101,10 @@ class ConfigEncryptionToolTest extends GroovyTestCase {
Cipher.getMaxAllowedKeyLength("AES") > 128
}
+ private static int getKeyLength(String keyHex = KEY_HEX) {
+ keyHex?.size() * 4
+ }
+
private static void printProperties(NiFiProperties properties) {
if (!(properties instanceof ProtectedNiFiProperties)) {
properties = new ProtectedNiFiProperties(properties)
@@ -139,6 +157,13 @@ class ConfigEncryptionToolTest extends GroovyTestCase {
formattedDate =~ datePattern
}
+ private static File setupTmpDir(String tmpDirPath = "target/tmp/") {
+ File tmpDir = new File(tmpDirPath)
+ tmpDir.mkdirs()
+ setFilePermissions(tmpDir, [PosixFilePermission.OWNER_READ, PosixFilePermission.OWNER_WRITE, PosixFilePermission.OWNER_EXECUTE, PosixFilePermission.GROUP_READ, PosixFilePermission.GROUP_WRITE, PosixFilePermission.GROUP_EXECUTE, PosixFilePermission.OTHERS_READ, PosixFilePermission.OTHERS_WRITE, PosixFilePermission.OTHERS_EXECUTE])
+ tmpDir
+ }
+
@Test
void testShouldPrintHelpMessage() {
// Arrange
@@ -175,20 +200,6 @@ class ConfigEncryptionToolTest extends GroovyTestCase {
}
@Test
- void testParseShouldPopulateDefaultBootstrapConfArgument() {
- // Arrange
- String bootstrapPath = "conf/bootstrap.conf"
- ConfigEncryptionTool tool = new ConfigEncryptionTool()
-
- // Act
- tool.parse([] as String[])
- logger.info("Parsed bootstrap.conf location: ${tool.bootstrapConfPath}")
-
- // Assert
- assert new File(tool.bootstrapConfPath).getPath() == new File(bootstrapPath).getPath()
- }
-
- @Test
void testShouldParseNiFiPropertiesArgument() {
// Arrange
def flags = ["-n", "--niFiProperties"]
@@ -202,9 +213,12 @@ class ConfigEncryptionToolTest extends GroovyTestCase {
// Assert
assert tool.niFiPropertiesPath == niFiPropertiesPath
+ assert tool.handlingNiFiProperties
}
}
+ // TODO: Remove as part of NIFI-2655
+ @Ignore("Remove as part of NIFI-2655")
@Test
void testParseShouldPopulateDefaultNiFiPropertiesArgument() {
// Arrange
@@ -228,7 +242,7 @@ class ConfigEncryptionToolTest extends GroovyTestCase {
// Act
flags.each { String arg ->
- tool.parse([arg, niFiPropertiesPath] as String[])
+ tool.parse([arg, niFiPropertiesPath, "-n", niFiPropertiesPath] as String[])
logger.info("Parsed output nifi.properties location: ${tool.outputNiFiPropertiesPath}")
// Assert
@@ -236,6 +250,8 @@ class ConfigEncryptionToolTest extends GroovyTestCase {
}
}
+ // TODO: Remove as part of NIFI-2655
+ @Ignore("Remove as part of NIFI-2655")
@Test
void testParseShouldPopulateDefaultOutputNiFiPropertiesArgument() {
// Arrange
@@ -267,6 +283,91 @@ class ConfigEncryptionToolTest extends GroovyTestCase {
}
@Test
+ void testShouldParseLoginIdentityProvidersArgument() {
+ // Arrange
+ def flags = ["-l", "--loginIdentityProviders"]
+ String loginIdentityProvidersPath = "src/test/resources/login-identity-providers.xml"
+ ConfigEncryptionTool tool = new ConfigEncryptionTool()
+
+ // Act
+ flags.each { String arg ->
+ tool.parse([arg, loginIdentityProvidersPath] as String[])
+ logger.info("Parsed login-identity-providers.xml location: ${tool.loginIdentityProvidersPath}")
+
+ // Assert
+ assert tool.loginIdentityProvidersPath == loginIdentityProvidersPath
+ assert tool.handlingLoginIdentityProviders
+ }
+ }
+
+ // TODO: Remove as part of NIFI-2655
+ @Ignore("Remove as part of NIFI-2655")
+ @Test
+ void testParseShouldPopulateDefaultLoginIdentityProvidersArgument() {
+ // Arrange
+ String loginIdentityProvidersPath = "conf/login-identity-providers.xml"
+ ConfigEncryptionTool tool = new ConfigEncryptionTool()
+
+ // Act
+ tool.parse([] as String[])
+ logger.info("Parsed login-identity-providers.xml location: ${tool.loginIdentityProvidersPath}")
+
+ // Assert
+ assert new File(tool.loginIdentityProvidersPath).getPath() == new File(loginIdentityProvidersPath).getPath()
+ }
+
+ @Test
+ void testShouldParseOutputLoginIdentityProvidersArgument() {
+ // Arrange
+ def flags = ["-i", "--outputLoginIdentityProviders"]
+ String loginIdentityProvidersPath = "src/test/resources/login-identity-providers.xml"
+ ConfigEncryptionTool tool = new ConfigEncryptionTool()
+
+ // Act
+ flags.each { String arg ->
+ tool.parse([arg, loginIdentityProvidersPath, "-l", loginIdentityProvidersPath] as String[])
+ logger.info("Parsed output login-identity-providers.xml location: ${tool.outputLoginIdentityProvidersPath}")
+
+ // Assert
+ assert tool.outputLoginIdentityProvidersPath == loginIdentityProvidersPath
+ }
+ }
+
+ // TODO: Remove as part of NIFI-2655
+ @Ignore("Remove as part of NIFI-2655")
+ @Test
+ void testParseShouldPopulateDefaultOutputLoginIdentityProvidersArgument() {
+ // Arrange
+ String loginIdentityProvidersPath = "conf/login-identity-providers.xml"
+ ConfigEncryptionTool tool = new ConfigEncryptionTool()
+
+ // Act
+ tool.parse([] as String[])
+ logger.info("Parsed output login-identity-providers.xml location: ${tool.outputLoginIdentityProvidersPath}")
+
+ // Assert
+ assert new File(tool.outputLoginIdentityProvidersPath).getPath() == new File(loginIdentityProvidersPath).getPath()
+ }
+
+ @Test
+ void testParseShouldWarnIfLoginIdentityProvidersWillBeOverwritten() {
+ // Arrange
+ String loginIdentityProvidersPath = "conf/login-identity-providers.xml"
+ ConfigEncryptionTool tool = new ConfigEncryptionTool()
+
+ // Act
+ tool.parse("-l ${loginIdentityProvidersPath} -i ${loginIdentityProvidersPath}".split(" ") as String[])
+ logger.info("Parsed login-identity-providers.xml location: ${tool.loginIdentityProvidersPath}")
+ logger.info("Parsed output login-identity-providers.xml location: ${tool.outputLoginIdentityProvidersPath}")
+
+ // Assert
+ assert !TestAppender.events.isEmpty()
+ assert TestAppender.events.any {
+ it.message =~ "The source login-identity-providers.xml and destination login-identity-providers.xml are identical \\[.*\\] so the original will be overwritten"
+ }
+ }
+
+ @Test
void testShouldParseKeyArgument() {
// Arrange
def flags = ["-k", "--key"]
@@ -294,7 +395,7 @@ class ConfigEncryptionToolTest extends GroovyTestCase {
logger.expected(msg)
// Assert
- assert msg =~ "Only one of oldPassword and oldKey can be used"
+ assert msg =~ "Only one of '-w'/'--oldPassword' and '-e'/'--oldKey' can be used"
}
@Test
@@ -307,13 +408,14 @@ class ConfigEncryptionToolTest extends GroovyTestCase {
// Act
argStrings.each { String argString ->
+ argString += " -n any/path"
def msg = shouldFail {
tool.parse(argString.split(" ") as String[])
}
logger.expected(msg)
// Assert
- assert msg == "oldPassword and oldKey are ignored unless migrate is enabled"
+ assert msg == "'-w'/'--oldPassword' and '-e'/'--oldKey' are ignored unless '-m'/'--migrate' is enabled"
}
}
@@ -597,7 +699,7 @@ class ConfigEncryptionToolTest extends GroovyTestCase {
@Test
void testShouldHandleKeyAndPasswordFlag() {
// Arrange
- def args = ["-k", KEY_HEX, "-p", PASSWORD]
+ def args = ["-k", KEY_HEX, "-p", PASSWORD, "-n", ""]
logger.info("Using args: ${args}")
// Act
@@ -607,7 +709,7 @@ class ConfigEncryptionToolTest extends GroovyTestCase {
logger.expected(msg)
// Assert
- assert msg == "Only one of password and key can be used"
+ assert msg == "Only one of '-p'/'--password' and '-k'/'--key' can be used"
}
@Test
@@ -1652,6 +1754,7 @@ class ConfigEncryptionToolTest extends GroovyTestCase {
exit.checkAssertionAfterwards(new Assertion() {
public void checkAssertion() {
+ assert outputPropertiesFile.exists()
final List<String> updatedPropertiesLines = outputPropertiesFile.readLines()
logger.info("Updated nifi.properties:")
logger.info("\n" * 2 + updatedPropertiesLines.join("\n"))
@@ -1751,6 +1854,627 @@ class ConfigEncryptionToolTest extends GroovyTestCase {
// Assertions in common method above
}
+
+ @Test
+ void testShouldDecryptLoginIdentityProviders() {
+ // Arrange
+ String loginIdentityProvidersPath = "src/test/resources/login-identity-providers-populated-encrypted.xml"
+ File loginIdentityProvidersFile = new File(loginIdentityProvidersPath)
+
+ File tmpDir = setupTmpDir()
+
+ File workingFile = new File("target/tmp/tmp-login-identity-providers.xml")
+ workingFile.delete()
+ Files.copy(loginIdentityProvidersFile.toPath(), workingFile.toPath())
+ ConfigEncryptionTool tool = new ConfigEncryptionTool()
+
+ // Sanity check for decryption
+ String cipherText = "q4r7WIgN0MaxdAKM||SGgdCTPGSFEcuH4RraMYEdeyVbOx93abdWTVSWvh1w+klA"
+ String EXPECTED_PASSWORD = "thisIsABadPassword"
+ AESSensitivePropertyProvider spp = new AESSensitivePropertyProvider(KEY_HEX_128)
+ assert spp.unprotect(cipherText) == EXPECTED_PASSWORD
+
+ tool.keyHex = KEY_HEX_128
+
+ def lines = workingFile.readLines()
+ logger.info("Read lines: \n${lines.join("\n")}")
+
+ // Act
+ def decryptedLines = tool.decryptLoginIdentityProviders(lines.join("\n")).split("\n")
+ logger.info("Decrypted lines: \n${decryptedLines.join("\n")}")
+
+ // Assert
+ def passwordLines = decryptedLines.findAll { it =~ PASSWORD_PROP_REGEX }
+ assert passwordLines.size() == LIP_PASSWORD_LINE_COUNT
+ assert passwordLines.every { it =~ ">thisIsABadPassword<" }
+ // Some lines were not encrypted originally so the encryption attribute would not have been updated
+ assert passwordLines.any { it =~ "encryption=\"none\"" }
+ }
+
+ @Test
+ void testShouldDecryptLoginIdentityProvidersWithMultilineElements() {
+ // Arrange
+ String loginIdentityProvidersPath = "src/test/resources/login-identity-providers-populated-encrypted-multiline.xml"
+ File loginIdentityProvidersFile = new File(loginIdentityProvidersPath)
+
+ File tmpDir = setupTmpDir()
+
+ File workingFile = new File("target/tmp/tmp-login-identity-providers.xml")
+ workingFile.delete()
+ Files.copy(loginIdentityProvidersFile.toPath(), workingFile.toPath())
+ ConfigEncryptionTool tool = new ConfigEncryptionTool()
+ tool.isVerbose = true
+
+ tool.keyHex = KEY_HEX_128
+
+ def lines = workingFile.readLines()
+ logger.info("Read lines: \n${lines.join("\n")}")
+
+ // Act
+ def decryptedLines = tool.decryptLoginIdentityProviders(lines.join("\n")).split("\n")
+ logger.info("Decrypted lines: \n${decryptedLines.join("\n")}")
+
+ // Assert
+ def passwordLines = decryptedLines.findAll { it =~ PASSWORD_PROP_REGEX }
+ assert passwordLines.size() == LIP_PASSWORD_LINE_COUNT
+ assert passwordLines.every { it =~ ">thisIsABadPassword<" }
+ // Some lines were not encrypted originally so the encryption attribute would not have been updated
+ assert passwordLines.any { it =~ "encryption=\"none\"" }
+ }
+
+ @Test
+ void testShouldDecryptLoginIdentityProvidersWithMultipleElementsPerLine() {
+ // Arrange
+ String loginIdentityProvidersPath = "src/test/resources/login-identity-providers-populated-encrypted-multiple-per-line.xml"
+ File loginIdentityProvidersFile = new File(loginIdentityProvidersPath)
+
+ File tmpDir = setupTmpDir()
+
+ File workingFile = new File("target/tmp/tmp-login-identity-providers.xml")
+ workingFile.delete()
+ Files.copy(loginIdentityProvidersFile.toPath(), workingFile.toPath())
+ ConfigEncryptionTool tool = new ConfigEncryptionTool()
+ tool.isVerbose = true
+
+ tool.keyHex = KEY_HEX_128
+
+ def lines = workingFile.readLines()
+ logger.info("Read lines: \n${lines.join("\n")}")
+
+ // Act
+ def decryptedLines = tool.decryptLoginIdentityProviders(lines.join("\n")).split("\n")
+ logger.info("Decrypted lines: \n${decryptedLines.join("\n")}")
+
+ // Assert
+ def passwordLines = decryptedLines.findAll { it =~ PASSWORD_PROP_REGEX }
+ assert passwordLines.size() == LIP_PASSWORD_LINE_COUNT
+ assert passwordLines.every { it =~ ">thisIsABadPassword<" }
+ // Some lines were not encrypted originally so the encryption attribute would not have been updated
+ assert passwordLines.any { it =~ "encryption=\"none\"" }
+ }
+
+
+ @Test
+ void testDecryptLoginIdentityProvidersShouldHandleCommentedElements() {
+ // Arrange
+ String loginIdentityProvidersPath = "src/test/resources/login-identity-providers-commented.xml"
+ File loginIdentityProvidersFile = new File(loginIdentityProvidersPath)
+
+ File tmpDir = setupTmpDir()
+
+ File workingFile = new File("target/tmp/tmp-login-identity-providers.xml")
+ workingFile.delete()
+ Files.copy(loginIdentityProvidersFile.toPath(), workingFile.toPath())
+ ConfigEncryptionTool tool = new ConfigEncryptionTool()
+ tool.isVerbose = true
+
+ tool.keyHex = KEY_HEX_128
+
+ def lines = workingFile.readLines()
+ logger.info("Read lines: \n${lines.join("\n")}")
+
+ // Act
+ def decryptedLines = tool.decryptLoginIdentityProviders(lines.join("\n")).split("\n")
+ logger.info("Decrypted lines: \n${decryptedLines.join("\n")}")
+
+ // Assert
+
+ // If no encrypted properties are found, the original input text is just returned (comments and formatting in tact)
+ assert decryptedLines == lines
+ }
+
+ @Test
+ void testShouldEncryptLoginIdentityProviders() {
+ // Arrange
+ String loginIdentityProvidersPath = "src/test/resources/login-identity-providers-populated.xml"
+ File loginIdentityProvidersFile = new File(loginIdentityProvidersPath)
+
+ File tmpDir = setupTmpDir()
+
+ File workingFile = new File("target/tmp/tmp-login-identity-providers.xml")
+ workingFile.delete()
+ Files.copy(loginIdentityProvidersFile.toPath(), workingFile.toPath())
+ ConfigEncryptionTool tool = new ConfigEncryptionTool()
+ tool.isVerbose = true
+
+ tool.keyHex = KEY_HEX
+ String encryptionScheme = "encryption=\"aes/gcm/${getKeyLength(KEY_HEX)}\""
+
+ def lines = workingFile.readLines()
+ logger.info("Read lines: \n${lines.join("\n")}")
+
+ AESSensitivePropertyProvider spp = new AESSensitivePropertyProvider(KEY_HEX)
+
+ // Act
+ def encryptedLines = tool.encryptLoginIdentityProviders(lines.join("\n")).split("\n")
+ logger.info("Encrypted lines: \n${encryptedLines.join("\n")}")
+
+ // Assert
+ def passwordLines = encryptedLines.findAll { it =~ PASSWORD_PROP_REGEX }
+ assert passwordLines.size() == LIP_PASSWORD_LINE_COUNT
+ assert passwordLines.every { !it.contains(">thisIsABadPassword<") }
+ assert passwordLines.every { it.contains(encryptionScheme) }
+ passwordLines.each {
+ String ct = (it =~ ">(.*)</property>")[0][1]
+ logger.info("Cipher text: ${ct}")
+ assert spp.unprotect(ct) == PASSWORD
+ }
+ }
+
+ @Test
+ void testShouldEncryptLoginIdentityProvidersWithEmptySensitiveElements() {
+ // Arrange
+ String loginIdentityProvidersPath = "src/test/resources/login-identity-providers-populated-empty.xml"
+ File loginIdentityProvidersFile = new File(loginIdentityProvidersPath)
+
+ File tmpDir = setupTmpDir()
+
+ File workingFile = new File("target/tmp/tmp-login-identity-providers.xml")
+ workingFile.delete()
+ Files.copy(loginIdentityProvidersFile.toPath(), workingFile.toPath())
+ ConfigEncryptionTool tool = new ConfigEncryptionTool()
+ tool.isVerbose = true
+
+ tool.keyHex = KEY_HEX
+ String encryptionScheme = "encryption=\"aes/gcm/${getKeyLength(KEY_HEX)}\""
+
+ def lines = workingFile.readLines()
+ logger.info("Read lines: \n${lines.join("\n")}")
+
+ AESSensitivePropertyProvider spp = new AESSensitivePropertyProvider(KEY_HEX)
+
+ // Act
+ def encryptedLines = tool.encryptLoginIdentityProviders(lines.join("\n")).split("\n")
+ logger.info("Encrypted lines: \n${encryptedLines.join("\n")}")
+
+ // Assert
+ def passwordLines = encryptedLines.findAll { it =~ PASSWORD_PROP_REGEX }
+ assert passwordLines.size() == LIP_PASSWORD_LINE_COUNT
+ def populatedPasswordLines = passwordLines.findAll { it.contains(">.*<") }
+ assert populatedPasswordLines.every { !it.contains(">thisIsABadPassword<") }
+ assert populatedPasswordLines.every { it.contains(encryptionScheme) }
+ populatedPasswordLines.each {
+ String ct = (it =~ ">(.*)</property>")[0][1]
+ logger.info("Cipher text: ${ct}")
+ assert spp.unprotect(ct) == PASSWORD
+ }
+ }
+
+ @Test
+ void testShouldEncryptLoginIdentityProvidersWithMultilineElements() {
+ // Arrange
+ String loginIdentityProvidersPath = "src/test/resources/login-identity-providers-populated-multiline.xml"
+ File loginIdentityProvidersFile = new File(loginIdentityProvidersPath)
+
+ File tmpDir = setupTmpDir()
+
+ File workingFile = new File("target/tmp/tmp-login-identity-providers.xml")
+ workingFile.delete()
+ Files.copy(loginIdentityProvidersFile.toPath(), workingFile.toPath())
+ ConfigEncryptionTool tool = new ConfigEncryptionTool()
+ tool.isVerbose = true
+
+ tool.keyHex = KEY_HEX
+ String encryptionScheme = "encryption=\"aes/gcm/${getKeyLength(KEY_HEX)}\""
+
+ def lines = workingFile.readLines()
+ logger.info("Read lines: \n${lines.join("\n")}")
+
+ AESSensitivePropertyProvider spp = new AESSensitivePropertyProvider(KEY_HEX)
+
+ // Act
+ def encryptedLines = tool.encryptLoginIdentityProviders(lines.join("\n")).split("\n")
+ logger.info("Encrypted lines: \n${encryptedLines.join("\n")}")
+
+ // Assert
+ def passwordLines = encryptedLines.findAll { it =~ PASSWORD_PROP_REGEX }
+ assert passwordLines.size() == LIP_PASSWORD_LINE_COUNT
+ assert passwordLines.every { !it.contains(">thisIsABadPassword<") }
+ assert passwordLines.every { it.contains(encryptionScheme) }
+ passwordLines.each {
+ String ct = (it =~ ">(.*)</property>")[0][1]
+ logger.info("Cipher text: ${ct}")
+ assert spp.unprotect(ct) == PASSWORD
+ }
+ }
+
+ @Test
+ void testShouldEncryptLoginIdentityProvidersWithMultipleElementsPerLine() {
+ // Arrange
+ String loginIdentityProvidersPath = "src/test/resources/login-identity-providers-populated-multiple-per-line.xml"
+ File loginIdentityProvidersFile = new File(loginIdentityProvidersPath)
+
+ File tmpDir = setupTmpDir()
+
+ File workingFile = new File("target/tmp/tmp-login-identity-providers.xml")
+ workingFile.delete()
+ Files.copy(loginIdentityProvidersFile.toPath(), workingFile.toPath())
+ ConfigEncryptionTool tool = new ConfigEncryptionTool()
+ tool.isVerbose = true
+
+ tool.keyHex = KEY_HEX
+ String encryptionScheme = "encryption=\"aes/gcm/${getKeyLength(KEY_HEX)}\""
+
+ def lines = workingFile.readLines()
+ logger.info("Read lines: \n${lines.join("\n")}")
+
+ AESSensitivePropertyProvider spp = new AESSensitivePropertyProvider(KEY_HEX)
+
+ // Act
+ def encryptedLines = tool.encryptLoginIdentityProviders(lines.join("\n")).split("\n")
+ logger.info("Encrypted lines: \n${encryptedLines.join("\n")}")
+
+ // Assert
+ def passwordLines = encryptedLines.findAll { it =~ PASSWORD_PROP_REGEX }
+ assert passwordLines.size() == LIP_PASSWORD_LINE_COUNT
+ assert passwordLines.every { !it.contains(">thisIsABadPassword<") }
+ assert passwordLines.every { it.contains(encryptionScheme) }
+ passwordLines.each {
+ String ct = (it =~ ">(.*)</property>")[0][1]
+ logger.info("Cipher text: ${ct}")
+ assert spp.unprotect(ct) == PASSWORD
+ }
+ }
+
+ @Test
+ void testEncryptLoginIdentityProvidersShouldHandleCommentedElements() {
+ // Arrange
+ String loginIdentityProvidersPath = "src/test/resources/login-identity-providers-commented.xml"
+ File loginIdentityProvidersFile = new File(loginIdentityProvidersPath)
+
+ File tmpDir = setupTmpDir()
+
+ File workingFile = new File("target/tmp/tmp-login-identity-providers.xml")
+ workingFile.delete()
+ Files.copy(loginIdentityProvidersFile.toPath(), workingFile.toPath())
+ ConfigEncryptionTool tool = new ConfigEncryptionTool()
+ tool.isVerbose = true
+
+ tool.keyHex = KEY_HEX_128
+
+ def lines = workingFile.readLines()
+ logger.info("Read lines: \n${lines.join("\n")}")
+
+ // Act
+ def encryptedLines = tool.encryptLoginIdentityProviders(lines.join("\n")).split("\n")
+ logger.info("Encrypted lines: \n${encryptedLines.join("\n")}")
+
+ // Assert
+
+ // If no sensitive properties are found, the original input text is just returned (comments and formatting in tact)
+ assert encryptedLines == lines
+ }
+
+ @Test
+ void testShouldPerformFullOperationForLoginIdentityProviders() {
+ // Arrange
+ exit.expectSystemExitWithStatus(0)
+
+ File tmpDir = setupTmpDir()
+
+ File emptyKeyFile = new File("src/test/resources/bootstrap_with_empty_master_key.conf")
+ File bootstrapFile = new File("target/tmp/tmp_bootstrap.conf")
+ bootstrapFile.delete()
+
+ Files.copy(emptyKeyFile.toPath(), bootstrapFile.toPath())
+ final List<String> originalBootstrapLines = bootstrapFile.readLines()
+ String originalKeyLine = originalBootstrapLines.find {
+ it.startsWith(ConfigEncryptionTool.BOOTSTRAP_KEY_PREFIX)
+ }
+ logger.info("Original key line from bootstrap.conf: ${originalKeyLine}")
+ assert originalKeyLine == ConfigEncryptionTool.BOOTSTRAP_KEY_PREFIX
+
+ final String EXPECTED_KEY_LINE = ConfigEncryptionTool.BOOTSTRAP_KEY_PREFIX + KEY_HEX
+
+ File inputLIPFile = new File("src/test/resources/login-identity-providers-populated.xml")
+ File outputLIPFile = new File("target/tmp/tmp-lip.xml")
+ outputLIPFile.delete()
+
+ String originalXmlContent = inputLIPFile.text
+ logger.info("Original XML content: ${originalXmlContent}")
+
+ String[] args = ["-l", inputLIPFile.path, "-b", bootstrapFile.path, "-i", outputLIPFile.path, "-k", KEY_HEX, "-v"]
+
+ AESSensitivePropertyProvider spp = new AESSensitivePropertyProvider(KEY_HEX)
+
+ exit.checkAssertionAfterwards(new Assertion() {
+ public void checkAssertion() {
+ final String updatedXmlContent = outputLIPFile.text
+ logger.info("Updated XML content: ${updatedXmlContent}")
+
+ // Check that the output values for sensitive properties are not the same as the original (i.e. it was encrypted)
+ def originalParsedXml = new XmlSlurper().parseText(originalXmlContent)
+ def updatedParsedXml = new XmlSlurper().parseText(updatedXmlContent)
+ assert originalParsedXml != updatedParsedXml
+ assert originalParsedXml.'**'.findAll { it.@encryption } != updatedParsedXml.'**'.findAll {
+ it.@encryption
+ }
+
+ def encryptedValues = updatedParsedXml.provider.find {
+ it.identifier == 'ldap-provider'
+ }.property.findAll {
+ it.@name =~ "Password" && it.@encryption =~ "aes/gcm/\\d{3}"
+ }
+
+ encryptedValues.each {
+ assert spp.unprotect(it.text()) == PASSWORD
+ }
+
+ // Check that the key was persisted to the bootstrap.conf
+ final List<String> updatedBootstrapLines = bootstrapFile.readLines()
+ String updatedKeyLine = updatedBootstrapLines.find {
+ it.startsWith(ConfigEncryptionTool.BOOTSTRAP_KEY_PREFIX)
+ }
+ logger.info("Updated key line: ${updatedKeyLine}")
+
+ assert updatedKeyLine == EXPECTED_KEY_LINE
+ assert originalBootstrapLines.size() == updatedBootstrapLines.size()
+
+ // Clean up
+ outputLIPFile.deleteOnExit()
+ bootstrapFile.deleteOnExit()
+ tmpDir.deleteOnExit()
+ }
+ });
+
+ // Act
+ ConfigEncryptionTool.main(args)
+ logger.info("Invoked #main with ${args.join(" ")}")
+
+ // Assert
+
+ // Assertions defined above
+ }
+
+ @Test
+ void testShouldPerformFullOperationMigratingLoginIdentityProviders() {
+ // Arrange
+ exit.expectSystemExitWithStatus(0)
+
+ File tmpDir = setupTmpDir()
+
+ // Start with 128-bit encryption and go to whatever is supported on this system
+ File emptyKeyFile = new File("src/test/resources/bootstrap_with_master_key_128.conf")
+ File bootstrapFile = new File("target/tmp/tmp_bootstrap.conf")
+ bootstrapFile.delete()
+
+ Files.copy(emptyKeyFile.toPath(), bootstrapFile.toPath())
+ final List<String> originalBootstrapLines = bootstrapFile.readLines()
+ String originalKeyLine = originalBootstrapLines.find {
+ it.startsWith(ConfigEncryptionTool.BOOTSTRAP_KEY_PREFIX)
+ }
+ logger.info("Original key line from bootstrap.conf: ${originalKeyLine}")
+ assert originalKeyLine == ConfigEncryptionTool.BOOTSTRAP_KEY_PREFIX + KEY_HEX_128
+
+ final String EXPECTED_KEY_LINE = ConfigEncryptionTool.BOOTSTRAP_KEY_PREFIX + PASSWORD_KEY_HEX
+
+ File inputLIPFile = new File("src/test/resources/login-identity-providers-populated-encrypted.xml")
+ File outputLIPFile = new File("target/tmp/tmp-lip.xml")
+ outputLIPFile.delete()
+
+ String originalXmlContent = inputLIPFile.text
+ logger.info("Original XML content: ${originalXmlContent}")
+
+ // Migrate from KEY_HEX_128 to PASSWORD_KEY_HEX
+ String[] args = ["-l", inputLIPFile.path, "-b", bootstrapFile.path, "-i", outputLIPFile.path, "-m", "-e", KEY_HEX_128, "-k", PASSWORD_KEY_HEX, "-v"]
+
+ AESSensitivePropertyProvider spp = new AESSensitivePropertyProvider(PASSWORD_KEY_HEX)
+
+ exit.checkAssertionAfterwards(new Assertion() {
+ public void checkAssertion() {
+ final String updatedXmlContent = outputLIPFile.text
+ logger.info("Updated XML content: ${updatedXmlContent}")
+
+ // Check that the output values for sensitive properties are not the same as the original (i.e. it was encrypted)
+ def originalParsedXml = new XmlSlurper().parseText(originalXmlContent)
+ def updatedParsedXml = new XmlSlurper().parseText(updatedXmlContent)
+ assert originalParsedXml != updatedParsedXml
+// assert originalParsedXml.'**'.findAll { it.@encryption } != updatedParsedXml.'**'.findAll { it.@encryption }
+
+ def encryptedValues = updatedParsedXml.provider.find {
+ it.identifier == 'ldap-provider'
+ }.property.findAll {
+ it.@name =~ "Password" && it.@encryption =~ "aes/gcm/\\d{3}"
+ }
+
+ encryptedValues.each {
+ assert spp.unprotect(it.text()) == PASSWORD
+ }
+
+ // Check that the key was persisted to the bootstrap.conf
+ final List<String> updatedBootstrapLines = bootstrapFile.readLines()
+ String updatedKeyLine = updatedBootstrapLines.find {
+ it.startsWith(ConfigEncryptionTool.BOOTSTRAP_KEY_PREFIX)
+ }
+ logger.info("Updated key line: ${updatedKeyLine}")
+
+ assert updatedKeyLine == EXPECTED_KEY_LINE
+ assert originalBootstrapLines.size() == updatedBootstrapLines.size()
+
+ // Clean up
+ outputLIPFile.deleteOnExit()
+ bootstrapFile.deleteOnExit()
+ tmpDir.deleteOnExit()
+ }
+ });
+
+ // Act
+ ConfigEncryptionTool.main(args)
+ logger.info("Invoked #main with ${args.join(" ")}")
+
+ // Assert
+
+ // Assertions defined above
+ }
+
+ @Test
+ void testSerializeLoginIdentityProvidersAndPreserveFormatShouldRespectComments() {
+ // Arrange
+ String loginIdentityProvidersPath = "src/test/resources/login-identity-providers-populated.xml"
+ File loginIdentityProvidersFile = new File(loginIdentityProvidersPath)
+
+ File tmpDir = setupTmpDir()
+
+ File workingFile = new File("target/tmp/tmp-login-identity-providers.xml")
+ workingFile.delete()
+ Files.copy(loginIdentityProvidersFile.toPath(), workingFile.toPath())
+ ConfigEncryptionTool tool = new ConfigEncryptionTool()
+ tool.isVerbose = true
+
+ // Just need to read the lines from the original file, parse them to XML, serialize back, and compare output, as no transformation operation will occur
+ def lines = workingFile.readLines()
+ logger.info("Read lines: \n${lines.join("\n")}")
+
+ String plainXml = workingFile.text
+ String encryptedXml = tool.encryptLoginIdentityProviders(plainXml, KEY_HEX)
+ logger.info("Encrypted XML: \n${encryptedXml}")
+
+ // Act
+ def serializedLines = tool.serializeLoginIdentityProvidersAndPreserveFormat(encryptedXml, workingFile)
+ logger.info("Serialized lines: \n${serializedLines.join("\n")}")
+
+ // Assert
+
+ // Some empty lines will be removed
+ def trimmedLines = lines.collect {it.trim() }.findAll { it }
+ def trimmedSerializedLines = serializedLines.collect { it.trim() }.findAll { it }
+ assert trimmedLines.size() == trimmedSerializedLines.size()
+ }
+
+ @Test
+ void testShouldPerformFullOperationForNiFiPropertiesAndLoginIdentityProviders() {
+ // Arrange
+ exit.expectSystemExitWithStatus(0)
+
+ File tmpDir = setupTmpDir()
+
+ File emptyKeyFile = new File("src/test/resources/bootstrap_with_empty_master_key.conf")
+ File bootstrapFile = new File("target/tmp/tmp_bootstrap.conf")
+ bootstrapFile.delete()
+
+ Files.copy(emptyKeyFile.toPath(), bootstrapFile.toPath())
+ final List<String> originalBootstrapLines = bootstrapFile.readLines()
+ String originalKeyLine = originalBootstrapLines.find {
+ it.startsWith(ConfigEncryptionTool.BOOTSTRAP_KEY_PREFIX)
+ }
+ logger.info("Original key line from bootstrap.conf: ${originalKeyLine}")
+ assert originalKeyLine == ConfigEncryptionTool.BOOTSTRAP_KEY_PREFIX
+
+ final String EXPECTED_KEY_LINE = ConfigEncryptionTool.BOOTSTRAP_KEY_PREFIX + KEY_HEX
+
+ // Set up the NFP file
+ File inputPropertiesFile = new File("src/test/resources/nifi_with_sensitive_properties_unprotected.properties")
+ File outputPropertiesFile = new File("target/tmp/tmp_nifi.properties")
+ outputPropertiesFile.delete()
+
+ NiFiProperties inputProperties = new NiFiPropertiesLoader().load(inputPropertiesFile)
+ logger.info("Loaded ${inputProperties.size()} properties from input file")
+ ProtectedNiFiProperties protectedInputProperties = new ProtectedNiFiProperties(inputProperties)
+ def originalSensitiveValues = protectedInputProperties.getSensitivePropertyKeys().collectEntries { String key -> [(key): protectedInputProperties.getProperty(key)] }
+ logger.info("Original sensitive values: ${originalSensitiveValues}")
+
+ // Set up the LIP file
+ File inputLIPFile = new File("src/test/resources/login-identity-providers-populated.xml")
+ File outputLIPFile = new File("target/tmp/tmp-lip.xml")
+ outputLIPFile.delete()
+
+ String originalXmlContent = inputLIPFile.text
+ logger.info("Original XML content: ${originalXmlContent}")
+
+ String[] args = ["-n", inputPropertiesFile.path, "-l", inputLIPFile.path, "-b", bootstrapFile.path, "-i", outputLIPFile.path, "-o", outputPropertiesFile.path, "-k", KEY_HEX, "-v"]
+
+ AESSensitivePropertyProvider spp = new AESSensitivePropertyProvider(KEY_HEX)
+
+ exit.checkAssertionAfterwards(new Assertion() {
+ public void checkAssertion() {
+ final List<String> updatedPropertiesLines = outputPropertiesFile.readLines()
+ logger.info("Updated nifi.properties:")
+ logger.info("\n" * 2 + updatedPropertiesLines.join("\n"))
+
+ // Check that the output values for sensitive properties are not the same as the original (i.e. it was encrypted)
+ NiFiProperties updatedProperties = new NiFiPropertiesLoader().readProtectedPropertiesFromDisk(outputPropertiesFile)
+ assert updatedProperties.size() >= inputProperties.size()
+ originalSensitiveValues.every { String key, String originalValue ->
+ assert updatedProperties.getProperty(key) != originalValue
+ }
+
+ // Check that the new NiFiProperties instance matches the output file (values still encrypted)
+ updatedProperties.getPropertyKeys().every { String key ->
+ assert updatedPropertiesLines.contains("${key}=${updatedProperties.getProperty(key)}".toString())
+ }
+
+ final String updatedXmlContent = outputLIPFile.text
+ logger.info("Updated XML content: ${updatedXmlContent}")
+
+ // Check that the output values for sensitive properties are not the same as the original (i.e. it was encrypted)
+ def originalParsedXml = new XmlSlurper().parseText(originalXmlContent)
+ def updatedParsedXml = new XmlSlurper().parseText(updatedXmlContent)
+ assert originalParsedXml != updatedParsedXml
+ assert originalParsedXml.'**'.findAll { it.@encryption } != updatedParsedXml.'**'.findAll {
+ it.@encryption
+ }
+
+ def encryptedValues = updatedParsedXml.provider.find {
+ it.identifier == 'ldap-provider'
+ }.property.findAll {
+ it.@name =~ "Password" && it.@encryption =~ "aes/gcm/\\d{3}"
+ }
+
+ encryptedValues.each {
+ assert spp.unprotect(it.text()) == PASSWORD
+ }
+
+ // Check that the comments are still there
+ def trimmedLines = inputLIPFile.readLines().collect {it.trim() }.findAll { it }
+ def trimmedSerializedLines = updatedXmlContent.split("\n").collect { it.trim() }.findAll { it }
+ assert trimmedLines.size() == trimmedSerializedLines.size()
+
+ // Check that the key was persisted to the bootstrap.conf
+ final List<String> updatedBootstrapLines = bootstrapFile.readLines()
+ String updatedKeyLine = updatedBootstrapLines.find {
+ it.startsWith(ConfigEncryptionTool.BOOTSTRAP_KEY_PREFIX)
+ }
+ logger.info("Updated key line: ${updatedKeyLine}")
+
+ assert updatedKeyLine == EXPECTED_KEY_LINE
+ assert originalBootstrapLines.size() == updatedBootstrapLines.size()
+
+ // Clean up
+ outputPropertiesFile.deleteOnExit()
+ outputLIPFile.deleteOnExit()
+ bootstrapFile.deleteOnExit()
+ tmpDir.deleteOnExit()
+ }
+ });
+
+ // Act
+ ConfigEncryptionTool.main(args)
+ logger.info("Invoked #main with ${args.join(" ")}")
+
+ // Assert
+
+ // Assertions defined above
+ }
}
public class TestAppender extends AppenderBase<LoggingEvent> {
http://git-wip-us.apache.org/repos/asf/nifi/blob/59fea1cb/nifi-toolkit/nifi-toolkit-encrypt-config/src/test/resources/bootstrap_with_master_key_128.conf
----------------------------------------------------------------------
diff --git a/nifi-toolkit/nifi-toolkit-encrypt-config/src/test/resources/bootstrap_with_master_key_128.conf b/nifi-toolkit/nifi-toolkit-encrypt-config/src/test/resources/bootstrap_with_master_key_128.conf
new file mode 100644
index 0000000..ae994de
--- /dev/null
+++ b/nifi-toolkit/nifi-toolkit-encrypt-config/src/test/resources/bootstrap_with_master_key_128.conf
@@ -0,0 +1,74 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+# Java command to use when running NiFi
+java=java
+
+# Username to use when running NiFi. This value will be ignored on Windows.
+run.as=
+
+# Configure where NiFi's lib and conf directories live
+lib.dir=./lib
+conf.dir=./conf
+
+# How long to wait after telling NiFi to shutdown before explicitly killing the Process
+graceful.shutdown.seconds=20
+
+# Disable JSR 199 so that we can use JSP's without running a JDK
+java.arg.1=-Dorg.apache.jasper.compiler.disablejsr199=true
+
+# JVM memory settings
+java.arg.2=-Xms512m
+java.arg.3=-Xmx512m
+
+# Enable Remote Debugging
+#java.arg.debug=-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=8000
+
+java.arg.4=-Djava.net.preferIPv4Stack=true
+
+# allowRestrictedHeaders is required for Cluster/Node communications to work properly
+java.arg.5=-Dsun.net.http.allowRestrictedHeaders=true
+java.arg.6=-Djava.protocol.handler.pkgs=sun.net.www.protocol
+
+# The G1GC is still considered experimental but has proven to be very advantageous in providing great
+# performance without significant "stop-the-world" delays.
+java.arg.13=-XX:+UseG1GC
+
+#Set headless mode by default
+java.arg.14=-Djava.awt.headless=true
+
+# Master key in hexadecimal format for encrypted sensitive configuration values
+nifi.bootstrap.sensitive.key=0123456789ABCDEFFEDCBA9876543210
+
+###
+# Notification Services for notifying interested parties when NiFi is stopped, started, dies
+###
+
+# XML File that contains the definitions of the notification services
+notification.services.file=./conf/bootstrap-notification-services.xml
+
+# In the case that we are unable to send a notification for an event, how many times should we retry?
+notification.max.attempts=5
+
+# Comma-separated list of identifiers that are present in the notification.services.file; which services should be used to notify when NiFi is started?
+#nifi.start.notification.services=email-notification
+
+# Comma-separated list of identifiers that are present in the notification.services.file; which services should be used to notify when NiFi is stopped?
+#nifi.stop.notification.services=email-notification
+
+# Comma-separated list of identifiers that are present in the notification.services.file; which services should be used to notify when NiFi dies?
+#nifi.dead.notification.services=email-notification
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/nifi/blob/59fea1cb/nifi-toolkit/nifi-toolkit-encrypt-config/src/test/resources/login-identity-providers-commented-populated.xml
----------------------------------------------------------------------
diff --git a/nifi-toolkit/nifi-toolkit-encrypt-config/src/test/resources/login-identity-providers-commented-populated.xml b/nifi-toolkit/nifi-toolkit-encrypt-config/src/test/resources/login-identity-providers-commented-populated.xml
new file mode 100644
index 0000000..53f5736
--- /dev/null
+++ b/nifi-toolkit/nifi-toolkit-encrypt-config/src/test/resources/login-identity-providers-commented-populated.xml
@@ -0,0 +1,107 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+ http://www.apache.org/licenses/LICENSE-2.0
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<!--
+ This file lists the login identity providers to use when running securely. In order
+ to use a specific provider it must be configured here and it's identifier
+ must be specified in the nifi.properties file.
+-->
+<loginIdentityProviders>
+ <!--
+ Identity Provider for users logging in with username/password against an LDAP server.
+
+ 'Authentication Strategy' - How the connection to the LDAP server is authenticated. Possible
+ values are ANONYMOUS, SIMPLE, or START_TLS.
+
+ 'Manager DN' - The DN of the manager that is used to bind to the LDAP server to search for users.
+ 'Manager Password' - The password of the manager that is used to bind to the LDAP server to
+ search for users.
+
+ 'TLS - Keystore' - Path to the Keystore that is used when connecting to LDAP using START_TLS.
+ 'TLS - Keystore Password' - Password for the Keystore that is used when connecting to LDAP
+ using START_TLS.
+ 'TLS - Keystore Type' - Type of the Keystore that is used when connecting to LDAP using
+ START_TLS (i.e. JKS or PKCS12).
+ 'TLS - Truststore' - Path to the Truststore that is used when connecting to LDAP using START_TLS.
+ 'TLS - Truststore Password' - Password for the Truststore that is used when connecting to
+ LDAP using START_TLS.
+ 'TLS - Truststore Type' - Type of the Truststore that is used when connecting to LDAP using
+ START_TLS (i.e. JKS or PKCS12).
+ 'TLS - Client Auth' - Client authentication policy when connecting to LDAP using START_TLS.
+ Possible values are REQUIRED, WANT, NONE.
+ 'TLS - Protocol' - Protocol to use when connecting to LDAP using START_TLS. (i.e. TLS,
+ TLSv1.1, TLSv1.2, etc).
+ 'TLS - Shutdown Gracefully' - Specifies whether the TLS should be shut down gracefully
+ before the target context is closed. Defaults to false.
+
+ 'Referral Strategy' - Strategy for handling referrals. Possible values are FOLLOW, IGNORE, THROW.
+ 'Connect Timeout' - Duration of connect timeout. (i.e. 10 secs).
+ 'Read Timeout' - Duration of read timeout. (i.e. 10 secs).
+
+ 'Url' - Url of the LDAP servier (i.e. ldap://<hostname>:<port>).
+ 'User Search Base' - Base DN for searching for users (i.e. CN=Users,DC=example,DC=com).
+ 'User Search Filter' - Filter for searching for users against the 'User Search Base'.
+ (i.e. sAMAccountName={0}). The user specified name is inserted into '{0}'.
+
+ 'Authentication Expiration' - The duration of how long the user authentication is valid
+ for. If the user never logs out, they will be required to log back in following
+ this duration.
+ -->
+ <!-- To enable the ldap-provider remove 2 lines. This is 1 of 2.
+ <provider>
+ <identifier>ldap-provider</identifier>
+ <class>org.apache.nifi.ldap.LdapProvider</class>
+ <property name="Authentication Strategy">START_TLS</property>
+
+ <property name="Manager DN"></property>
+ <property name="Manager Password">thisIsABadPassword</property>
+
+ <property name="TLS - Keystore"></property>
+ <property name="TLS - Keystore Password">thisIsABadPassword</property>
+ <property name="TLS - Keystore Type"></property>
+ <property name="TLS - Truststore"></property>
+ <property name="TLS - Truststore Password">thisIsABadPassword</property>
+ <property name="TLS - Truststore Type"></property>
+ <property name="TLS - Client Auth"></property>
+ <property name="TLS - Protocol"></property>
+ <property name="TLS - Shutdown Gracefully"></property>
+
+ <property name="Referral Strategy">FOLLOW</property>
+ <property name="Connect Timeout">10 secs</property>
+ <property name="Read Timeout">10 secs</property>
+
+ <property name="Url"></property>
+ <property name="User Search Base"></property>
+ <property name="User Search Filter"></property>
+
+ <property name="Authentication Expiration">12 hours</property>
+ </provider>
+ To enable the ldap-provider remove 2 lines. This is 2 of 2. -->
+
+ <!--
+ Identity Provider for users logging in with username/password against a Kerberos KDC server.
+
+ 'Default Realm' - Default realm to provide when user enters incomplete user principal (i.e. NIFI.APACHE.ORG).
+ 'Authentication Expiration' - The duration of how long the user authentication is valid for. If the user never logs out, they will be required to log back in following this duration.
+ -->
+ <!-- To enable the kerberos-provider remove 2 lines. This is 1 of 2.
+ <provider>
+ <identifier>kerberos-provider</identifier>
+ <class>org.apache.nifi.kerberos.KerberosProvider</class>
+ <property name="Default Realm">NIFI.APACHE.ORG</property>
+ <property name="Authentication Expiration">12 hours</property>
+ </provider>
+ To enable the kerberos-provider remove 2 lines. This is 2 of 2. -->
+</loginIdentityProviders>
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/nifi/blob/59fea1cb/nifi-toolkit/nifi-toolkit-encrypt-config/src/test/resources/login-identity-providers-commented.xml
----------------------------------------------------------------------
diff --git a/nifi-toolkit/nifi-toolkit-encrypt-config/src/test/resources/login-identity-providers-commented.xml b/nifi-toolkit/nifi-toolkit-encrypt-config/src/test/resources/login-identity-providers-commented.xml
new file mode 100644
index 0000000..a2beb4c
--- /dev/null
+++ b/nifi-toolkit/nifi-toolkit-encrypt-config/src/test/resources/login-identity-providers-commented.xml
@@ -0,0 +1,107 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+ http://www.apache.org/licenses/LICENSE-2.0
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<!--
+ This file lists the login identity providers to use when running securely. In order
+ to use a specific provider it must be configured here and it's identifier
+ must be specified in the nifi.properties file.
+-->
+<loginIdentityProviders>
+ <!--
+ Identity Provider for users logging in with username/password against an LDAP server.
+
+ 'Authentication Strategy' - How the connection to the LDAP server is authenticated. Possible
+ values are ANONYMOUS, SIMPLE, or START_TLS.
+
+ 'Manager DN' - The DN of the manager that is used to bind to the LDAP server to search for users.
+ 'Manager Password' - The password of the manager that is used to bind to the LDAP server to
+ search for users.
+
+ 'TLS - Keystore' - Path to the Keystore that is used when connecting to LDAP using START_TLS.
+ 'TLS - Keystore Password' - Password for the Keystore that is used when connecting to LDAP
+ using START_TLS.
+ 'TLS - Keystore Type' - Type of the Keystore that is used when connecting to LDAP using
+ START_TLS (i.e. JKS or PKCS12).
+ 'TLS - Truststore' - Path to the Truststore that is used when connecting to LDAP using START_TLS.
+ 'TLS - Truststore Password' - Password for the Truststore that is used when connecting to
+ LDAP using START_TLS.
+ 'TLS - Truststore Type' - Type of the Truststore that is used when connecting to LDAP using
+ START_TLS (i.e. JKS or PKCS12).
+ 'TLS - Client Auth' - Client authentication policy when connecting to LDAP using START_TLS.
+ Possible values are REQUIRED, WANT, NONE.
+ 'TLS - Protocol' - Protocol to use when connecting to LDAP using START_TLS. (i.e. TLS,
+ TLSv1.1, TLSv1.2, etc).
+ 'TLS - Shutdown Gracefully' - Specifies whether the TLS should be shut down gracefully
+ before the target context is closed. Defaults to false.
+
+ 'Referral Strategy' - Strategy for handling referrals. Possible values are FOLLOW, IGNORE, THROW.
+ 'Connect Timeout' - Duration of connect timeout. (i.e. 10 secs).
+ 'Read Timeout' - Duration of read timeout. (i.e. 10 secs).
+
+ 'Url' - Url of the LDAP servier (i.e. ldap://<hostname>:<port>).
+ 'User Search Base' - Base DN for searching for users (i.e. CN=Users,DC=example,DC=com).
+ 'User Search Filter' - Filter for searching for users against the 'User Search Base'.
+ (i.e. sAMAccountName={0}). The user specified name is inserted into '{0}'.
+
+ 'Authentication Expiration' - The duration of how long the user authentication is valid
+ for. If the user never logs out, they will be required to log back in following
+ this duration.
+ -->
+ <!-- To enable the ldap-provider remove 2 lines. This is 1 of 2.
+ <provider>
+ <identifier>ldap-provider</identifier>
+ <class>org.apache.nifi.ldap.LdapProvider</class>
+ <property name="Authentication Strategy">START_TLS</property>
+
+ <property name="Manager DN"></property>
+ <property name="Manager Password"></property>
+
+ <property name="TLS - Keystore"></property>
+ <property name="TLS - Keystore Password"></property>
+ <property name="TLS - Keystore Type"></property>
+ <property name="TLS - Truststore"></property>
+ <property name="TLS - Truststore Password"></property>
+ <property name="TLS - Truststore Type"></property>
+ <property name="TLS - Client Auth"></property>
+ <property name="TLS - Protocol"></property>
+ <property name="TLS - Shutdown Gracefully"></property>
+
+ <property name="Referral Strategy">FOLLOW</property>
+ <property name="Connect Timeout">10 secs</property>
+ <property name="Read Timeout">10 secs</property>
+
+ <property name="Url"></property>
+ <property name="User Search Base"></property>
+ <property name="User Search Filter"></property>
+
+ <property name="Authentication Expiration">12 hours</property>
+ </provider>
+ To enable the ldap-provider remove 2 lines. This is 2 of 2. -->
+
+ <!--
+ Identity Provider for users logging in with username/password against a Kerberos KDC server.
+
+ 'Default Realm' - Default realm to provide when user enters incomplete user principal (i.e. NIFI.APACHE.ORG).
+ 'Authentication Expiration' - The duration of how long the user authentication is valid for. If the user never logs out, they will be required to log back in following this duration.
+ -->
+ <!-- To enable the kerberos-provider remove 2 lines. This is 1 of 2.
+ <provider>
+ <identifier>kerberos-provider</identifier>
+ <class>org.apache.nifi.kerberos.KerberosProvider</class>
+ <property name="Default Realm">NIFI.APACHE.ORG</property>
+ <property name="Authentication Expiration">12 hours</property>
+ </provider>
+ To enable the kerberos-provider remove 2 lines. This is 2 of 2. -->
+</loginIdentityProviders>
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/nifi/blob/59fea1cb/nifi-toolkit/nifi-toolkit-encrypt-config/src/test/resources/login-identity-providers-populated-empty.xml
----------------------------------------------------------------------
diff --git a/nifi-toolkit/nifi-toolkit-encrypt-config/src/test/resources/login-identity-providers-populated-empty.xml b/nifi-toolkit/nifi-toolkit-encrypt-config/src/test/resources/login-identity-providers-populated-empty.xml
new file mode 100644
index 0000000..2a0917d
--- /dev/null
+++ b/nifi-toolkit/nifi-toolkit-encrypt-config/src/test/resources/login-identity-providers-populated-empty.xml
@@ -0,0 +1,105 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+ http://www.apache.org/licenses/LICENSE-2.0
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<!--
+ This file lists the login identity providers to use when running securely. In order
+ to use a specific provider it must be configured here and it's identifier
+ must be specified in the nifi.properties file.
+-->
+<loginIdentityProviders>
+ <!--
+ Identity Provider for users logging in with username/password against an LDAP server.
+
+ 'Authentication Strategy' - How the connection to the LDAP server is authenticated. Possible
+ values are ANONYMOUS, SIMPLE, or START_TLS.
+
+ 'Manager DN' - The DN of the manager that is used to bind to the LDAP server to search for users.
+ 'Manager Password' - The password of the manager that is used to bind to the LDAP server to
+ search for users.
+
+ 'TLS - Keystore' - Path to the Keystore that is used when connecting to LDAP using START_TLS.
+ 'TLS - Keystore Password' - Password for the Keystore that is used when connecting to LDAP
+ using START_TLS.
+ 'TLS - Keystore Type' - Type of the Keystore that is used when connecting to LDAP using
+ START_TLS (i.e. JKS or PKCS12).
+ 'TLS - Truststore' - Path to the Truststore that is used when connecting to LDAP using START_TLS.
+ 'TLS - Truststore Password' - Password for the Truststore that is used when connecting to
+ LDAP using START_TLS.
+ 'TLS - Truststore Type' - Type of the Truststore that is used when connecting to LDAP using
+ START_TLS (i.e. JKS or PKCS12).
+ 'TLS - Client Auth' - Client authentication policy when connecting to LDAP using START_TLS.
+ Possible values are REQUIRED, WANT, NONE.
+ 'TLS - Protocol' - Protocol to use when connecting to LDAP using START_TLS. (i.e. TLS,
+ TLSv1.1, TLSv1.2, etc).
+ 'TLS - Shutdown Gracefully' - Specifies whether the TLS should be shut down gracefully
+ before the target context is closed. Defaults to false.
+
+ 'Referral Strategy' - Strategy for handling referrals. Possible values are FOLLOW, IGNORE, THROW.
+ 'Connect Timeout' - Duration of connect timeout. (i.e. 10 secs).
+ 'Read Timeout' - Duration of read timeout. (i.e. 10 secs).
+
+ 'Url' - Url of the LDAP servier (i.e. ldap://<hostname>:<port>).
+ 'User Search Base' - Base DN for searching for users (i.e. CN=Users,DC=example,DC=com).
+ 'User Search Filter' - Filter for searching for users against the 'User Search Base'.
+ (i.e. sAMAccountName={0}). The user specified name is inserted into '{0}'.
+
+ 'Authentication Expiration' - The duration of how long the user authentication is valid
+ for. If the user never logs out, they will be required to log back in following
+ this duration.
+ -->
+ <provider>
+ <identifier>ldap-provider</identifier>
+ <class>org.apache.nifi.ldap.LdapProvider</class>
+ <property name="Authentication Strategy">START_TLS</property>
+
+ <property name="Manager DN">someuser</property>
+ <property name="Manager Password">thisIsABadPassword</property>
+
+ <property name="TLS - Keystore"></property>
+ <property name="TLS - Keystore Password"></property>
+ <property name="TLS - Keystore Type"></property>
+ <property name="TLS - Truststore"></property>
+ <property name="TLS - Truststore Password"></property>
+ <property name="TLS - Truststore Type"></property>
+ <property name="TLS - Client Auth"></property>
+ <property name="TLS - Protocol"></property>
+ <property name="TLS - Shutdown Gracefully"></property>
+
+ <property name="Referral Strategy">FOLLOW</property>
+ <property name="Connect Timeout">10 secs</property>
+ <property name="Read Timeout">10 secs</property>
+
+ <property name="Url"></property>
+ <property name="User Search Base"></property>
+ <property name="User Search Filter"></property>
+
+ <property name="Authentication Expiration">12 hours</property>
+ </provider>
+
+ <!--
+ Identity Provider for users logging in with username/password against a Kerberos KDC server.
+
+ 'Default Realm' - Default realm to provide when user enters incomplete user principal (i.e. NIFI.APACHE.ORG).
+ 'Authentication Expiration' - The duration of how long the user authentication is valid for. If the user never logs out, they will be required to log back in following this duration.
+ -->
+ <!-- To enable the kerberos-provider remove 2 lines. This is 1 of 2.
+ <provider>
+ <identifier>kerberos-provider</identifier>
+ <class>org.apache.nifi.kerberos.KerberosProvider</class>
+ <property name="Default Realm">NIFI.APACHE.ORG</property>
+ <property name="Authentication Expiration">12 hours</property>
+ </provider>
+ To enable the kerberos-provider remove 2 lines. This is 2 of 2. -->
+</loginIdentityProviders>
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/nifi/blob/59fea1cb/nifi-toolkit/nifi-toolkit-encrypt-config/src/test/resources/login-identity-providers-populated-encrypted-multiline.xml
----------------------------------------------------------------------
diff --git a/nifi-toolkit/nifi-toolkit-encrypt-config/src/test/resources/login-identity-providers-populated-encrypted-multiline.xml b/nifi-toolkit/nifi-toolkit-encrypt-config/src/test/resources/login-identity-providers-populated-encrypted-multiline.xml
new file mode 100644
index 0000000..8c5ade5
--- /dev/null
+++ b/nifi-toolkit/nifi-toolkit-encrypt-config/src/test/resources/login-identity-providers-populated-encrypted-multiline.xml
@@ -0,0 +1,110 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+ http://www.apache.org/licenses/LICENSE-2.0
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<!--
+ This file lists the login identity providers to use when running securely. In order
+ to use a specific provider it must be configured here and it's identifier
+ must be specified in the nifi.properties file.
+-->
+<loginIdentityProviders>
+ <!--
+ Identity Provider for users logging in with username/password against an LDAP server.
+
+ 'Authentication Strategy' - How the connection to the LDAP server is authenticated. Possible
+ values are ANONYMOUS, SIMPLE, or START_TLS.
+
+ 'Manager DN' - The DN of the manager that is used to bind to the LDAP server to search for users.
+ 'Manager Password' - The password of the manager that is used to bind to the LDAP server to
+ search for users.
+
+ 'TLS - Keystore' - Path to the Keystore that is used when connecting to LDAP using START_TLS.
+ 'TLS - Keystore Password' - Password for the Keystore that is used when connecting to LDAP
+ using START_TLS.
+ 'TLS - Keystore Type' - Type of the Keystore that is used when connecting to LDAP using
+ START_TLS (i.e. JKS or PKCS12).
+ 'TLS - Truststore' - Path to the Truststore that is used when connecting to LDAP using START_TLS.
+ 'TLS - Truststore Password' - Password for the Truststore that is used when connecting to
+ LDAP using START_TLS.
+ 'TLS - Truststore Type' - Type of the Truststore that is used when connecting to LDAP using
+ START_TLS (i.e. JKS or PKCS12).
+ 'TLS - Client Auth' - Client authentication policy when connecting to LDAP using START_TLS.
+ Possible values are REQUIRED, WANT, NONE.
+ 'TLS - Protocol' - Protocol to use when connecting to LDAP using START_TLS. (i.e. TLS,
+ TLSv1.1, TLSv1.2, etc).
+ 'TLS - Shutdown Gracefully' - Specifies whether the TLS should be shut down gracefully
+ before the target context is closed. Defaults to false.
+
+ 'Referral Strategy' - Strategy for handling referrals. Possible values are FOLLOW, IGNORE, THROW.
+ 'Connect Timeout' - Duration of connect timeout. (i.e. 10 secs).
+ 'Read Timeout' - Duration of read timeout. (i.e. 10 secs).
+
+ 'Url' - Url of the LDAP servier (i.e. ldap://<hostname>:<port>).
+ 'User Search Base' - Base DN for searching for users (i.e. CN=Users,DC=example,DC=com).
+ 'User Search Filter' - Filter for searching for users against the 'User Search Base'.
+ (i.e. sAMAccountName={0}). The user specified name is inserted into '{0}'.
+
+ 'Authentication Expiration' - The duration of how long the user authentication is valid
+ for. If the user never logs out, they will be required to log back in following
+ this duration.
+ -->
+ <provider>
+ <identifier>ldap-provider</identifier>
+ <class>org.apache.nifi.ldap.LdapProvider</class>
+ <property name="Authentication Strategy">START_TLS</property>
+
+ <property name="Manager DN">someuser</property>
+ <property name="Manager Password" encryption=
+ "aes/gcm/128">q4r7WIgN0MaxdAKM||SGgdCTPGSFEcuH4RraMYEdeyVbOx93abdWTVSWvh1w+klA</property>
+
+ <property name="TLS - Keystore"></property>
+ <property
+ name="TLS - Keystore Password"
+ encryption="aes/gcm/128">
+ Uah59TWX+Ru5GY5p||B44RT/LJtC08QWA5ehQf01JxIpf0qSJUzug25UwkF5a50g
+ </property>
+ <property name="TLS - Keystore Type"></property>
+ <property name="TLS - Truststore"></property>
+ <property name="TLS - Truststore Password">thisIsABadPassword</property>
+ <property name="TLS - Truststore Type"></property>
+ <property name="TLS - Client Auth"></property>
+ <property name="TLS - Protocol"></property>
+ <property name="TLS - Shutdown Gracefully"></property>
+
+ <property name="Referral Strategy">FOLLOW</property>
+ <property name="Connect Timeout">10 secs</property>
+ <property name="Read Timeout">10 secs</property>
+
+ <property name="Url"></property>
+ <property name="User Search Base"></property>
+ <property name="User Search Filter"></property>
+
+ <property name="Authentication Expiration">12 hours</property>
+ </provider>
+
+ <!--
+ Identity Provider for users logging in with username/password against a Kerberos KDC server.
+
+ 'Default Realm' - Default realm to provide when user enters incomplete user principal (i.e. NIFI.APACHE.ORG).
+ 'Authentication Expiration' - The duration of how long the user authentication is valid for. If the user never logs out, they will be required to log back in following this duration.
+ -->
+ <!-- To enable the kerberos-provider remove 2 lines. This is 1 of 2.
+ <provider>
+ <identifier>kerberos-provider</identifier>
+ <class>org.apache.nifi.kerberos.KerberosProvider</class>
+ <property name="Default Realm">NIFI.APACHE.ORG</property>
+ <property name="Authentication Expiration">12 hours</property>
+ </provider>
+ To enable the kerberos-provider remove 2 lines. This is 2 of 2. -->
+</loginIdentityProviders>
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/nifi/blob/59fea1cb/nifi-toolkit/nifi-toolkit-encrypt-config/src/test/resources/login-identity-providers-populated-encrypted-multiple-per-line.xml
----------------------------------------------------------------------
diff --git a/nifi-toolkit/nifi-toolkit-encrypt-config/src/test/resources/login-identity-providers-populated-encrypted-multiple-per-line.xml b/nifi-toolkit/nifi-toolkit-encrypt-config/src/test/resources/login-identity-providers-populated-encrypted-multiple-per-line.xml
new file mode 100644
index 0000000..e551035
--- /dev/null
+++ b/nifi-toolkit/nifi-toolkit-encrypt-config/src/test/resources/login-identity-providers-populated-encrypted-multiple-per-line.xml
@@ -0,0 +1,101 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+ http://www.apache.org/licenses/LICENSE-2.0
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<!--
+ This file lists the login identity providers to use when running securely. In order
+ to use a specific provider it must be configured here and it's identifier
+ must be specified in the nifi.properties file.
+-->
+<loginIdentityProviders>
+ <!--
+ Identity Provider for users logging in with username/password against an LDAP server.
+
+ 'Authentication Strategy' - How the connection to the LDAP server is authenticated. Possible
+ values are ANONYMOUS, SIMPLE, or START_TLS.
+
+ 'Manager DN' - The DN of the manager that is used to bind to the LDAP server to search for users.
+ 'Manager Password' - The password of the manager that is used to bind to the LDAP server to
+ search for users.
+
+ 'TLS - Keystore' - Path to the Keystore that is used when connecting to LDAP using START_TLS.
+ 'TLS - Keystore Password' - Password for the Keystore that is used when connecting to LDAP
+ using START_TLS.
+ 'TLS - Keystore Type' - Type of the Keystore that is used when connecting to LDAP using
+ START_TLS (i.e. JKS or PKCS12).
+ 'TLS - Truststore' - Path to the Truststore that is used when connecting to LDAP using START_TLS.
+ 'TLS - Truststore Password' - Password for the Truststore that is used when connecting to
+ LDAP using START_TLS.
+ 'TLS - Truststore Type' - Type of the Truststore that is used when connecting to LDAP using
+ START_TLS (i.e. JKS or PKCS12).
+ 'TLS - Client Auth' - Client authentication policy when connecting to LDAP using START_TLS.
+ Possible values are REQUIRED, WANT, NONE.
+ 'TLS - Protocol' - Protocol to use when connecting to LDAP using START_TLS. (i.e. TLS,
+ TLSv1.1, TLSv1.2, etc).
+ 'TLS - Shutdown Gracefully' - Specifies whether the TLS should be shut down gracefully
+ before the target context is closed. Defaults to false.
+
+ 'Referral Strategy' - Strategy for handling referrals. Possible values are FOLLOW, IGNORE, THROW.
+ 'Connect Timeout' - Duration of connect timeout. (i.e. 10 secs).
+ 'Read Timeout' - Duration of read timeout. (i.e. 10 secs).
+
+ 'Url' - Url of the LDAP servier (i.e. ldap://<hostname>:<port>).
+ 'User Search Base' - Base DN for searching for users (i.e. CN=Users,DC=example,DC=com).
+ 'User Search Filter' - Filter for searching for users against the 'User Search Base'.
+ (i.e. sAMAccountName={0}). The user specified name is inserted into '{0}'.
+
+ 'Authentication Expiration' - The duration of how long the user authentication is valid
+ for. If the user never logs out, they will be required to log back in following
+ this duration.
+ -->
+ <provider>
+ <identifier>ldap-provider</identifier>
+ <class>org.apache.nifi.ldap.LdapProvider</class>
+ <property name="Authentication Strategy">START_TLS</property>
+
+ <property name="Manager DN">someuser</property>
+ <property name="Manager Password" encryption="aes/gcm/128">q4r7WIgN0MaxdAKM||SGgdCTPGSFEcuH4RraMYEdeyVbOx93abdWTVSWvh1w+klA</property><property name="TLS - Keystore"></property><property name="TLS - Keystore Password" encryption="aes/gcm/128">Uah59TWX+Ru5GY5p||B44RT/LJtC08QWA5ehQf01JxIpf0qSJUzug25UwkF5a50g</property><property name="TLS - Keystore Type"></property>
+ <property name="TLS - Truststore"></property>
+ <property name="TLS - Truststore Password">thisIsABadPassword</property>
+ <property name="TLS - Truststore Type"></property>
+ <property name="TLS - Client Auth"></property>
+ <property name="TLS - Protocol"></property>
+ <property name="TLS - Shutdown Gracefully"></property>
+
+ <property name="Referral Strategy">FOLLOW</property>
+ <property name="Connect Timeout">10 secs</property>
+ <property name="Read Timeout">10 secs</property>
+
+ <property name="Url"></property>
+ <property name="User Search Base"></property>
+ <property name="User Search Filter"></property>
+
+ <property name="Authentication Expiration">12 hours</property>
+ </provider>
+
+ <!--
+ Identity Provider for users logging in with username/password against a Kerberos KDC server.
+
+ 'Default Realm' - Default realm to provide when user enters incomplete user principal (i.e. NIFI.APACHE.ORG).
+ 'Authentication Expiration' - The duration of how long the user authentication is valid for. If the user never logs out, they will be required to log back in following this duration.
+ -->
+ <!-- To enable the kerberos-provider remove 2 lines. This is 1 of 2.
+ <provider>
+ <identifier>kerberos-provider</identifier>
+ <class>org.apache.nifi.kerberos.KerberosProvider</class>
+ <property name="Default Realm">NIFI.APACHE.ORG</property>
+ <property name="Authentication Expiration">12 hours</property>
+ </provider>
+ To enable the kerberos-provider remove 2 lines. This is 2 of 2. -->
+</loginIdentityProviders>
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/nifi/blob/59fea1cb/nifi-toolkit/nifi-toolkit-encrypt-config/src/test/resources/login-identity-providers-populated-encrypted.xml
----------------------------------------------------------------------
diff --git a/nifi-toolkit/nifi-toolkit-encrypt-config/src/test/resources/login-identity-providers-populated-encrypted.xml b/nifi-toolkit/nifi-toolkit-encrypt-config/src/test/resources/login-identity-providers-populated-encrypted.xml
new file mode 100644
index 0000000..705eb88
--- /dev/null
+++ b/nifi-toolkit/nifi-toolkit-encrypt-config/src/test/resources/login-identity-providers-populated-encrypted.xml
@@ -0,0 +1,105 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+ http://www.apache.org/licenses/LICENSE-2.0
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<!--
+ This file lists the login identity providers to use when running securely. In order
+ to use a specific provider it must be configured here and it's identifier
+ must be specified in the nifi.properties file.
+-->
+<loginIdentityProviders>
+ <!--
+ Identity Provider for users logging in with username/password against an LDAP server.
+
+ 'Authentication Strategy' - How the connection to the LDAP server is authenticated. Possible
+ values are ANONYMOUS, SIMPLE, or START_TLS.
+
+ 'Manager DN' - The DN of the manager that is used to bind to the LDAP server to search for users.
+ 'Manager Password' - The password of the manager that is used to bind to the LDAP server to
+ search for users.
+
+ 'TLS - Keystore' - Path to the Keystore that is used when connecting to LDAP using START_TLS.
+ 'TLS - Keystore Password' - Password for the Keystore that is used when connecting to LDAP
+ using START_TLS.
+ 'TLS - Keystore Type' - Type of the Keystore that is used when connecting to LDAP using
+ START_TLS (i.e. JKS or PKCS12).
+ 'TLS - Truststore' - Path to the Truststore that is used when connecting to LDAP using START_TLS.
+ 'TLS - Truststore Password' - Password for the Truststore that is used when connecting to
+ LDAP using START_TLS.
+ 'TLS - Truststore Type' - Type of the Truststore that is used when connecting to LDAP using
+ START_TLS (i.e. JKS or PKCS12).
+ 'TLS - Client Auth' - Client authentication policy when connecting to LDAP using START_TLS.
+ Possible values are REQUIRED, WANT, NONE.
+ 'TLS - Protocol' - Protocol to use when connecting to LDAP using START_TLS. (i.e. TLS,
+ TLSv1.1, TLSv1.2, etc).
+ 'TLS - Shutdown Gracefully' - Specifies whether the TLS should be shut down gracefully
+ before the target context is closed. Defaults to false.
+
+ 'Referral Strategy' - Strategy for handling referrals. Possible values are FOLLOW, IGNORE, THROW.
+ 'Connect Timeout' - Duration of connect timeout. (i.e. 10 secs).
+ 'Read Timeout' - Duration of read timeout. (i.e. 10 secs).
+
+ 'Url' - Url of the LDAP servier (i.e. ldap://<hostname>:<port>).
+ 'User Search Base' - Base DN for searching for users (i.e. CN=Users,DC=example,DC=com).
+ 'User Search Filter' - Filter for searching for users against the 'User Search Base'.
+ (i.e. sAMAccountName={0}). The user specified name is inserted into '{0}'.
+
+ 'Authentication Expiration' - The duration of how long the user authentication is valid
+ for. If the user never logs out, they will be required to log back in following
+ this duration.
+ -->
+ <provider>
+ <identifier>ldap-provider</identifier>
+ <class>org.apache.nifi.ldap.LdapProvider</class>
+ <property name="Authentication Strategy">START_TLS</property>
+
+ <property name="Manager DN">someuser</property>
+ <property name="Manager Password" encryption="aes/gcm/128">q4r7WIgN0MaxdAKM||SGgdCTPGSFEcuH4RraMYEdeyVbOx93abdWTVSWvh1w+klA</property>
+
+ <property name="TLS - Keystore"></property>
+ <property name="TLS - Keystore Password" encryption="aes/gcm/128">Uah59TWX+Ru5GY5p||B44RT/LJtC08QWA5ehQf01JxIpf0qSJUzug25UwkF5a50g</property>
+ <property name="TLS - Keystore Type"></property>
+ <property name="TLS - Truststore"></property>
+ <property name="TLS - Truststore Password">thisIsABadPassword</property>
+ <property name="TLS - Truststore Type"></property>
+ <property name="TLS - Client Auth"></property>
+ <property name="TLS - Protocol"></property>
+ <property name="TLS - Shutdown Gracefully"></property>
+
+ <property name="Referral Strategy">FOLLOW</property>
+ <property name="Connect Timeout">10 secs</property>
+ <property name="Read Timeout">10 secs</property>
+
+ <property name="Url"></property>
+ <property name="User Search Base"></property>
+ <property name="User Search Filter"></property>
+
+ <property name="Authentication Expiration">12 hours</property>
+ </provider>
+
+ <!--
+ Identity Provider for users logging in with username/password against a Kerberos KDC server.
+
+ 'Default Realm' - Default realm to provide when user enters incomplete user principal (i.e. NIFI.APACHE.ORG).
+ 'Authentication Expiration' - The duration of how long the user authentication is valid for. If the user never logs out, they will be required to log back in following this duration.
+ -->
+ <!-- To enable the kerberos-provider remove 2 lines. This is 1 of 2.
+ <provider>
+ <identifier>kerberos-provider</identifier>
+ <class>org.apache.nifi.kerberos.KerberosProvider</class>
+ <property name="Default Realm">NIFI.APACHE.ORG</property>
+ <property name="Authentication Expiration">12 hours</property>
+ </provider>
+ To enable the kerberos-provider remove 2 lines. This is 2 of 2. -->
+</loginIdentityProviders>
\ No newline at end of file