diff --git a/doc/licenses/apache-commons-codec-1.11/NOTICE b/doc/licenses/apache-commons-codec-1.11/NOTICE new file mode 100644 index 0000000000..9899d2108a --- /dev/null +++ b/doc/licenses/apache-commons-codec-1.11/NOTICE @@ -0,0 +1,17 @@ +Apache Commons Codec +Copyright 2002-2020 The Apache Software Foundation + +This product includes software developed at +The Apache Software Foundation (https://www.apache.org/). + +src/test/org/apache/commons/codec/language/DoubleMetaphoneTest.java +contains test data from http://aspell.net/test/orig/batch0.tab. +Copyright (C) 2002 Kevin Atkinson (kevina@gnu.org) + +=============================================================================== + +The content of package org.apache.commons.codec.language.bm has been translated +from the original php source code available at http://stevemorse.org/phoneticinfo.htm +with permission from the original authors. +Original source copyright: +Copyright (c) 2008 Alexander Beider & Stephen P. Morse. diff --git a/doc/licenses/apache-commons-codec-1.11/README b/doc/licenses/apache-commons-codec-1.11/README new file mode 100644 index 0000000000..1c9959a73a --- /dev/null +++ b/doc/licenses/apache-commons-codec-1.11/README @@ -0,0 +1,8 @@ +Apache Commons Codec (http://commons.apache.org/proper/commons-codec/) +----------------------------------------------------------------------- + + Version: 1.11 + From: 'Apache Software Foundation' (https://www.apache.org/) + License(s): + Apache v2.0 + diff --git a/doc/licenses/apache-commons-codec-1.11/dep-coordinates.txt b/doc/licenses/apache-commons-codec-1.11/dep-coordinates.txt new file mode 100644 index 0000000000..6eaa2d04e0 --- /dev/null +++ b/doc/licenses/apache-commons-codec-1.11/dep-coordinates.txt @@ -0,0 +1 @@ +commons-codec:commons-codec:jar:1.11 \ No newline at end of file diff --git a/doc/licenses/duo-universal-sdk-1.1.3/LICENSE b/doc/licenses/duo-universal-sdk-1.1.3/LICENSE new file mode 100644 index 0000000000..369fbf8130 --- /dev/null +++ b/doc/licenses/duo-universal-sdk-1.1.3/LICENSE @@ -0,0 +1,25 @@ +Copyright (c) 2022 Cisco Systems, Inc. and/or its affiliates +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: + +1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. +2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. +3. The name of the author may not be used to endorse or promote products + derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR +IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, +INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF +THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. \ No newline at end of file diff --git a/doc/licenses/duo-universal-sdk-1.1.3/README b/doc/licenses/duo-universal-sdk-1.1.3/README new file mode 100644 index 0000000000..5bc1049ae8 --- /dev/null +++ b/doc/licenses/duo-universal-sdk-1.1.3/README @@ -0,0 +1,8 @@ +Duo Universal SDK for Java (https://duo.com/docs/duoweb) +-------------------------------------------------------- + + Version: 1.1.3 + From: 'Cisco Systems' + License(s): + Duo License (bundled/duo-universal-sdk-1.1.3/LICENSE) + diff --git a/doc/licenses/duo-universal-sdk-1.1.3/dep-coordinates.txt b/doc/licenses/duo-universal-sdk-1.1.3/dep-coordinates.txt new file mode 100644 index 0000000000..e89d39cd95 --- /dev/null +++ b/doc/licenses/duo-universal-sdk-1.1.3/dep-coordinates.txt @@ -0,0 +1 @@ +com.duosecurity:duo-universal-sdk:jar:1.1.3 \ No newline at end of file diff --git a/doc/licenses/java-jwt-3.3.0/LICENSE b/doc/licenses/java-jwt-3.3.0/LICENSE new file mode 100644 index 0000000000..4a7a13adaa --- /dev/null +++ b/doc/licenses/java-jwt-3.3.0/LICENSE @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2015 Auth0, Inc. (http://auth0.com) + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. \ No newline at end of file diff --git a/doc/licenses/java-jwt-3.3.0/README b/doc/licenses/java-jwt-3.3.0/README new file mode 100644 index 0000000000..f00c8aafd8 --- /dev/null +++ b/doc/licenses/java-jwt-3.3.0/README @@ -0,0 +1,8 @@ +Java JWT (https://github.com/auth0/java-jwt) +-------------------------------------------- + + Version: 3.3.0 + From: 'Auth0 by Okta' (https://www.auth0.com) + License(s): + MIT (bundled/java-jwt-3.3.0/LICENSE) + diff --git a/doc/licenses/java-jwt-3.3.0/dep-coordinates.txt b/doc/licenses/java-jwt-3.3.0/dep-coordinates.txt new file mode 100644 index 0000000000..4ad3a6064a --- /dev/null +++ b/doc/licenses/java-jwt-3.3.0/dep-coordinates.txt @@ -0,0 +1 @@ +com.auth0:java-jwt:jar:3.3.0 \ No newline at end of file diff --git a/doc/licenses/kotlin-1.4.10/NOTICE.txt b/doc/licenses/kotlin-1.4.10/NOTICE.txt new file mode 100644 index 0000000000..0f3e7c29d7 --- /dev/null +++ b/doc/licenses/kotlin-1.4.10/NOTICE.txt @@ -0,0 +1,2 @@ +Kotlin Compiler +Copyright 2010-2023 JetBrains s.r.o and respective authors and developers diff --git a/doc/licenses/kotlin-1.4.10/README b/doc/licenses/kotlin-1.4.10/README new file mode 100644 index 0000000000..a89a5ceea9 --- /dev/null +++ b/doc/licenses/kotlin-1.4.10/README @@ -0,0 +1,8 @@ +Kotlin (https://kotlinlang.org/) +-------------------------------- + + Version: 1.4.10 + From: 'JetBrains s.r.o and respective authors and developers' + License(s): + Apache v2.0 + diff --git a/doc/licenses/kotlin-1.4.10/dep-coordinates.txt b/doc/licenses/kotlin-1.4.10/dep-coordinates.txt new file mode 100644 index 0000000000..9eedc33fe4 --- /dev/null +++ b/doc/licenses/kotlin-1.4.10/dep-coordinates.txt @@ -0,0 +1,5 @@ +org.jetbrains.kotlin:kotlin-reflect:jar:1.4.10 +org.jetbrains.kotlin:kotlin-stdlib:jar:1.4.10 +org.jetbrains.kotlin:kotlin-stdlib-common:jar:1.4.10 +org.jetbrains.kotlin:kotlin-stdlib-jdk8:jar:1.4.10 +org.jetbrains.kotlin:kotlin-stdlib-jdk7:jar:1.4.10 diff --git a/doc/licenses/logging-interceptor-4.9.1/LICENSE.txt b/doc/licenses/logging-interceptor-4.9.1/LICENSE.txt new file mode 100644 index 0000000000..f49a4e16e6 --- /dev/null +++ b/doc/licenses/logging-interceptor-4.9.1/LICENSE.txt @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. \ No newline at end of file diff --git a/doc/licenses/logging-interceptor-4.9.1/NOTICE b/doc/licenses/logging-interceptor-4.9.1/NOTICE new file mode 100644 index 0000000000..d8bff2eefb --- /dev/null +++ b/doc/licenses/logging-interceptor-4.9.1/NOTICE @@ -0,0 +1,13 @@ +Copyright 2019 Square, Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. \ No newline at end of file diff --git a/doc/licenses/logging-interceptor-4.9.1/README b/doc/licenses/logging-interceptor-4.9.1/README new file mode 100644 index 0000000000..4755b031ce --- /dev/null +++ b/doc/licenses/logging-interceptor-4.9.1/README @@ -0,0 +1,8 @@ +okhttp logging-interceptor (https://square.github.io/okhttp/) +------------------------------------------------------------- + + Version: 4.9.1 + From: 'Square Inc' + License(s): + Apache v2.0 + diff --git a/doc/licenses/logging-interceptor-4.9.1/dep-coordinates.txt b/doc/licenses/logging-interceptor-4.9.1/dep-coordinates.txt new file mode 100644 index 0000000000..aeab282478 --- /dev/null +++ b/doc/licenses/logging-interceptor-4.9.1/dep-coordinates.txt @@ -0,0 +1 @@ +com.squareup.okhttp3:logging-interceptor:jar:4.9.1 \ No newline at end of file diff --git a/doc/licenses/okhttp-3.14.9/LICENSE.txt b/doc/licenses/okhttp-3.14.9/LICENSE.txt new file mode 100644 index 0000000000..f49a4e16e6 --- /dev/null +++ b/doc/licenses/okhttp-3.14.9/LICENSE.txt @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. \ No newline at end of file diff --git a/doc/licenses/okhttp-3.14.9/NOTICE b/doc/licenses/okhttp-3.14.9/NOTICE new file mode 100644 index 0000000000..d8bff2eefb --- /dev/null +++ b/doc/licenses/okhttp-3.14.9/NOTICE @@ -0,0 +1,13 @@ +Copyright 2019 Square, Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. \ No newline at end of file diff --git a/doc/licenses/okhttp-3.14.9/README b/doc/licenses/okhttp-3.14.9/README new file mode 100644 index 0000000000..7f343e7bd4 --- /dev/null +++ b/doc/licenses/okhttp-3.14.9/README @@ -0,0 +1,8 @@ +okhttp (https://square.github.io/okhttp/) +--------------------------------------------- + + Version: 3.14.9 + From: 'Square Inc' + License(s): + Apache 2.0 + diff --git a/doc/licenses/okhttp-3.14.9/dep-coordinates.txt b/doc/licenses/okhttp-3.14.9/dep-coordinates.txt new file mode 100644 index 0000000000..ea402ee6ba --- /dev/null +++ b/doc/licenses/okhttp-3.14.9/dep-coordinates.txt @@ -0,0 +1 @@ +com.squareup.okhttp3:okhttp:jar:3.14.9 \ No newline at end of file diff --git a/doc/licenses/okio-1.17.2/LICENSE.txt b/doc/licenses/okio-1.17.2/LICENSE.txt new file mode 100644 index 0000000000..f49a4e16e6 --- /dev/null +++ b/doc/licenses/okio-1.17.2/LICENSE.txt @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. \ No newline at end of file diff --git a/doc/licenses/okio-1.17.2/NOTICE b/doc/licenses/okio-1.17.2/NOTICE new file mode 100644 index 0000000000..25fdd5926a --- /dev/null +++ b/doc/licenses/okio-1.17.2/NOTICE @@ -0,0 +1,13 @@ +Copyright 2013 Square, Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. \ No newline at end of file diff --git a/doc/licenses/okio-1.17.2/README b/doc/licenses/okio-1.17.2/README new file mode 100644 index 0000000000..74976b808b --- /dev/null +++ b/doc/licenses/okio-1.17.2/README @@ -0,0 +1,8 @@ +okio (https://square.github.io/okio/) +--------------------------------------------- + + Version: 1.17.2 + From: 'Square Inc' + License(s): + Apache 2.0 (bundled/retrofit-2.9.0/LICENSE.txt) + diff --git a/doc/licenses/okio-1.17.2/dep-coordinates.txt b/doc/licenses/okio-1.17.2/dep-coordinates.txt new file mode 100644 index 0000000000..566082a428 --- /dev/null +++ b/doc/licenses/okio-1.17.2/dep-coordinates.txt @@ -0,0 +1 @@ +com.squareup.okio:okio:jar:1.17.2 \ No newline at end of file diff --git a/doc/licenses/retrofit-2.9.0/LICENSE.txt b/doc/licenses/retrofit-2.9.0/LICENSE.txt new file mode 100644 index 0000000000..f49a4e16e6 --- /dev/null +++ b/doc/licenses/retrofit-2.9.0/LICENSE.txt @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. \ No newline at end of file diff --git a/doc/licenses/retrofit-2.9.0/NOTICE b/doc/licenses/retrofit-2.9.0/NOTICE new file mode 100644 index 0000000000..25fdd5926a --- /dev/null +++ b/doc/licenses/retrofit-2.9.0/NOTICE @@ -0,0 +1,13 @@ +Copyright 2013 Square, Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. \ No newline at end of file diff --git a/doc/licenses/retrofit-2.9.0/README b/doc/licenses/retrofit-2.9.0/README new file mode 100644 index 0000000000..8de113264e --- /dev/null +++ b/doc/licenses/retrofit-2.9.0/README @@ -0,0 +1,8 @@ +retrofit (https://square.github.io/retrofit/) +--------------------------------------------- + + Version: 2.9.0 + From: 'Square Inc' + License(s): + Apache 2.0 (bundled/retrofit-2.9.0/LICENSE.txt) + diff --git a/doc/licenses/retrofit-2.9.0/dep-coordinates.txt b/doc/licenses/retrofit-2.9.0/dep-coordinates.txt new file mode 100644 index 0000000000..43f8e2898b --- /dev/null +++ b/doc/licenses/retrofit-2.9.0/dep-coordinates.txt @@ -0,0 +1,2 @@ +com.squareup.retrofit2:retrofit:jar:2.9.0 +com.squareup.retrofit2:converter-jackson:jar:2.9.0 \ No newline at end of file diff --git a/extensions/guacamole-auth-duo/pom.xml b/extensions/guacamole-auth-duo/pom.xml index 7d6ab3b23f..0614cb47d0 100644 --- a/extensions/guacamole-auth-duo/pom.xml +++ b/extensions/guacamole-auth-duo/pom.xml @@ -39,93 +39,9 @@ UTF-8 + true - - - - - - com.keithbranton.mojo - angular-maven-plugin - 0.3.4 - - - generate-resources - - html2js - - - - - ${basedir}/src/main/resources - **/*.html - ${basedir}/src/main/resources/generated/templates-main/templates.js - app/ext/duo - - - - - - com.github.buckelieg - minify-maven-plugin - - - default-cli - - UTF-8 - - ${basedir}/src/main/resources - ${project.build.directory}/classes - - / - / - duo.css - - - license.txt - - - - **/*.css - - - / - / - duo.js - - - license.txt - lib/DuoWeb/LICENSE.js - - - - **/*.js - - - - - **/*.test.js - - CLOSURE - - - - OFF - OFF - - - - - minify - - - - - - - - @@ -155,6 +71,20 @@ 2.5 provided + + + + com.duosecurity + duo-universal-sdk + 1.1.3 + + + + + org.jetbrains.kotlin + kotlin-stdlib-common + 1.4.10 + diff --git a/extensions/guacamole-auth-duo/src/main/java/org/apache/guacamole/auth/duo/DuoAuthenticationProviderModule.java b/extensions/guacamole-auth-duo/src/main/java/org/apache/guacamole/auth/duo/DuoAuthenticationProviderModule.java index a60523bf87..2b5e5d0b27 100644 --- a/extensions/guacamole-auth-duo/src/main/java/org/apache/guacamole/auth/duo/DuoAuthenticationProviderModule.java +++ b/extensions/guacamole-auth-duo/src/main/java/org/apache/guacamole/auth/duo/DuoAuthenticationProviderModule.java @@ -21,7 +21,6 @@ import com.google.inject.AbstractModule; import org.apache.guacamole.GuacamoleException; -import org.apache.guacamole.auth.duo.api.DuoService; import org.apache.guacamole.auth.duo.conf.ConfigurationService; import org.apache.guacamole.environment.Environment; import org.apache.guacamole.environment.LocalEnvironment; @@ -42,6 +41,11 @@ public class DuoAuthenticationProviderModule extends AbstractModule { * module has configured injection. */ private final AuthenticationProvider authProvider; + + /** + * The session manager that stores authentication attempts. + */ + private final DuoAuthenticationSessionManager authSessionManager; /** * Creates a new Duo authentication provider module which configures @@ -62,6 +66,9 @@ public DuoAuthenticationProviderModule(AuthenticationProvider authProvider) // Store associated auth provider this.authProvider = authProvider; + + // Create a new session manager + this.authSessionManager = new DuoAuthenticationSessionManager(); } @@ -73,9 +80,10 @@ protected void configure() { bind(Environment.class).toInstance(environment); // Bind Duo-specific services + bind(DuoAuthenticationSessionManager.class).toInstance(authSessionManager); bind(ConfigurationService.class); - bind(DuoService.class); bind(UserVerificationService.class); + } diff --git a/extensions/guacamole-auth-duo/src/main/java/org/apache/guacamole/auth/duo/DuoAuthenticationSession.java b/extensions/guacamole-auth-duo/src/main/java/org/apache/guacamole/auth/duo/DuoAuthenticationSession.java new file mode 100644 index 0000000000..8dd3e8db1e --- /dev/null +++ b/extensions/guacamole-auth-duo/src/main/java/org/apache/guacamole/auth/duo/DuoAuthenticationSession.java @@ -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. + */ + +package org.apache.guacamole.auth.duo; + +import org.apache.guacamole.net.auth.AuthenticationSession; + +/** + * An AuthenticationSession that stores the information required for an + * in-progress Duo authentication attempt. + */ +public class DuoAuthenticationSession extends AuthenticationSession { + + /** + * The session state generated by the Duo client, which is used to track + * the session through the redirect and return process. + */ + private final String state; + + /** + * The username of the user who is authenticating with this session. + */ + private final String username; + + /** + * Create a new instance of this authenticaiton session, having the given length of time + * for expriation and the state generated by the Duo Client. + * + * @param expires + * The number of milliseconds before this session is invalid. + * + * @param state + * The session state, as generated by the Duo Client. + * + * @param username + * The username of the user who is attempting authentication with Duo. + */ + public DuoAuthenticationSession(long expires, String state, String username) { + super(expires); + this.state = state; + this.username = username; + } + + /** + * Return the stored session state. + * + * @return + * The stored session state. + */ + public String getState() { + return state; + } + + public String getUsername() { + return username; + } + +} diff --git a/extensions/guacamole-auth-duo/src/main/resources/duoModule.js b/extensions/guacamole-auth-duo/src/main/java/org/apache/guacamole/auth/duo/DuoAuthenticationSessionManager.java similarity index 64% rename from extensions/guacamole-auth-duo/src/main/resources/duoModule.js rename to extensions/guacamole-auth-duo/src/main/java/org/apache/guacamole/auth/duo/DuoAuthenticationSessionManager.java index 49a342f843..9bfbcc4668 100644 --- a/extensions/guacamole-auth-duo/src/main/resources/duoModule.js +++ b/extensions/guacamole-auth-duo/src/main/java/org/apache/guacamole/auth/duo/DuoAuthenticationSessionManager.java @@ -17,12 +17,18 @@ * under the License. */ +package org.apache.guacamole.auth.duo; + +import com.google.inject.Singleton; +import org.apache.guacamole.net.auth.AuthenticationSessionManager; + /** - * Module which provides handling for Duo multi-factor authentication. + * An AuthenticationSessionManager implementation that temporarily stores + * authentication attempts for Duo MFA while they are underway. */ -angular.module('guacDuo', [ - 'form' -]); - -// Ensure the guacDuo module is loaded along with the rest of the app -angular.module('index').requires.push('guacDuo'); +@Singleton +public class DuoAuthenticationSessionManager extends AuthenticationSessionManager { + + // Nothing to see here. + +} diff --git a/extensions/guacamole-auth-duo/src/main/java/org/apache/guacamole/auth/duo/UserVerificationService.java b/extensions/guacamole-auth-duo/src/main/java/org/apache/guacamole/auth/duo/UserVerificationService.java index abcb486057..d38a4c6c62 100644 --- a/extensions/guacamole-auth-duo/src/main/java/org/apache/guacamole/auth/duo/UserVerificationService.java +++ b/extensions/guacamole-auth-duo/src/main/java/org/apache/guacamole/auth/duo/UserVerificationService.java @@ -19,25 +19,52 @@ package org.apache.guacamole.auth.duo; +import com.duosecurity.Client; +import com.duosecurity.exception.DuoException; +import com.duosecurity.model.Token; import com.google.inject.Inject; +import java.net.URI; +import java.net.URISyntaxException; import java.util.Collections; import javax.servlet.http.HttpServletRequest; import org.apache.guacamole.GuacamoleException; -import org.apache.guacamole.auth.duo.api.DuoService; +import org.apache.guacamole.GuacamoleServerException; import org.apache.guacamole.auth.duo.conf.ConfigurationService; -import org.apache.guacamole.auth.duo.form.DuoSignedResponseField; -import org.apache.guacamole.form.Field; +import org.apache.guacamole.form.RedirectField; import org.apache.guacamole.language.TranslatableGuacamoleClientException; import org.apache.guacamole.language.TranslatableGuacamoleInsufficientCredentialsException; +import org.apache.guacamole.language.TranslatableMessage; import org.apache.guacamole.net.auth.AuthenticatedUser; import org.apache.guacamole.net.auth.Credentials; import org.apache.guacamole.net.auth.credentials.CredentialsInfo; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** * Service for verifying the identity of a user against Duo. */ public class UserVerificationService { + private static final Logger LOGGER = LoggerFactory.getLogger(UserVerificationService.class); + + /** + * The name of the parameter which Duo will return in it's GET call-back + * that contains the code that the client will use to generate a token. + */ + private static final String DUO_CODE_PARAMETER_NAME = "duo_code"; + + /** + * The name of the parameter that will be used in the GET call-back that + * contains the session state. + */ + private static final String DUO_STATE_PARAMETER_NAME = "state"; + + /** + * The value that will be returned in the token if Duo authentication + * was successful. + */ + private static final String DUO_TOKEN_SUCCESS_VALUE = "ALLOW"; + /** * Service for retrieving Duo configuration information. */ @@ -45,10 +72,11 @@ public class UserVerificationService { private ConfigurationService confService; /** - * Service for verifying users against Duo. + * The authentication session manager that temporarily stores in-progress + * authentication attempts. */ @Inject - private DuoService duoService; + private DuoAuthenticationSessionManager duoSessionManager; /** * Verifies the identity of the given user via the Duo multi-factor @@ -75,39 +103,74 @@ public void verifyAuthenticatedUser(AuthenticatedUser authenticatedUser) // Ignore anonymous users if (authenticatedUser.getIdentifier().equals(AuthenticatedUser.ANONYMOUS_IDENTIFIER)) return; - - // Retrieve signed Duo response from request - String signedResponse = request.getParameter(DuoSignedResponseField.PARAMETER_NAME); - - // If no signed response, request one - if (signedResponse == null) { - - // Create field which requests a signed response from Duo that - // verifies the identity of the given user via the configured - // Duo API endpoint - Field signedResponseField = new DuoSignedResponseField( - confService.getAPIHostname(), - duoService.createSignedRequest(authenticatedUser)); - - // Create an overall description of the additional credentials - // required to verify identity - CredentialsInfo expectedCredentials = new CredentialsInfo( - Collections.singletonList(signedResponseField)); + + String username = authenticatedUser.getIdentifier(); + + try { + + // Set up the Duo Client + Client duoClient = new Client.Builder( + confService.getClientId(), + confService.getClientSecret(), + confService.getAPIHostname(), + confService.getRedirectUrl().toString()) + .build(); + + duoClient.healthCheck(); + + + // Retrieve signed Duo Code and State from the request + String duoCode = request.getParameter(DUO_CODE_PARAMETER_NAME); + String duoState = request.getParameter(DUO_STATE_PARAMETER_NAME); + + // If no code or state is received, assume Duo MFA redirect has not occured and do it. + if (duoCode == null || duoState == null) { + + // Get a new session state from the Duo client + duoState = duoClient.generateState(); + LOGGER.debug(">>> DUO <<< STATE DEFER: {}", duoState); + + // Add this session + duoSessionManager.defer(new DuoAuthenticationSession(confService.getAuthTimeout(), duoState, username), duoState); // Request additional credentials throw new TranslatableGuacamoleInsufficientCredentialsException( - "Verification using Duo is required before authentication " - + "can continue.", "LOGIN.INFO_DUO_AUTH_REQUIRED", - expectedCredentials); + "Verification using Duo is required before authentication " + + "can continue.", "LOGIN.INFO_DUO_AUTH_REQUIRED", + new CredentialsInfo(Collections.singletonList( + new RedirectField( + DUO_CODE_PARAMETER_NAME, + new URI(duoClient.createAuthUrl(username, duoState)), + new TranslatableMessage("LOGIN.INFO_DUO_REDIRECT_PENDING") + ) + )) + ); } - - // If signed response does not verify this user's identity, abort auth - if (!duoService.isValidSignedResponse(authenticatedUser, signedResponse)) + + LOGGER.debug(">>> DUO <<< STATE RESUME: {}", duoState); + + // Retrieve the deferred authenticaiton attempt + DuoAuthenticationSession duoSession = duoSessionManager.resume(duoState); + if (duoSession == null) + throw new GuacamoleServerException("Failed to resume Duo authentication session."); + + // Get the token from the DuoClient using the code and username, and check status + Token token = duoClient.exchangeAuthorizationCodeFor2FAResult(duoCode, duoSession.getUsername()); + if (token == null + || token.getAuth_result() == null + || !DUO_TOKEN_SUCCESS_VALUE.equals(token.getAuth_result().getStatus())) throw new TranslatableGuacamoleClientException("Provided Duo " + "validation code is incorrect.", "LOGIN.INFO_DUO_VALIDATION_CODE_INCORRECT"); + } + catch (DuoException e) { + throw new GuacamoleServerException("Duo Client error.", e); + } + catch (URISyntaxException e) { + throw new GuacamoleServerException("Error creating URI from Duo Authentication URL.", e); + } } } diff --git a/extensions/guacamole-auth-duo/src/main/java/org/apache/guacamole/auth/duo/api/DuoCookie.java b/extensions/guacamole-auth-duo/src/main/java/org/apache/guacamole/auth/duo/api/DuoCookie.java deleted file mode 100644 index 6fa2a88c4c..0000000000 --- a/extensions/guacamole-auth-duo/src/main/java/org/apache/guacamole/auth/duo/api/DuoCookie.java +++ /dev/null @@ -1,245 +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. - */ - -package org.apache.guacamole.auth.duo.api; - -import com.google.common.io.BaseEncoding; -import java.io.UnsupportedEncodingException; -import java.util.regex.Matcher; -import java.util.regex.Pattern; -import org.apache.guacamole.GuacamoleClientException; -import org.apache.guacamole.GuacamoleException; - -/** - * Data which describes the identity of the user being verified by Duo. - */ -public class DuoCookie { - - /** - * Pattern which matches valid cookies. Each cookie is made up of three - * sections, separated from each other by pipe symbols ("|"). - */ - private static final Pattern COOKIE_FORMAT = Pattern.compile("([^|]+)\\|([^|]+)\\|([0-9]+)"); - - /** - * The index of the capturing group within COOKIE_FORMAT which contains the - * username. - */ - private static final int USERNAME_GROUP = 1; - - /** - * The index of the capturing group within COOKIE_FORMAT which contains the - * integration key. - */ - private static final int INTEGRATION_KEY_GROUP = 2; - - /** - * The index of the capturing group within COOKIE_FORMAT which contains the - * expiration timestamp. - */ - private static final int EXPIRATION_TIMESTAMP_GROUP = 3; - - /** - * The username of the user being verified. - */ - private final String username; - - /** - * The integration key provided by Duo and specific to this deployment of - * Guacamole. - */ - private final String integrationKey; - - /** - * The time that this cookie expires, in seconds since midnight of - * 1970-01-01 (UTC). - */ - private final long expires; - - /** - * Creates a new DuoCookie which describes the identity of a user being - * verified. - * - * @param username - * The username of the user being verified. - * - * @param integrationKey - * The integration key provided by Duo and specific to this deployment - * of Guacamole. - * - * @param expires - * The time that this cookie expires, in seconds since midnight of - * 1970-01-01 (UTC). - */ - public DuoCookie(String username, String integrationKey, long expires) { - this.username = username; - this.integrationKey = integrationKey; - this.expires = expires; - } - - /** - * Returns the username of the user being verified. - * - * @return - * The username of the user being verified. - */ - public String getUsername() { - return username; - } - - /** - * Returns the integration key provided by Duo and specific to this - * deployment of Guacamole. - * - * @return - * The integration key provided by Duo and specific to this deployment - * of Guacamole. - */ - public String getIntegrationKey() { - return integrationKey; - } - - /** - * Returns the time that this cookie expires. The expiration time is - * represented in seconds since midnight of 1970-01-01 (UTC). - * - * @return - * The time that this cookie expires, in seconds since midnight of - * 1970-01-01 (UTC). - */ - public long getExpirationTimestamp(){ - return expires; - } - - /** - * Returns the current time as the number of seconds elapsed since - * midnight of 1970-01-01 (UTC). - * - * @return - * The current time as the number of seconds elapsed since midnight of - * 1970-01-01 (UTC). - */ - public static long currentTimestamp() { - return System.currentTimeMillis() / 1000; - } - - /** - * Returns whether this cookie has expired (the current time has met or - * exceeded the expiration timestamp). - * - * @return - * true if this cookie has expired, false otherwise. - */ - public boolean isExpired() { - return currentTimestamp() >= expires; - } - - /** - * Parses a base64-encoded Duo cookie, producing a new DuoCookie object - * containing the data therein. If the given string is not a valid Duo - * cookie, an exception is thrown. Note that the cookie may be expired, and - * must be checked for expiration prior to actual use. - * - * @param str - * The base64-encoded Duo cookie to parse. - * - * @return - * A new DuoCookie object containing the same data as the given - * base64-encoded Duo cookie string. - * - * @throws GuacamoleException - * If the given string is not a valid base64-encoded Duo cookie. - */ - public static DuoCookie parseDuoCookie(String str) throws GuacamoleException { - - // Attempt to decode data as base64 - String data; - try { - data = new String(BaseEncoding.base64().decode(str), "UTF-8"); - } - - // Bail if invalid base64 is provided - catch (IllegalArgumentException e) { - throw new GuacamoleClientException("Username is not correctly " - + "encoded as base64.", e); - } - - // Throw hard errors if standard pieces of Java are missing - catch (UnsupportedEncodingException e) { - throw new UnsupportedOperationException("Unexpected lack of " - + "UTF-8 support.", e); - } - - // Verify format of provided data - Matcher matcher = COOKIE_FORMAT.matcher(data); - if (!matcher.matches()) - throw new GuacamoleClientException("Format of base64-encoded " - + "username is invalid."); - - // Get username and key (simple strings) - String username = matcher.group(USERNAME_GROUP); - String key = matcher.group(INTEGRATION_KEY_GROUP); - - // Parse expiration time - long expires; - try { - expires = Long.parseLong(matcher.group(EXPIRATION_TIMESTAMP_GROUP)); - } - - // Bail if expiration timestamp is not a valid long - catch (NumberFormatException e) { - throw new GuacamoleClientException("Expiration timestamp is " - + "not valid.", e); - } - - // Return parsed cookie - return new DuoCookie(username, key, expires); - - } - - /** - * Returns the base64-encoded string representation of this DuoCookie. The - * format used is identical to that required by the Duo service: the - * username, integration key, and expiration timestamp separated by pipe - * symbols ("|") and encoded with base64. - * - * @return - * The base64-encoded string representation of this DuoCookie. - */ - @Override - public String toString() { - - try { - - // Separate each cookie field with pipe symbols - String data = username + "|" + integrationKey + "|" + expires; - - // Encode resulting cookie string with base64 - return BaseEncoding.base64().encode(data.getBytes("UTF-8")); - - } - - // Throw hard errors if standard pieces of Java are missing - catch (UnsupportedEncodingException e) { - throw new UnsupportedOperationException("Unexpected lack of UTF-8 support.", e); - } - - } - -} diff --git a/extensions/guacamole-auth-duo/src/main/java/org/apache/guacamole/auth/duo/api/DuoService.java b/extensions/guacamole-auth-duo/src/main/java/org/apache/guacamole/auth/duo/api/DuoService.java deleted file mode 100644 index 11cca13c55..0000000000 --- a/extensions/guacamole-auth-duo/src/main/java/org/apache/guacamole/auth/duo/api/DuoService.java +++ /dev/null @@ -1,205 +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. - */ - -package org.apache.guacamole.auth.duo.api; - -import com.google.inject.Inject; -import java.util.regex.Matcher; -import java.util.regex.Pattern; -import org.apache.guacamole.GuacamoleException; -import org.apache.guacamole.auth.duo.conf.ConfigurationService; -import org.apache.guacamole.net.auth.AuthenticatedUser; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -/** - * Service which produces signed requests and parses/verifies signed responses - * as required by Duo's API. - */ -public class DuoService { - - /** - * Logger for this class. - */ - private static final Logger logger = LoggerFactory.getLogger(DuoService.class); - - /** - * Pattern which matches valid Duo responses. Each response is made up of - * two sections, separated from each other by a colon, where each section - * is a signed Duo cookie. - */ - private static final Pattern RESPONSE_FORMAT = Pattern.compile("([^:]+):([^:]+)"); - - /** - * The index of the capturing group within RESPONSE_FORMAT which - * contains the DUO_RESPONSE cookie signed by the secret key. - */ - private static final int DUO_COOKIE_GROUP = 1; - - /** - * The index of the capturing group within RESPONSE_FORMAT which - * contains the APPLICATION cookie signed by the application key. - */ - private static final int APP_COOKIE_GROUP = 2; - - /** - * The amount of time that each generated cookie remains valid, in seconds. - */ - private static final int COOKIE_EXPIRATION_TIME = 300; - - /** - * Service for retrieving Duo configuration information. - */ - @Inject - private ConfigurationService confService; - - /** - * Creates and signs a new request to verify the identity of the given - * user. This request may ultimately be sent to Duo, resulting in a signed - * response from Duo if that verification succeeds. - * - * @param authenticatedUser - * The user whose identity should be verified. - * - * @return - * A signed user verification request which can be sent to Duo. - * - * @throws GuacamoleException - * If required Duo-specific configuration options are missing or - * invalid, or if an error prevents generation of the signature. - */ - public String createSignedRequest(AuthenticatedUser authenticatedUser) - throws GuacamoleException { - - // Generate a cookie associating the username with the integration key - DuoCookie cookie = new DuoCookie(authenticatedUser.getIdentifier(), - confService.getIntegrationKey(), - DuoCookie.currentTimestamp() + COOKIE_EXPIRATION_TIME); - - // Sign cookie with secret key - SignedDuoCookie duoCookie = new SignedDuoCookie(cookie, - SignedDuoCookie.Type.DUO_REQUEST, - confService.getSecretKey()); - - // Sign cookie with application key - SignedDuoCookie appCookie = new SignedDuoCookie(cookie, - SignedDuoCookie.Type.APPLICATION, - confService.getApplicationKey()); - - // Return signed request containing both signed cookies, separated by - // a colon (as required by Duo) - return duoCookie + ":" + appCookie; - - } - - /** - * Returns whether the given signed response is a valid response from Duo - * which verifies the identity of the given user. If the given response is - * invalid or does not verify the identity of the given user (including if - * it is a valid response which verifies the identity of a DIFFERENT user), - * false is returned. - * - * @param authenticatedUser - * The user that the given signed response should verify. - * - * @param signedResponse - * The signed response received from Duo in response to a signed - * request. - * - * @return - * true if the signed response is a valid response from Duo AND verifies - * the identity of the given user, false otherwise. - * - * @throws GuacamoleException - * If required Duo-specific configuration options are missing or - * invalid, or if an error occurs prevents validation of the signature. - */ - public boolean isValidSignedResponse(AuthenticatedUser authenticatedUser, - String signedResponse) throws GuacamoleException { - - SignedDuoCookie duoCookie; - SignedDuoCookie appCookie; - - // Retrieve username from externally-authenticated user - String username = authenticatedUser.getIdentifier(); - - // Retrieve Duo-specific keys from configuration - String applicationKey = confService.getApplicationKey(); - String integrationKey = confService.getIntegrationKey(); - String secretKey = confService.getSecretKey(); - - try { - - // Verify format of response - Matcher matcher = RESPONSE_FORMAT.matcher(signedResponse); - if (!matcher.matches()) { - logger.debug("Duo response is not in correct format."); - return false; - } - - // Parse signed cookie defining the user verified by Duo - duoCookie = SignedDuoCookie.parseSignedDuoCookie(secretKey, - matcher.group(DUO_COOKIE_GROUP)); - - // Parse signed cookie defining the user this application - // originally requested - appCookie = SignedDuoCookie.parseSignedDuoCookie(applicationKey, - matcher.group(APP_COOKIE_GROUP)); - - } - - // Simply return false if signature fails to verify - catch (GuacamoleException e) { - logger.debug("Duo signature verification failed.", e); - return false; - } - - // Verify neither cookie is expired - if (duoCookie.isExpired() || appCookie.isExpired()) { - logger.debug("Duo response contained expired cookie(s)."); - return false; - } - - // Verify the cookies in the response have the correct types - if (duoCookie.getType() != SignedDuoCookie.Type.DUO_RESPONSE - || appCookie.getType() != SignedDuoCookie.Type.APPLICATION) { - logger.debug("Duo response did not contain correct cookie type(s)."); - return false; - } - - // Verify integration key matches both cookies - if (!duoCookie.getIntegrationKey().equals(integrationKey) - || !appCookie.getIntegrationKey().equals(integrationKey)) { - logger.debug("Integration key of Duo response is incorrect."); - return false; - } - - // Verify both cookies are for the current user - if (!duoCookie.getUsername().equals(username) - || !appCookie.getUsername().equals(username)) { - logger.debug("Username of Duo response is incorrect."); - return false; - } - - // All verifications tests pass - return true; - - } - -} diff --git a/extensions/guacamole-auth-duo/src/main/java/org/apache/guacamole/auth/duo/api/SignedDuoCookie.java b/extensions/guacamole-auth-duo/src/main/java/org/apache/guacamole/auth/duo/api/SignedDuoCookie.java deleted file mode 100644 index c959acdd16..0000000000 --- a/extensions/guacamole-auth-duo/src/main/java/org/apache/guacamole/auth/duo/api/SignedDuoCookie.java +++ /dev/null @@ -1,332 +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. - */ - -package org.apache.guacamole.auth.duo.api; - -import com.google.common.io.BaseEncoding; -import java.io.UnsupportedEncodingException; -import java.security.InvalidKeyException; -import java.security.NoSuchAlgorithmException; -import java.util.regex.Matcher; -import java.util.regex.Pattern; -import javax.crypto.Mac; -import javax.crypto.spec.SecretKeySpec; -import org.apache.guacamole.GuacamoleClientException; -import org.apache.guacamole.GuacamoleException; -import org.apache.guacamole.GuacamoleServerException; - -/** - * A DuoCookie which is cryptographically signed with a provided key using - * HMAC-SHA1. - */ -public class SignedDuoCookie extends DuoCookie { - - /** - * Pattern which matches valid signed cookies. Like unsigned cookies, each - * signed cookie is made up of three sections, separated from each other by - * pipe symbols ("|"). - */ - private static final Pattern SIGNED_COOKIE_FORMAT = Pattern.compile("([^|]+)\\|([^|]+)\\|([0-9a-f]+)"); - - /** - * The index of the capturing group within SIGNED_COOKIE_FORMAT which - * contains the cookie type prefix. - */ - private static final int PREFIX_GROUP = 1; - - /** - * The index of the capturing group within SIGNED_COOKIE_FORMAT which - * contains the cookie's base64-encoded data. - */ - private static final int DATA_GROUP = 2; - - /** - * The index of the capturing group within SIGNED_COOKIE_FORMAT which - * contains the signature. - */ - private static final int SIGNATURE_GROUP = 3; - - /** - * The signature algorithm that should be used to sign the cookie, as - * defined by: - * http://docs.oracle.com/javase/7/docs/technotes/guides/security/StandardNames.html#Mac - */ - private static final String SIGNATURE_ALGORITHM = "HmacSHA1"; - - /** - * The type of a signed Duo cookie. Each signed Duo cookie has an - * associated type which determines the prefix included in the string - * representation of that cookie. As that type is included in the data - * that is signed, different types will result in different signatures, - * even if the data portion of the cookie is otherwise identical. - */ - public enum Type { - - /** - * A Duo cookie which has been signed with the secret key for inclusion - * in a Duo request. - */ - DUO_REQUEST("TX"), - - /** - * A Duo cookie which has been signed with the secret key by Duo and - * was included in a Duo response. - */ - DUO_RESPONSE("AUTH"), - - /** - * A Duo cookie which has been signed with the application key for - * inclusion in a Duo request. Such cookies are also included in Duo - * responses, for verification by the application. - */ - APPLICATION("APP"); - - /** - * The prefix associated with the Duo cookie type. This prefix will - * be included in the string representation of the cookie. - */ - private final String prefix; - - /** - * Creates a new Duo cookie type associated with the given string - * prefix. This prefix will be included in the string representation of - * the cookie. - * - * @param prefix - * The prefix to associated with the Duo cookie type. - */ - Type(String prefix) { - this.prefix = prefix; - } - - /** - * Returns the prefix associated with the Duo cookie type. - * - * @return - * The prefix to associated with this Duo cookie type. - */ - public String getPrefix() { - return prefix; - } - - /** - * Returns the cookie type associated with the given prefix. If no such - * cookie type exists, null is returned. - * - * @param prefix - * The prefix of the cookie type to search for. - * - * @return - * The cookie type associated with the given prefix, or null if no - * such cookie type exists. - */ - public static Type fromPrefix(String prefix) { - - // Search through all defined cookie types for the given prefix - for (Type type : Type.values()) { - if (type.getPrefix().equals(prefix)) - return type; - } - - // No such cookie type exists - return null; - - } - - } - - /** - * The type of this Duo cookie. - */ - private final Type type; - - /** - * The signature produced when the cookie was signed with HMAC-SHA1. The - * signature covers the prefix of the type and the cookie's base64-encoded - * data, separated by a pipe symbol. - */ - private final String signature; - - /** - * Creates a new SignedDuoCookie which describes the identity of a user - * being verified and is cryptographically signed with HMAC-SHA1 by a given - * key. - * - * @param cookie - * The cookie defining the identity being verified. - * - * @param type - * The type of the cookie being created. - * - * @param key - * The key to use to generate the cryptographic signature. This key - * will not be stored within the cookie. - * - * @throws GuacamoleException - * If the given signing key is invalid. - */ - public SignedDuoCookie(DuoCookie cookie, Type type, String key) - throws GuacamoleException { - - // Init underlying cookie - super(cookie.getUsername(), cookie.getIntegrationKey(), - cookie.getExpirationTimestamp()); - - // Store cookie type and signature - this.type = type; - this.signature = sign(key, type.getPrefix() + "|" + cookie.toString()); - - } - - /** - * Signs the given arbitrary string data with the given key using the - * algorithm defined by SIGNATURE_ALGORITHM. Both the data and the key will - * be interpreted as UTF-8 bytes. - * - * @param key - * The key which should be used to sign the given data. - * - * @param data - * The data being signed. - * - * @return - * The signature produced by signing the given data with the given key, - * encoded as lowercase hexadecimal. - * - * @throws GuacamoleException - * If the given signing key is invalid. - */ - private static String sign(String key, String data) throws GuacamoleException { - - try { - - // Attempt to sign UTF-8 bytes of provided data - Mac mac = Mac.getInstance(SIGNATURE_ALGORITHM); - mac.init(new SecretKeySpec(key.getBytes("UTF-8"), SIGNATURE_ALGORITHM)); - - // Return signature as hex - return BaseEncoding.base16().lowerCase().encode(mac.doFinal(data.getBytes("UTF-8"))); - - } - - // Re-throw any errors which prevent signature - catch (InvalidKeyException e){ - throw new GuacamoleServerException("Signing key is invalid.", e); - } - - // Throw hard errors if standard pieces of Java are missing - catch (UnsupportedEncodingException e) { - throw new UnsupportedOperationException("Unexpected lack of UTF-8 support.", e); - } - catch (NoSuchAlgorithmException e) { - throw new UnsupportedOperationException("Unexpected lack of support " - + "for required signature algorithm " - + "\"" + SIGNATURE_ALGORITHM + "\".", e); - } - - } - - /** - * Returns the type of this Duo cookie. The Duo cookie type is dictated - * by the context of the cookie's use, and is included with the cookie's - * underlying data when generating the signature. - * - * @return - * The type of this Duo cookie. - */ - public Type getType() { - return type; - } - - /** - * Returns the signature produced when the cookie was signed with HMAC-SHA1. - * The signature covers the prefix of the cookie's type and the cookie's - * base64-encoded data, separated by a pipe symbol. - * - * @return - * The signature produced when the cookie was signed with HMAC-SHA1. - */ - public String getSignature() { - return signature; - } - - /** - * Parses a signed Duo cookie string, such as that produced by the - * toString() function or received from the Duo service, producing a new - * SignedDuoCookie object containing the associated cookie data and - * signature. If the given string is not a valid Duo cookie, or if the - * signature is incorrect, an exception is thrown. Note that the cookie may - * be expired, and must be checked for expiration prior to actual use. - * - * @param key - * The key that was used to sign the Duo cookie. - * - * @param str - * The Duo cookie string to parse. - * - * @return - * A new SignedDuoCookie object containing the same data and signature - * as the given Duo cookie string. - * - * @throws GuacamoleException - * If the given string is not a valid Duo cookie string, or if the - * signature of the cookie is invalid. - */ - public static SignedDuoCookie parseSignedDuoCookie(String key, String str) - throws GuacamoleException { - - // Verify format of provided data - Matcher matcher = SIGNED_COOKIE_FORMAT.matcher(str); - if (!matcher.matches()) - throw new GuacamoleClientException("Format of signed Duo cookie " - + "is invalid."); - - // Parse type from prefix - Type type = Type.fromPrefix(matcher.group(PREFIX_GROUP)); - if (type == null) - throw new GuacamoleClientException("Invalid Duo cookie prefix."); - - // Parse cookie from base64-encoded data - DuoCookie cookie = DuoCookie.parseDuoCookie(matcher.group(DATA_GROUP)); - - // Verify signature of cookie - SignedDuoCookie signedCookie = new SignedDuoCookie(cookie, type, key); - if (!signedCookie.getSignature().equals(matcher.group(SIGNATURE_GROUP))) - throw new GuacamoleClientException("Duo cookie has incorrect signature."); - - // Cookie has valid signature and has parsed successfully - return signedCookie; - - } - - /** - * Returns the string representation of this SignedDuoCookie. The format - * used is identical to that required by the Duo service: the type prefix, - * base64-encoded cookie data, and HMAC-SHA1 signature separated by pipe - * symbols ("|"). - * - * @return - * The string representation of this SignedDuoCookie. - */ - @Override - public String toString() { - return type.getPrefix() + "|" + super.toString() + "|" + signature; - } - -} diff --git a/extensions/guacamole-auth-duo/src/main/java/org/apache/guacamole/auth/duo/conf/ConfigurationService.java b/extensions/guacamole-auth-duo/src/main/java/org/apache/guacamole/auth/duo/conf/ConfigurationService.java index 40ccde9e00..212b4a6182 100644 --- a/extensions/guacamole-auth-duo/src/main/java/org/apache/guacamole/auth/duo/conf/ConfigurationService.java +++ b/extensions/guacamole-auth-duo/src/main/java/org/apache/guacamole/auth/duo/conf/ConfigurationService.java @@ -20,9 +20,12 @@ package org.apache.guacamole.auth.duo.conf; import com.google.inject.Inject; +import java.net.URI; import org.apache.guacamole.GuacamoleException; import org.apache.guacamole.environment.Environment; +import org.apache.guacamole.properties.IntegerGuacamoleProperty; import org.apache.guacamole.properties.StringGuacamoleProperty; +import org.apache.guacamole.properties.URIGuacamoleProperty; /** * Service for retrieving configuration information regarding the Duo @@ -56,11 +59,11 @@ public class ConfigurationService { * key received from Duo for verifying Guacamole users. This value MUST be * exactly 20 characters. */ - private static final StringGuacamoleProperty DUO_INTEGRATION_KEY = + private static final StringGuacamoleProperty DUO_CLIENT_ID = new StringGuacamoleProperty() { @Override - public String getName() { return "duo-integration-key"; } + public String getName() { return "duo-client-id"; } }; @@ -69,26 +72,38 @@ public class ConfigurationService { * received from Duo for verifying Guacamole users. This value MUST be * exactly 40 characters. */ - private static final StringGuacamoleProperty DUO_SECRET_KEY = + private static final StringGuacamoleProperty DUO_CLIENT_SECRET = new StringGuacamoleProperty() { @Override - public String getName() { return "duo-secret-key"; } + public String getName() { return "duo-client-secret"; } }; - + /** - * The property within guacamole.properties which defines the arbitrary - * random key which was generated for Guacamole. Note that this value is not - * provided by Duo, but is expected to be generated by the administrator of - * the system hosting Guacamole. This value MUST be at least 40 characters. + * The property within guacamole.properties which defines the redirect URL + * that Duo will call after the second factor has been completed. This + * should be the URL used to access Guacamole. */ - private static final StringGuacamoleProperty DUO_APPLICATION_KEY = - new StringGuacamoleProperty() { - + private static final URIGuacamoleProperty DUO_REDIRECT_URL = + new URIGuacamoleProperty() { + @Override - public String getName() { return "duo-application-key"; } - + public String getName() { return "duo-redirect-url"; } + + }; + + /** + * The property that configures the timeout, in seconds, of in-progress + * Duo authentication attempts. Authentication attempts that take longer + * than this period of time will be invalidated. + */ + private static final IntegerGuacamoleProperty DUO_AUTH_TIMEOUT = + new IntegerGuacamoleProperty() { + + @Override + public String getName() { return "duo-auth-timeout"; } + }; /** @@ -110,51 +125,65 @@ public String getAPIHostname() throws GuacamoleException { } /** - * Returns the integration key received from Duo for verifying Guacamole - * users, as defined in guacamole.properties by the "duo-integration-key" + * Returns the Duo client id received from Duo for verifying Guacamole + * users, as defined in guacamole.properties by the "duo-client-id" * property. This value MUST be exactly 20 characters. * * @return - * The integration key received from Duo for verifying Guacamole - * users. + * The client id received from Duo for verifying Guacamole users. * * @throws GuacamoleException * If the associated property within guacamole.properties is missing. */ - public String getIntegrationKey() throws GuacamoleException { - return environment.getRequiredProperty(DUO_INTEGRATION_KEY); + public String getClientId() throws GuacamoleException { + return environment.getRequiredProperty(DUO_CLIENT_ID); } /** - * Returns the secret key received from Duo for verifying Guacamole users, - * as defined in guacamole.properties by the "duo-secret-key" property. This - * value MUST be exactly 20 characters. + * Returns the client secert received from Duo for verifying Guacamole users, + * as defined in guacamole.properties by the "duo-client-secert" property. + * This value MUST be exactly 20 characters. * * @return - * The secret key received from Duo for verifying Guacamole users. + * The client secret received from Duo for verifying Guacamole users. * * @throws GuacamoleException * If the associated property within guacamole.properties is missing. */ - public String getSecretKey() throws GuacamoleException { - return environment.getRequiredProperty(DUO_SECRET_KEY); + public String getClientSecret() throws GuacamoleException { + return environment.getRequiredProperty(DUO_CLIENT_SECRET); } - + /** - * Returns the arbitrary random key which was generated for Guacamole, as - * defined in guacamole.properties by the "duo-application-key" property. - * Note that this value is not provided by Duo, but is expected to be - * generated by the administrator of the system hosting Guacamole. This - * value MUST be at least 40 characters. - * + * Return the callback URL that will be called by Duo after authentication + * with Duo has been completed. This should be the URL to return the user + * to the Guacamole interface, and will be a full URL. + * * @return - * The arbitrary random key which was generated for Guacamole. - * - * @throws GuacamoleException - * If the associated property within guacamole.properties is missing. + * The URL for Duo to use to callback to the Guacamole interface after + * authentication has been completed. + * + * @throws GuacamoleException + * If guacamole.properties cannot be read, or if the property is not + * defined. + */ + public URI getRedirectUrl() throws GuacamoleException { + return environment.getRequiredProperty(DUO_REDIRECT_URL); + } + + /** + * Return the number of seconds after which in-progress authentication attempts with + * Duo should be invalidated. The default is 30 seconds. + * + * @return + * The number of seconds after which in-progress Duo MFA attempts should + * be invalidated. + * + * @throws GuacamoleException + * If guacamole.properties cannot be parsed. */ - public String getApplicationKey() throws GuacamoleException { - return environment.getRequiredProperty(DUO_APPLICATION_KEY); + public int getAuthTimeout() throws GuacamoleException { + return environment.getProperty(DUO_AUTH_TIMEOUT, 30); } } diff --git a/extensions/guacamole-auth-duo/src/main/java/org/apache/guacamole/auth/duo/form/DuoSignedResponseField.java b/extensions/guacamole-auth-duo/src/main/java/org/apache/guacamole/auth/duo/form/DuoSignedResponseField.java deleted file mode 100644 index df46a31220..0000000000 --- a/extensions/guacamole-auth-duo/src/main/java/org/apache/guacamole/auth/duo/form/DuoSignedResponseField.java +++ /dev/null @@ -1,98 +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. - */ - -package org.apache.guacamole.auth.duo.form; - -import org.apache.guacamole.form.Field; - -/** - * A custom field type which uses the DuoWeb API to produce a signed response - * for a particular user. The signed response serves as an additional - * authentication factor, as it cryptographically verifies possession of the - * physical device associated with that user's Duo account. - */ -public class DuoSignedResponseField extends Field { - - /** - * The name of the HTTP parameter which an instance of this field will - * populate within a user's credentials. - */ - public static final String PARAMETER_NAME = "guac-duo-signed-response"; - - /** - * The unique name associated with this field type. - */ - private static final String FIELD_TYPE_NAME = "GUAC_DUO_SIGNED_RESPONSE"; - - /** - * The hostname of the DuoWeb API endpoint. - */ - private final String apiHost; - - /** - * The signed request generated by a call to DuoWeb.signRequest(). - */ - private final String signedRequest; - - /** - * Creates a new field which uses the DuoWeb API to prompt the user for - * additional credentials. The provided credentials, if valid, will - * ultimately be verified by Duo's service, resulting in a signed response - * which can be cryptographically verified. - * - * @param apiHost - * The hostname of the DuoWeb API endpoint. - * - * @param signedRequest - * A signed request generated for the user in question by a call to - * DuoWeb.signRequest(). - */ - public DuoSignedResponseField(String apiHost, String signedRequest) { - - // Init base field type properties - super(PARAMETER_NAME, FIELD_TYPE_NAME); - - // Init Duo-specific properties - this.apiHost = apiHost; - this.signedRequest = signedRequest; - - } - - /** - * Returns the hostname of the DuoWeb API endpoint. - * - * @return - * The hostname of the DuoWeb API endpoint. - */ - public String getApiHost() { - return apiHost; - } - - /** - * Returns the signed request string, which must have been generated by a - * call to DuoWeb.signRequest(). - * - * @return - * The signed request generated by a call to DuoWeb.signRequest(). - */ - public String getSignedRequest() { - return signedRequest; - } - -} diff --git a/extensions/guacamole-auth-duo/src/main/resources/config/duoConfig.js b/extensions/guacamole-auth-duo/src/main/resources/config/duoConfig.js deleted file mode 100644 index 43c37dc0cf..0000000000 --- a/extensions/guacamole-auth-duo/src/main/resources/config/duoConfig.js +++ /dev/null @@ -1,33 +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. - */ - -/** - * Config block which registers Duo-specific field types. - */ -angular.module('guacDuo').config(['formServiceProvider', - function guacDuoConfig(formServiceProvider) { - - // Define field for the signed response from the Duo service - formServiceProvider.registerFieldType('GUAC_DUO_SIGNED_RESPONSE', { - module : 'guacDuo', - controller : 'duoSignedResponseController', - templateUrl : 'app/ext/duo/templates/duoSignedResponseField.html' - }); - -}]); diff --git a/extensions/guacamole-auth-duo/src/main/resources/controllers/duoSignedResponseController.js b/extensions/guacamole-auth-duo/src/main/resources/controllers/duoSignedResponseController.js deleted file mode 100644 index b4ca4f360a..0000000000 --- a/extensions/guacamole-auth-duo/src/main/resources/controllers/duoSignedResponseController.js +++ /dev/null @@ -1,86 +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. - */ - -/** - * Controller for the "GUAC_DUO_SIGNED_RESPONSE" field which uses the DuoWeb - * API to prompt the user for additional credentials, ultimately receiving a - * signed response from the Duo service. - */ -angular.module('guacDuo').controller('duoSignedResponseController', ['$scope', '$element', - function duoSignedResponseController($scope, $element) { - - /** - * The iframe which contains the Duo authentication interface. - * - * @type HTMLIFrameElement - */ - var iframe = $element.find('iframe')[0]; - - /** - * The submit button which should be used to submit the login form once - * the Duo response has been received. - * - * @type HTMLInputElement - */ - var submit = $element.find('input[type="submit"]')[0]; - - /** - * Whether the Duo interface has finished loading within the iframe. - * - * @type Boolean - */ - $scope.duoInterfaceLoaded = false; - - /** - * Submits the signed response from Duo once the user has authenticated. - * This is a callback invoked by the DuoWeb API after the user has been - * verified and the signed response has been received. - * - * @param {HTMLFormElement} form - * The form element provided by the DuoWeb API containing the signed - * response as the value of an input field named "sig_response". - */ - var submitSignedResponse = function submitSignedResponse(form) { - - // Update model to match received response - $scope.$apply(function updateModel() { - $scope.model = form.elements['sig_response'].value; - }); - - // Submit updated credentials - submit.click(); - - }; - - // Update Duo loaded state when iframe finishes loading - iframe.onload = function duoLoaded() { - $scope.$apply(function updateLoadedState() { - $scope.duoInterfaceLoaded = true; - }); - }; - - // Initialize Duo interface within iframe - Duo.init({ - iframe : iframe, - host : $scope.field.apiHost, - sig_request : $scope.field.signedRequest, - submit_callback : submitSignedResponse - }); - -}]); diff --git a/extensions/guacamole-auth-duo/src/main/resources/guac-manifest.json b/extensions/guacamole-auth-duo/src/main/resources/guac-manifest.json index 5d98adca4f..2a9d727a91 100644 --- a/extensions/guacamole-auth-duo/src/main/resources/guac-manifest.json +++ b/extensions/guacamole-auth-duo/src/main/resources/guac-manifest.json @@ -20,18 +20,6 @@ "translations/pt.json", "translations/ru.json", "translations/zh.json" - ], - - "js" : [ - "duo.min.js" - ], - - "css" : [ - "duo.min.css" - ], - - "resources" : { - "templates/duoSignedResponseField.html" : "text/html" - } + ] } diff --git a/extensions/guacamole-auth-duo/src/main/resources/lib/DuoWeb/Duo-Web-v2.js b/extensions/guacamole-auth-duo/src/main/resources/lib/DuoWeb/Duo-Web-v2.js deleted file mode 100644 index a02a95756d..0000000000 --- a/extensions/guacamole-auth-duo/src/main/resources/lib/DuoWeb/Duo-Web-v2.js +++ /dev/null @@ -1,366 +0,0 @@ -/** - * Duo Web SDK v2 - * Copyright 2015, Duo Security - */ -window.Duo = (function(document, window) { - var DUO_MESSAGE_FORMAT = /^(?:AUTH|ENROLL)+\|[A-Za-z0-9\+\/=]+\|[A-Za-z0-9\+\/=]+$/; - var DUO_ERROR_FORMAT = /^ERR\|[\w\s\.\(\)]+$/; - - var iframeId = 'duo_iframe', - postAction = '', - postArgument = 'sig_response', - host, - sigRequest, - duoSig, - appSig, - iframe, - submitCallback; - - function throwError(message, url) { - throw new Error( - 'Duo Web SDK error: ' + message + - (url ? ('\n' + 'See ' + url + ' for more information') : '') - ); - } - - function hyphenize(str) { - return str.replace(/([a-z])([A-Z])/, '$1-$2').toLowerCase(); - } - - // cross-browser data attributes - function getDataAttribute(element, name) { - if ('dataset' in element) { - return element.dataset[name]; - } else { - return element.getAttribute('data-' + hyphenize(name)); - } - } - - // cross-browser event binding/unbinding - function on(context, event, fallbackEvent, callback) { - if ('addEventListener' in window) { - context.addEventListener(event, callback, false); - } else { - context.attachEvent(fallbackEvent, callback); - } - } - - function off(context, event, fallbackEvent, callback) { - if ('removeEventListener' in window) { - context.removeEventListener(event, callback, false); - } else { - context.detachEvent(fallbackEvent, callback); - } - } - - function onReady(callback) { - on(document, 'DOMContentLoaded', 'onreadystatechange', callback); - } - - function offReady(callback) { - off(document, 'DOMContentLoaded', 'onreadystatechange', callback); - } - - function onMessage(callback) { - on(window, 'message', 'onmessage', callback); - } - - function offMessage(callback) { - off(window, 'message', 'onmessage', callback); - } - - /** - * Parse the sig_request parameter, throwing errors if the token contains - * a server error or if the token is invalid. - * - * @param {String} sig Request token - */ - function parseSigRequest(sig) { - if (!sig) { - // nothing to do - return; - } - - // see if the token contains an error, throwing it if it does - if (sig.indexOf('ERR|') === 0) { - throwError(sig.split('|')[1]); - } - - // validate the token - if (sig.indexOf(':') === -1 || sig.split(':').length !== 2) { - throwError( - 'Duo was given a bad token. This might indicate a configuration ' + - 'problem with one of Duo\'s client libraries.', - 'https://www.duosecurity.com/docs/duoweb#first-steps' - ); - } - - var sigParts = sig.split(':'); - - // hang on to the token, and the parsed duo and app sigs - sigRequest = sig; - duoSig = sigParts[0]; - appSig = sigParts[1]; - - return { - sigRequest: sig, - duoSig: sigParts[0], - appSig: sigParts[1] - }; - } - - /** - * This function is set up to run when the DOM is ready, if the iframe was - * not available during `init`. - */ - function onDOMReady() { - iframe = document.getElementById(iframeId); - - if (!iframe) { - throw new Error( - 'This page does not contain an iframe for Duo to use.' + - 'Add an element like ' + - 'to this page. ' + - 'See https://www.duosecurity.com/docs/duoweb#3.-show-the-iframe ' + - 'for more information.' - ); - } - - // we've got an iframe, away we go! - ready(); - - // always clean up after yourself - offReady(onDOMReady); - } - - /** - * Validate that a MessageEvent came from the Duo service, and that it - * is a properly formatted payload. - * - * The Google Chrome sign-in page injects some JS into pages that also - * make use of postMessage, so we need to do additional validation above - * and beyond the origin. - * - * @param {MessageEvent} event Message received via postMessage - */ - function isDuoMessage(event) { - return Boolean( - event.origin === ('https://' + host) && - typeof event.data === 'string' && - ( - event.data.match(DUO_MESSAGE_FORMAT) || - event.data.match(DUO_ERROR_FORMAT) - ) - ); - } - - /** - * Validate the request token and prepare for the iframe to become ready. - * - * All options below can be passed into an options hash to `Duo.init`, or - * specified on the iframe using `data-` attributes. - * - * Options specified using the options hash will take precedence over - * `data-` attributes. - * - * Example using options hash: - * ```javascript - * Duo.init({ - * iframe: "some_other_id", - * host: "api-main.duo.test", - * sig_request: "...", - * post_action: "/auth", - * post_argument: "resp" - * }); - * ``` - * - * Example using `data-` attributes: - * ``` - * - * ``` - * - * @param {Object} options - * @param {String} options.iframe The iframe, or id of an iframe to set up - * @param {String} options.host Hostname - * @param {String} options.sig_request Request token - * @param {String} [options.post_action=''] URL to POST back to after successful auth - * @param {String} [options.post_argument='sig_response'] Parameter name to use for response token - * @param {Function} [options.submit_callback] If provided, duo will not submit the form instead execute - * the callback function with reference to the "duo_form" form object - * submit_callback can be used to prevent the webpage from reloading. - */ - function init(options) { - if (options) { - if (options.host) { - host = options.host; - } - - if (options.sig_request) { - parseSigRequest(options.sig_request); - } - - if (options.post_action) { - postAction = options.post_action; - } - - if (options.post_argument) { - postArgument = options.post_argument; - } - - if (options.iframe) { - if ('tagName' in options.iframe) { - iframe = options.iframe; - } else if (typeof options.iframe === 'string') { - iframeId = options.iframe; - } - } - - if (typeof options.submit_callback === 'function') { - submitCallback = options.submit_callback; - } - } - - // if we were given an iframe, no need to wait for the rest of the DOM - if (iframe) { - ready(); - } else { - // try to find the iframe in the DOM - iframe = document.getElementById(iframeId); - - // iframe is in the DOM, away we go! - if (iframe) { - ready(); - } else { - // wait until the DOM is ready, then try again - onReady(onDOMReady); - } - } - - // always clean up after yourself! - offReady(init); - } - - /** - * This function is called when a message was received from another domain - * using the `postMessage` API. Check that the event came from the Duo - * service domain, and that the message is a properly formatted payload, - * then perform the post back to the primary service. - * - * @param event Event object (contains origin and data) - */ - function onReceivedMessage(event) { - if (isDuoMessage(event)) { - // the event came from duo, do the post back - doPostBack(event.data); - - // always clean up after yourself! - offMessage(onReceivedMessage); - } - } - - /** - * Point the iframe at Duo, then wait for it to postMessage back to us. - */ - function ready() { - if (!host) { - host = getDataAttribute(iframe, 'host'); - - if (!host) { - throwError( - 'No API hostname is given for Duo to use. Be sure to pass ' + - 'a `host` parameter to Duo.init, or through the `data-host` ' + - 'attribute on the iframe element.', - 'https://www.duosecurity.com/docs/duoweb#3.-show-the-iframe' - ); - } - } - - if (!duoSig || !appSig) { - parseSigRequest(getDataAttribute(iframe, 'sigRequest')); - - if (!duoSig || !appSig) { - throwError( - 'No valid signed request is given. Be sure to give the ' + - '`sig_request` parameter to Duo.init, or use the ' + - '`data-sig-request` attribute on the iframe element.', - 'https://www.duosecurity.com/docs/duoweb#3.-show-the-iframe' - ); - } - } - - // if postAction/Argument are defaults, see if they are specified - // as data attributes on the iframe - if (postAction === '') { - postAction = getDataAttribute(iframe, 'postAction') || postAction; - } - - if (postArgument === 'sig_response') { - postArgument = getDataAttribute(iframe, 'postArgument') || postArgument; - } - - // point the iframe at Duo - iframe.src = [ - 'https://', host, '/frame/web/v1/auth?tx=', duoSig, - '&parent=', encodeURIComponent(document.location.href), - '&v=2.3' - ].join(''); - - // listen for the 'message' event - onMessage(onReceivedMessage); - } - - /** - * We received a postMessage from Duo. POST back to the primary service - * with the response token, and any additional user-supplied parameters - * given in form#duo_form. - */ - function doPostBack(response) { - // create a hidden input to contain the response token - var input = document.createElement('input'); - input.type = 'hidden'; - input.name = postArgument; - input.value = response + ':' + appSig; - - // user may supply their own form with additional inputs - var form = document.getElementById('duo_form'); - - // if the form doesn't exist, create one - if (!form) { - form = document.createElement('form'); - - // insert the new form after the iframe - iframe.parentElement.insertBefore(form, iframe.nextSibling); - } - - // make sure we are actually posting to the right place - form.method = 'POST'; - form.action = postAction; - - // add the response token input to the form - form.appendChild(input); - - // away we go! - if (typeof submitCallback === "function") { - submitCallback.call(null, form); - } else { - form.submit(); - } - } - - // when the DOM is ready, initialize - // note that this will get cleaned up if the user calls init directly! - onReady(init); - - return { - init: init, - _parseSigRequest: parseSigRequest, - _isDuoMessage: isDuoMessage, - _doPostBack: doPostBack - }; -}(document, window)); diff --git a/extensions/guacamole-auth-duo/src/main/resources/lib/DuoWeb/LICENSE.js b/extensions/guacamole-auth-duo/src/main/resources/lib/DuoWeb/LICENSE.js deleted file mode 100644 index 58ead21752..0000000000 --- a/extensions/guacamole-auth-duo/src/main/resources/lib/DuoWeb/LICENSE.js +++ /dev/null @@ -1,27 +0,0 @@ -/* - * Copyright (c) 2011, Duo Security, Inc. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ \ No newline at end of file diff --git a/extensions/guacamole-auth-duo/src/main/resources/styles/duo.css b/extensions/guacamole-auth-duo/src/main/resources/styles/duo.css deleted file mode 100644 index 6d01a85cdd..0000000000 --- a/extensions/guacamole-auth-duo/src/main/resources/styles/duo.css +++ /dev/null @@ -1,62 +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. - */ - - -.duo-signature-response-field-container { - height: 100%; - width: 100%; - position: fixed; - left: 0; - top: 0; - display: table; - background: white; -} - -.duo-signature-response-field { - width: 100%; - display: table-cell; - vertical-align: middle; -} - -.duo-signature-response-field input[type="submit"] { - display: none !important; -} - -.duo-signature-response-field iframe { - width: 100%; - max-width: 620px; - height: 330px; - border: none; - box-shadow: 4px 4px 8px rgba(0, 0, 0, 0.5); - display: block; - margin: 1.5em auto; -} - -.duo-signature-response-field iframe { - opacity: 1; - -webkit-transition: opacity 0.125s; - -moz-transition: opacity 0.125s; - -ms-transition: opacity 0.125s; - -o-transition: opacity 0.125s; - transition: opacity 0.125s; -} - -.duo-signature-response-field.loading iframe { - opacity: 0; -} diff --git a/extensions/guacamole-auth-duo/src/main/resources/templates/duoSignedResponseField.html b/extensions/guacamole-auth-duo/src/main/resources/templates/duoSignedResponseField.html deleted file mode 100644 index e51e1900b1..0000000000 --- a/extensions/guacamole-auth-duo/src/main/resources/templates/duoSignedResponseField.html +++ /dev/null @@ -1,6 +0,0 @@ -
-
- - -
-
diff --git a/extensions/guacamole-auth-sso/modules/guacamole-auth-sso-base/src/main/java/org/apache/guacamole/auth/sso/NonceService.java b/extensions/guacamole-auth-sso/modules/guacamole-auth-sso-base/src/main/java/org/apache/guacamole/auth/sso/NonceService.java index 5717794fdc..d43a0047bb 100644 --- a/extensions/guacamole-auth-sso/modules/guacamole-auth-sso-base/src/main/java/org/apache/guacamole/auth/sso/NonceService.java +++ b/extensions/guacamole-auth-sso/modules/guacamole-auth-sso-base/src/main/java/org/apache/guacamole/auth/sso/NonceService.java @@ -19,11 +19,11 @@ package org.apache.guacamole.auth.sso; -import com.google.inject.Inject; import java.util.Iterator; import java.util.Locale; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; +import org.apache.guacamole.net.auth.IdentifierGenerator; /** * Service for generating and validating single-use random tokens (nonces). @@ -31,12 +31,6 @@ */ public class NonceService { - /** - * Generator of arbitrary, unique, unpredictable identifiers. - */ - @Inject - private IdentifierGenerator idGenerator; - /** * Map of all generated nonces to their corresponding expiration timestamps. * This Map must be periodically swept of expired nonces to avoid growing @@ -107,7 +101,7 @@ public String generate(long maxAge) { sweepExpiredNonces(); // Generate and store nonce, along with expiration timestamp - String nonce = idGenerator.generateIdentifier(NONCE_BITS, false); + String nonce = IdentifierGenerator.generateIdentifier(NONCE_BITS, false); nonces.put(nonce, System.currentTimeMillis() + maxAge); return nonce; diff --git a/extensions/guacamole-auth-sso/modules/guacamole-auth-sso-saml/src/main/java/org/apache/guacamole/auth/saml/acs/SAMLAuthenticationSession.java b/extensions/guacamole-auth-sso/modules/guacamole-auth-sso-saml/src/main/java/org/apache/guacamole/auth/saml/acs/SAMLAuthenticationSession.java index bbd74e2a9c..f89502de47 100644 --- a/extensions/guacamole-auth-sso/modules/guacamole-auth-sso-saml/src/main/java/org/apache/guacamole/auth/saml/acs/SAMLAuthenticationSession.java +++ b/extensions/guacamole-auth-sso/modules/guacamole-auth-sso-saml/src/main/java/org/apache/guacamole/auth/saml/acs/SAMLAuthenticationSession.java @@ -19,7 +19,7 @@ package org.apache.guacamole.auth.saml.acs; -import org.apache.guacamole.auth.sso.AuthenticationSession; +import org.apache.guacamole.net.auth.AuthenticationSession; /** * Representation of an in-progress SAML authentication attempt. diff --git a/extensions/guacamole-auth-sso/modules/guacamole-auth-sso-saml/src/main/java/org/apache/guacamole/auth/saml/acs/SAMLAuthenticationSessionManager.java b/extensions/guacamole-auth-sso/modules/guacamole-auth-sso-saml/src/main/java/org/apache/guacamole/auth/saml/acs/SAMLAuthenticationSessionManager.java index 4adf82f2cc..2371bb54d1 100644 --- a/extensions/guacamole-auth-sso/modules/guacamole-auth-sso-saml/src/main/java/org/apache/guacamole/auth/saml/acs/SAMLAuthenticationSessionManager.java +++ b/extensions/guacamole-auth-sso/modules/guacamole-auth-sso-saml/src/main/java/org/apache/guacamole/auth/saml/acs/SAMLAuthenticationSessionManager.java @@ -20,7 +20,7 @@ package org.apache.guacamole.auth.saml.acs; import com.google.inject.Singleton; -import org.apache.guacamole.auth.sso.AuthenticationSessionManager; +import org.apache.guacamole.net.auth.AuthenticationSessionManager; /** * Manager service that temporarily stores SAML authentication attempts while diff --git a/extensions/guacamole-auth-sso/modules/guacamole-auth-sso-saml/src/main/java/org/apache/guacamole/auth/saml/acs/SAMLService.java b/extensions/guacamole-auth-sso/modules/guacamole-auth-sso-saml/src/main/java/org/apache/guacamole/auth/saml/acs/SAMLService.java index 2fe6da4c8b..37d7fa9200 100644 --- a/extensions/guacamole-auth-sso/modules/guacamole-auth-sso-saml/src/main/java/org/apache/guacamole/auth/saml/acs/SAMLService.java +++ b/extensions/guacamole-auth-sso/modules/guacamole-auth-sso-saml/src/main/java/org/apache/guacamole/auth/saml/acs/SAMLService.java @@ -36,7 +36,7 @@ import org.apache.guacamole.GuacamoleSecurityException; import org.apache.guacamole.GuacamoleServerException; import org.apache.guacamole.auth.saml.conf.ConfigurationService; -import org.apache.guacamole.auth.sso.IdentifierGenerator; +import org.apache.guacamole.net.auth.IdentifierGenerator; import org.xml.sax.SAXException; /** @@ -58,12 +58,6 @@ public class SAMLService { @Inject private SAMLAuthenticationSessionManager sessionManager; - /** - * Generator of arbitrary, unique, unpredictable identifiers. - */ - @Inject - private IdentifierGenerator idGenerator; - /** * Creates a new SAML request, beginning the overall authentication flow * that will ultimately result in an asserted user identity if the user is @@ -89,7 +83,7 @@ public URI createRequest() throws GuacamoleException { Auth auth = new Auth(samlSettings, null, null); // Generate a unique ID to use for the relay state - String identifier = idGenerator.generateIdentifier(); + String identifier = IdentifierGenerator.generateIdentifier(); // Create the request URL for the SAML IdP String requestUrl = auth.login( diff --git a/extensions/guacamole-auth-sso/modules/guacamole-auth-sso-saml/src/main/java/org/apache/guacamole/auth/saml/conf/ConfigurationService.java b/extensions/guacamole-auth-sso/modules/guacamole-auth-sso-saml/src/main/java/org/apache/guacamole/auth/saml/conf/ConfigurationService.java index d2a73c46a2..47ead88208 100644 --- a/extensions/guacamole-auth-sso/modules/guacamole-auth-sso-saml/src/main/java/org/apache/guacamole/auth/saml/conf/ConfigurationService.java +++ b/extensions/guacamole-auth-sso/modules/guacamole-auth-sso-saml/src/main/java/org/apache/guacamole/auth/saml/conf/ConfigurationService.java @@ -24,7 +24,6 @@ import com.onelogin.saml2.settings.Saml2Settings; import com.onelogin.saml2.settings.SettingsBuilder; import com.onelogin.saml2.util.Constants; - import java.io.File; import java.io.IOException; import java.net.URI; diff --git a/extensions/guacamole-auth-sso/modules/guacamole-auth-sso-ssl/src/main/java/org/apache/guacamole/auth/ssl/SSLAuthenticationEventListener.java b/extensions/guacamole-auth-sso/modules/guacamole-auth-sso-ssl/src/main/java/org/apache/guacamole/auth/ssl/SSLAuthenticationEventListener.java index 26769ced92..2d353b58e2 100644 --- a/extensions/guacamole-auth-sso/modules/guacamole-auth-sso-ssl/src/main/java/org/apache/guacamole/auth/ssl/SSLAuthenticationEventListener.java +++ b/extensions/guacamole-auth-sso/modules/guacamole-auth-sso-ssl/src/main/java/org/apache/guacamole/auth/ssl/SSLAuthenticationEventListener.java @@ -20,14 +20,8 @@ package org.apache.guacamole.auth.ssl; import com.google.inject.Inject; -import com.google.inject.Singleton; -import org.apache.guacamole.GuacamoleException; -import org.apache.guacamole.auth.ssl.SSLAuthenticationSessionManager; import org.apache.guacamole.auth.sso.SSOAuthenticationEventListener; import org.apache.guacamole.net.auth.Credentials; -import org.apache.guacamole.net.event.AuthenticationFailureEvent; -import org.apache.guacamole.net.event.AuthenticationSuccessEvent; -import org.apache.guacamole.net.event.listener.Listener; /** * A Listener that will reactivate or invalidate SSL auth sessions depending on diff --git a/extensions/guacamole-auth-sso/modules/guacamole-auth-sso-ssl/src/main/java/org/apache/guacamole/auth/ssl/SSLAuthenticationSession.java b/extensions/guacamole-auth-sso/modules/guacamole-auth-sso-ssl/src/main/java/org/apache/guacamole/auth/ssl/SSLAuthenticationSession.java index 4a4c9ce8ff..41813a462a 100644 --- a/extensions/guacamole-auth-sso/modules/guacamole-auth-sso-ssl/src/main/java/org/apache/guacamole/auth/ssl/SSLAuthenticationSession.java +++ b/extensions/guacamole-auth-sso/modules/guacamole-auth-sso-ssl/src/main/java/org/apache/guacamole/auth/ssl/SSLAuthenticationSession.java @@ -19,7 +19,7 @@ package org.apache.guacamole.auth.ssl; -import org.apache.guacamole.auth.sso.AuthenticationSession; +import org.apache.guacamole.net.auth.AuthenticationSession; /** * Representation of an in-progress SSL/TLS authentication attempt. diff --git a/extensions/guacamole-auth-sso/modules/guacamole-auth-sso-ssl/src/main/java/org/apache/guacamole/auth/ssl/SSLAuthenticationSessionManager.java b/extensions/guacamole-auth-sso/modules/guacamole-auth-sso-ssl/src/main/java/org/apache/guacamole/auth/ssl/SSLAuthenticationSessionManager.java index fc1b0842f4..252a2c94ef 100644 --- a/extensions/guacamole-auth-sso/modules/guacamole-auth-sso-ssl/src/main/java/org/apache/guacamole/auth/ssl/SSLAuthenticationSessionManager.java +++ b/extensions/guacamole-auth-sso/modules/guacamole-auth-sso-ssl/src/main/java/org/apache/guacamole/auth/ssl/SSLAuthenticationSessionManager.java @@ -20,7 +20,7 @@ package org.apache.guacamole.auth.ssl; import com.google.inject.Singleton; -import org.apache.guacamole.auth.sso.AuthenticationSessionManager; +import org.apache.guacamole.net.auth.AuthenticationSessionManager; /** * Manager service that temporarily stores SSL/TLS authentication attempts diff --git a/extensions/guacamole-auth-sso/modules/guacamole-auth-sso-base/src/main/java/org/apache/guacamole/auth/sso/AuthenticationSession.java b/guacamole-ext/src/main/java/org/apache/guacamole/net/auth/AuthenticationSession.java similarity index 97% rename from extensions/guacamole-auth-sso/modules/guacamole-auth-sso-base/src/main/java/org/apache/guacamole/auth/sso/AuthenticationSession.java rename to guacamole-ext/src/main/java/org/apache/guacamole/net/auth/AuthenticationSession.java index 89d75df701..8d13e6111c 100644 --- a/extensions/guacamole-auth-sso/modules/guacamole-auth-sso-base/src/main/java/org/apache/guacamole/auth/sso/AuthenticationSession.java +++ b/guacamole-ext/src/main/java/org/apache/guacamole/net/auth/AuthenticationSession.java @@ -17,7 +17,7 @@ * under the License. */ -package org.apache.guacamole.auth.sso; +package org.apache.guacamole.net.auth; /** * Representation of an in-progress authentication attempt. diff --git a/extensions/guacamole-auth-sso/modules/guacamole-auth-sso-base/src/main/java/org/apache/guacamole/auth/sso/AuthenticationSessionManager.java b/guacamole-ext/src/main/java/org/apache/guacamole/net/auth/AuthenticationSessionManager.java similarity index 94% rename from extensions/guacamole-auth-sso/modules/guacamole-auth-sso-base/src/main/java/org/apache/guacamole/auth/sso/AuthenticationSessionManager.java rename to guacamole-ext/src/main/java/org/apache/guacamole/net/auth/AuthenticationSessionManager.java index 11ef307e2f..d8a47f4ef1 100644 --- a/extensions/guacamole-auth-sso/modules/guacamole-auth-sso-base/src/main/java/org/apache/guacamole/auth/sso/AuthenticationSessionManager.java +++ b/guacamole-ext/src/main/java/org/apache/guacamole/net/auth/AuthenticationSessionManager.java @@ -17,10 +17,7 @@ * under the License. */ -package org.apache.guacamole.auth.sso; - -import com.google.inject.Inject; -import com.google.inject.Singleton; +package org.apache.guacamole.net.auth; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; @@ -39,14 +36,7 @@ * @param * The type of sessions managed by this session manager. */ -@Singleton -public class AuthenticationSessionManager { - - /** - * Generator of arbitrary, unique, unpredictable identifiers. - */ - @Inject - private IdentifierGenerator idGenerator; +public abstract class AuthenticationSessionManager { /** * Map of authentication session identifiers to their associated @@ -98,7 +88,7 @@ public AuthenticationSessionManager() { * token. */ public String generateInvalid() { - return idGenerator.generateIdentifier(); + return IdentifierGenerator.generateIdentifier(); } /** @@ -193,7 +183,7 @@ public T resume(String identifier) { * given session when calling resume(). */ public String defer(T session) { - String identifier = idGenerator.generateIdentifier(); + String identifier = IdentifierGenerator.generateIdentifier(); sessions.put(identifier, session); return identifier; } diff --git a/extensions/guacamole-auth-sso/modules/guacamole-auth-sso-base/src/main/java/org/apache/guacamole/auth/sso/IdentifierGenerator.java b/guacamole-ext/src/main/java/org/apache/guacamole/net/auth/IdentifierGenerator.java similarity index 92% rename from extensions/guacamole-auth-sso/modules/guacamole-auth-sso-base/src/main/java/org/apache/guacamole/auth/sso/IdentifierGenerator.java rename to guacamole-ext/src/main/java/org/apache/guacamole/net/auth/IdentifierGenerator.java index 82538c6a9f..fcc365a9b7 100644 --- a/extensions/guacamole-auth-sso/modules/guacamole-auth-sso-base/src/main/java/org/apache/guacamole/auth/sso/IdentifierGenerator.java +++ b/guacamole-ext/src/main/java/org/apache/guacamole/net/auth/IdentifierGenerator.java @@ -17,10 +17,9 @@ * under the License. */ -package org.apache.guacamole.auth.sso; +package org.apache.guacamole.net.auth; import com.google.common.io.BaseEncoding; -import com.google.inject.Singleton; import java.math.BigInteger; import java.security.SecureRandom; @@ -29,14 +28,13 @@ * is an arbitrary, random string produced using a cryptographically-secure * random number generator. */ -@Singleton public class IdentifierGenerator { /** * Cryptographically-secure random number generator for generating unique * identifiers. */ - private final SecureRandom secureRandom = new SecureRandom(); + private static final SecureRandom secureRandom = new SecureRandom(); /** * Generates a unique and unpredictable identifier. Each identifier is at @@ -48,7 +46,7 @@ public class IdentifierGenerator { * A unique and unpredictable identifier with at least 256 bits of * entropy. */ - public String generateIdentifier() { + public static String generateIdentifier() { return generateIdentifier(256); } @@ -65,7 +63,7 @@ public String generateIdentifier() { * A unique and unpredictable identifier with at least the given number * of bits of entropy. */ - public String generateIdentifier(int minBits) { + public static String generateIdentifier(int minBits) { return generateIdentifier(minBits, true); } @@ -87,7 +85,7 @@ public String generateIdentifier(int minBits) { * A unique and unpredictable identifier with at least the given number * of bits of entropy. */ - public String generateIdentifier(int minBits, boolean caseSensitive) { + public static String generateIdentifier(int minBits, boolean caseSensitive) { // Generate a base64 identifier if we're allowed to vary by case if (caseSensitive) {