diff --git a/.gitignore b/.gitignore index 8031def96885..eee87485f4e8 100644 --- a/.gitignore +++ b/.gitignore @@ -37,6 +37,7 @@ elvis !/deps/rabbitmq_amqp_client/ !/deps/rabbitmq_auth_backend_cache/ !/deps/rabbitmq_auth_backend_http/ +!/deps/rabbitmq_auth_backend_internal_loopback/ !/deps/rabbitmq_auth_backend_ldap/ !/deps/rabbitmq_auth_backend_oauth2/ !/deps/rabbitmq_auth_mechanism_ssl/ diff --git a/Makefile b/Makefile index 4e68e6f23796..842c51b2820b 100644 --- a/Makefile +++ b/Makefile @@ -523,6 +523,7 @@ TIER1_PLUGINS := \ rabbitmq_amqp1_0 \ rabbitmq_auth_backend_cache \ rabbitmq_auth_backend_http \ + rabbitmq_auth_backend_internal_loopback \ rabbitmq_auth_backend_ldap \ rabbitmq_auth_backend_oauth2 \ rabbitmq_auth_mechanism_ssl \ diff --git a/deps/rabbit/src/rabbit_auth_mechanism_plain.erl b/deps/rabbit/src/rabbit_auth_mechanism_plain.erl index e69ee00bd3f5..35d3ecb87302 100644 --- a/deps/rabbit/src/rabbit_auth_mechanism_plain.erl +++ b/deps/rabbit/src/rabbit_auth_mechanism_plain.erl @@ -10,6 +10,10 @@ -export([description/0, should_offer/1, init/1, handle_response/2]). +-record(state, { + socket + }). + -rabbit_boot_step({?MODULE, [{description, "auth mechanism plain"}, {mfa, {rabbit_registry, register, @@ -26,8 +30,17 @@ description() -> should_offer(_Sock) -> true. -init(_Sock) -> - []. +init(Sock) -> + #state{socket = Sock}. + +handle_response(Response, #state{socket = Socket}) -> + case extract_user_pass(Response) of + {ok, User, Pass} -> + AuthProps = build_auth_props(Pass, Socket), + rabbit_access_control:check_user_login(User, AuthProps); + error -> + {protocol_error, "response ~tp invalid", [Response]} + end; handle_response(Response, _State) -> case extract_user_pass(Response) of @@ -37,6 +50,10 @@ handle_response(Response, _State) -> {protocol_error, "response ~tp invalid", [Response]} end. + +build_auth_props(Pass, Socket) -> + [{password, Pass}, {sockOrAddr, Socket}]. + extract_user_pass(Response) -> case extract_elem(Response) of {ok, User, Response1} -> diff --git a/deps/rabbitmq_auth_backend_http/src/rabbit_auth_backend_http.erl b/deps/rabbitmq_auth_backend_http/src/rabbit_auth_backend_http.erl index f2bd50800935..3a7556177e12 100644 --- a/deps/rabbitmq_auth_backend_http/src/rabbit_auth_backend_http.erl +++ b/deps/rabbitmq_auth_backend_http/src/rabbit_auth_backend_http.erl @@ -79,9 +79,13 @@ is_internal_property(_Other) -> false. is_internal_none_password(password, none) -> true; is_internal_none_password(_, _) -> false. +is_sockOrAddr(sockOrAddr) -> true; +is_sockOrAddr(_) -> false. + extract_other_credentials(AuthProps) -> - PublicAuthProps = [{K,V} || {K,V} <-AuthProps, not is_internal_property(K) and - not is_internal_none_password(K, V)], + PublicAuthProps = [{K,V} || {K,V} <-AuthProps, not is_internal_property(K) and + not is_internal_none_password(K, V) and + not is_sockOrAddr(K)], case PublicAuthProps of [] -> resolve_using_persisted_credentials(AuthProps); _ -> PublicAuthProps diff --git a/deps/rabbitmq_auth_backend_internal_loopback/.gitignore b/deps/rabbitmq_auth_backend_internal_loopback/.gitignore new file mode 100644 index 000000000000..0595211a7ee4 --- /dev/null +++ b/deps/rabbitmq_auth_backend_internal_loopback/.gitignore @@ -0,0 +1 @@ +test/config_schema_SUITE_data/schema/ diff --git a/deps/rabbitmq_auth_backend_internal_loopback/CODE_OF_CONDUCT.md b/deps/rabbitmq_auth_backend_internal_loopback/CODE_OF_CONDUCT.md new file mode 100644 index 000000000000..7cefb156b3ef --- /dev/null +++ b/deps/rabbitmq_auth_backend_internal_loopback/CODE_OF_CONDUCT.md @@ -0,0 +1,44 @@ +# Contributor Code of Conduct + +As contributors and maintainers of this project, and in the interest of fostering an open +and welcoming community, we pledge to respect all people who contribute through reporting +issues, posting feature requests, updating documentation, submitting pull requests or +patches, and other activities. + +We are committed to making participation in this project a harassment-free experience for +everyone, regardless of level of experience, gender, gender identity and expression, +sexual orientation, disability, personal appearance, body size, race, ethnicity, age, +religion, or nationality. + +Examples of unacceptable behavior by participants include: + + * The use of sexualized language or imagery + * Personal attacks + * Trolling or insulting/derogatory comments + * Public or private harassment + * Publishing other's private information, such as physical or electronic addresses, + without explicit permission + * Other unethical or unprofessional conduct + +Project maintainers have the right and responsibility to remove, edit, or reject comments, +commits, code, wiki edits, issues, and other contributions that are not aligned to this +Code of Conduct, or to ban temporarily or permanently any contributor for other behaviors +that they deem inappropriate, threatening, offensive, or harmful. + +By adopting this Code of Conduct, project maintainers commit themselves to fairly and +consistently applying these principles to every aspect of managing this project. Project +maintainers who do not follow or enforce the Code of Conduct may be permanently removed +from the project team. + +This Code of Conduct applies both within project spaces and in public spaces when an +individual is representing the project or its community. + +Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by +contacting a project maintainer at [rabbitmq-core@groups.vmware.com](mailto:rabbitmq-core@groups.vmware.com). All complaints will +be reviewed and investigated and will result in a response that is deemed necessary and +appropriate to the circumstances. Maintainers are obligated to maintain confidentiality +with regard to the reporter of an incident. + +This Code of Conduct is adapted from the +[Contributor Covenant](https://contributor-covenant.org), version 1.3.0, available at +[contributor-covenant.org/version/1/3/0/](https://contributor-covenant.org/version/1/3/0/) diff --git a/deps/rabbitmq_auth_backend_internal_loopback/CONTRIBUTING.md b/deps/rabbitmq_auth_backend_internal_loopback/CONTRIBUTING.md new file mode 100644 index 000000000000..20dd149f7171 --- /dev/null +++ b/deps/rabbitmq_auth_backend_internal_loopback/CONTRIBUTING.md @@ -0,0 +1,203 @@ +## Overview + +RabbitMQ projects use pull requests to discuss, collaborate on and accept code contributions. +Pull requests is the primary place of discussing code changes. + +## How to Contribute + +The process is fairly standard: + + * Present your idea to the RabbitMQ core team using [GitHub Discussions](https://github.com/rabbitmq/rabbitmq-server/discussions) or [RabbitMQ community Discord server](https://rabbitmq.com/discord) + * Fork the repository or repositories you plan on contributing to + * Run `git clean -xfffd && gmake clean && gmake distclean && gmake` to build all subprojects from scratch + * Create a branch with a descriptive name + * Make your changes, run tests, ensure correct code formatting, commit with a [descriptive message](https://tbaggery.com/2008/04/19/a-note-about-git-commit-messages.html), push to your fork + * Submit pull requests with an explanation what has been changed and **why** + * Submit a filled out and signed [Contributor Agreement](https://cla.pivotal.io/) if needed (see below) + * Be patient. We will get to your pull request eventually + + +## Running Tests + +Test suites of individual subprojects can be run from the subproject directory under +`deps/*`. For example, for the core broker: + +``` shell +# Running all server suites in parallel will take between 30 and 40 minutes on reasonably +# recent multi-core machines. This is rarely necessary in development environments. +# Running individual test suites or groups of test suites can be enough. +# + +# Before you start: this will terminate all running nodes, make processes and Common Test processes +killall -9 beam.smp; killall -9 erl; killall -9 make; killall -9 epmd; killall -9 erl_setup_child; killall -9 ct_run + +# the core broker subproject +cd deps/rabbit + +# cleans build artifacts +git clean -xfffd +gmake clean; gmake distclean + +# builds the broker and all of its dependencies +gmake +# runs an integration test suite, tests/rabbit_fifo_SUITE with CT (Common Test) +gmake ct-rabbit_fifo +# runs an integration test suite, tests/quorum_queue_SUITE with CT (Common Test) +gmake ct-quorum_queue +# runs an integration test suite, tests/queue_parallel_SUITE with CT (Common Test) +gmake ct-queue_parallel +# runs a unit test suite tests/unit_log_management_SUITE with CT (Common Test) +gmake ct-unit_log_management +``` + +### Running Specific Groups or Tests + +All `ct-*` Make targets support a `t=` argument which are transformed to [`-group` and `-case` Common Test runner options](https://www.erlang.org/doc/apps/common_test/run_test_chapter.html). + +``` shell +# Runs a a group of tests named 'all_tests_with_prefix' in suite 'test/rabbit_mgmt_http_SUITE.erl' +gmake ct-rabbit_mgmt_http t="all_tests_with_prefix" + +# Runs a test named 'users_test' in group 'all_tests_with_prefix' in suite 'test/rabbit_mgmt_http_SUITE.erl' +gmake ct-rabbit_mgmt_http t="all_tests_with_prefix:users_test" +# Runs a test named 'queues_test' in group 'all_tests_with_prefix' in suite 'test/rabbit_mgmt_http_SUITE.erl' +gmake ct-rabbit_mgmt_http t="all_tests_with_prefix:queues_test" +``` + +### Running Tests with a Specific Schema Data Store + +Set `RABBITMQ_METADATA_STORE` to either `khepri` or `mnesia` to make the Common Test suites +use a specific [schema data store]() (metadata store): + +``` shell +RABBITMQ_METADATA_STORE=khepri gmake ct-quorum_queue +``` + +Or, with Nu shell: + +```nu +with-env {'RABBITMQ_METADATA_STORE': 'khepri'} { gmake ct-quorum_queue } +``` + + +## Running Single Nodes from Source + +``` shell +# Run from repository root. +# Starts a node with the management plugin enabled +gmake run-broker RABBITMQ_PLUGINS=rabbitmq_management +``` + +The nodes will be started in the background. They will use `rabbit@{hostname}` for its name, so CLI will be able to contact +it without an explicit `-n` (`--node`) argument: + +```shell +# Run from repository root. +./sbin/rabbitmq-diagnostics status +``` + +## Running Clusters from Source + +``` shell +# Run from repository root. +# Starts a three node cluster with the management plugin enabled +gmake start-cluster NODES=3 RABBITMQ_PLUGINS=rabbitmq_management +``` + +The node will use `rabbit-{n}@{hostname}` for names, so CLI must +be explicitly given explicit an `-n` (`--node`) argument in order to +contact one of the nodes: + + * `rabbit-1` + * `rabbit-2` + * `rabbit-3` + +The names of the nodes can be looked up via + +``` shell +epmd -names +``` + +``` shell +# Run from repository root. +# Makes CLI tools talk to node rabbit-2 +sbin/rabbitmq-diagnostics cluster_status -n rabbit-2 + +# Run from repository root. +# Makes CLI tools talk to node rabbit-1 +sbin/rabbitmq-diagnostics status -n rabbit-1 +``` + +To stop a previously started cluster: + +``` shell +# Run from repository root. +# Stops a three node cluster started earlier +gmake stop-cluster NODES=3 +``` + + +## Working on Management UI with BrowserSync + +When working on management UI code, besides starting the node with + +``` shell +# starts a node with the management plugin enabled +gmake run-broker RABBITMQ_PLUGINS=rabbitmq_management +``` + +(or any other set of plugins), it is highly recommended to use [BrowserSync](https://browsersync.io/#install) +to shorten the edit/feedback cycle for JS files, CSS, and so on. + +First, install BrowserSync using NPM: + +``` shell +npm install -g browser-sync +``` + +Assuming a node running locally with HTTP API on port `15672`, start +a BrowserSync proxy like so: + +``` shell +cd deps/rabbitmq_management/priv/www + +browser-sync start --proxy localhost:15672 --serverStatic . --files . +``` + +BrowserSync will automatically open a browser window for you to use. The window +will automatically refresh when one of the static (templates, JS, CSS) files change. + +All HTTP requests that BrowserSync does not know how to handle will be proxied to +the HTTP API at `localhost:15672`. + + +## Formatting the RabbitMQ CLI + +The RabbitMQ CLI uses the standard [Elixir code formatter](https://hexdocs.pm/mix/main/Mix.Tasks.Format.html). To ensure correct code formatting of the CLI: + +``` +cd deps/rabbitmq_cli +mix format +``` + +Running `make` will validate the CLI formatting and issue any necessary warnings. Alternatively, run the format checker in the `deps/rabbitmq_cli` directory: + +``` +mix format --check-formatted +``` + +## Code of Conduct + +See [CODE_OF_CONDUCT.md](./CODE_OF_CONDUCT.md). + +## Contributor Agreement + +If you want to contribute a non-trivial change, please submit a signed copy of our +[Contributor Agreement](https://cla.pivotal.io/) around the time +you submit your pull request. This will make it much easier (in some cases, possible) +for the RabbitMQ team at Pivotal to merge your contribution. + +## Where to Ask Questions + +If something isn't clear, feel free to ask on [GitHub Discussions](https://github.com/rabbitmq/rabbitmq-server/discussions) +and [community Discord server](https://rabbitmq.com/discord). diff --git a/deps/rabbitmq_auth_backend_internal_loopback/LICENSE b/deps/rabbitmq_auth_backend_internal_loopback/LICENSE new file mode 100644 index 000000000000..e75136bfb5f8 --- /dev/null +++ b/deps/rabbitmq_auth_backend_internal_loopback/LICENSE @@ -0,0 +1,3 @@ +This package is licensed under the MPL 2.0. For the MPL 2.0, please see LICENSE-MPL-RabbitMQ. + +If you have any questions regarding licensing, please contact us at rabbitmq-core@groups.vmware.com. diff --git a/deps/rabbitmq_auth_backend_internal_loopback/LICENSE-MPL-RabbitMQ b/deps/rabbitmq_auth_backend_internal_loopback/LICENSE-MPL-RabbitMQ new file mode 100644 index 000000000000..14e2f777f6c3 --- /dev/null +++ b/deps/rabbitmq_auth_backend_internal_loopback/LICENSE-MPL-RabbitMQ @@ -0,0 +1,373 @@ +Mozilla Public License Version 2.0 +================================== + +1. Definitions +-------------- + +1.1. "Contributor" + means each individual or legal entity that creates, contributes to + the creation of, or owns Covered Software. + +1.2. "Contributor Version" + means the combination of the Contributions of others (if any) used + by a Contributor and that particular Contributor's Contribution. + +1.3. "Contribution" + means Covered Software of a particular Contributor. + +1.4. "Covered Software" + means Source Code Form to which the initial Contributor has attached + the notice in Exhibit A, the Executable Form of such Source Code + Form, and Modifications of such Source Code Form, in each case + including portions thereof. + +1.5. "Incompatible With Secondary Licenses" + means + + (a) that the initial Contributor has attached the notice described + in Exhibit B to the Covered Software; or + + (b) that the Covered Software was made available under the terms of + version 1.1 or earlier of the License, but not also under the + terms of a Secondary License. + +1.6. "Executable Form" + means any form of the work other than Source Code Form. + +1.7. "Larger Work" + means a work that combines Covered Software with other material, in + a separate file or files, that is not Covered Software. + +1.8. "License" + means this document. + +1.9. "Licensable" + means having the right to grant, to the maximum extent possible, + whether at the time of the initial grant or subsequently, any and + all of the rights conveyed by this License. + +1.10. "Modifications" + means any of the following: + + (a) any file in Source Code Form that results from an addition to, + deletion from, or modification of the contents of Covered + Software; or + + (b) any new file in Source Code Form that contains any Covered + Software. + +1.11. "Patent Claims" of a Contributor + means any patent claim(s), including without limitation, method, + process, and apparatus claims, in any patent Licensable by such + Contributor that would be infringed, but for the grant of the + License, by the making, using, selling, offering for sale, having + made, import, or transfer of either its Contributions or its + Contributor Version. + +1.12. "Secondary License" + means either the GNU General Public License, Version 2.0, the GNU + Lesser General Public License, Version 2.1, the GNU Affero General + Public License, Version 3.0, or any later versions of those + licenses. + +1.13. "Source Code Form" + means the form of the work preferred for making modifications. + +1.14. "You" (or "Your") + means an individual or a legal entity exercising rights under this + License. For legal entities, "You" includes any entity that + controls, is controlled by, or is under common control with You. For + purposes of this definition, "control" means (a) the power, direct + or indirect, to cause the direction or management of such entity, + whether by contract or otherwise, or (b) ownership of more than + fifty percent (50%) of the outstanding shares or beneficial + ownership of such entity. + +2. License Grants and Conditions +-------------------------------- + +2.1. Grants + +Each Contributor hereby grants You a world-wide, royalty-free, +non-exclusive license: + +(a) under intellectual property rights (other than patent or trademark) + Licensable by such Contributor to use, reproduce, make available, + modify, display, perform, distribute, and otherwise exploit its + Contributions, either on an unmodified basis, with Modifications, or + as part of a Larger Work; and + +(b) under Patent Claims of such Contributor to make, use, sell, offer + for sale, have made, import, and otherwise transfer either its + Contributions or its Contributor Version. + +2.2. Effective Date + +The licenses granted in Section 2.1 with respect to any Contribution +become effective for each Contribution on the date the Contributor first +distributes such Contribution. + +2.3. Limitations on Grant Scope + +The licenses granted in this Section 2 are the only rights granted under +this License. No additional rights or licenses will be implied from the +distribution or licensing of Covered Software under this License. +Notwithstanding Section 2.1(b) above, no patent license is granted by a +Contributor: + +(a) for any code that a Contributor has removed from Covered Software; + or + +(b) for infringements caused by: (i) Your and any other third party's + modifications of Covered Software, or (ii) the combination of its + Contributions with other software (except as part of its Contributor + Version); or + +(c) under Patent Claims infringed by Covered Software in the absence of + its Contributions. + +This License does not grant any rights in the trademarks, service marks, +or logos of any Contributor (except as may be necessary to comply with +the notice requirements in Section 3.4). + +2.4. Subsequent Licenses + +No Contributor makes additional grants as a result of Your choice to +distribute the Covered Software under a subsequent version of this +License (see Section 10.2) or under the terms of a Secondary License (if +permitted under the terms of Section 3.3). + +2.5. Representation + +Each Contributor represents that the Contributor believes its +Contributions are its original creation(s) or it has sufficient rights +to grant the rights to its Contributions conveyed by this License. + +2.6. Fair Use + +This License is not intended to limit any rights You have under +applicable copyright doctrines of fair use, fair dealing, or other +equivalents. + +2.7. Conditions + +Sections 3.1, 3.2, 3.3, and 3.4 are conditions of the licenses granted +in Section 2.1. + +3. Responsibilities +------------------- + +3.1. Distribution of Source Form + +All distribution of Covered Software in Source Code Form, including any +Modifications that You create or to which You contribute, must be under +the terms of this License. You must inform recipients that the Source +Code Form of the Covered Software is governed by the terms of this +License, and how they can obtain a copy of this License. You may not +attempt to alter or restrict the recipients' rights in the Source Code +Form. + +3.2. Distribution of Executable Form + +If You distribute Covered Software in Executable Form then: + +(a) such Covered Software must also be made available in Source Code + Form, as described in Section 3.1, and You must inform recipients of + the Executable Form how they can obtain a copy of such Source Code + Form by reasonable means in a timely manner, at a charge no more + than the cost of distribution to the recipient; and + +(b) You may distribute such Executable Form under the terms of this + License, or sublicense it under different terms, provided that the + license for the Executable Form does not attempt to limit or alter + the recipients' rights in the Source Code Form under this License. + +3.3. Distribution of a Larger Work + +You may create and distribute a Larger Work under terms of Your choice, +provided that You also comply with the requirements of this License for +the Covered Software. If the Larger Work is a combination of Covered +Software with a work governed by one or more Secondary Licenses, and the +Covered Software is not Incompatible With Secondary Licenses, this +License permits You to additionally distribute such Covered Software +under the terms of such Secondary License(s), so that the recipient of +the Larger Work may, at their option, further distribute the Covered +Software under the terms of either this License or such Secondary +License(s). + +3.4. Notices + +You may not remove or alter the substance of any license notices +(including copyright notices, patent notices, disclaimers of warranty, +or limitations of liability) contained within the Source Code Form of +the Covered Software, except that You may alter any license notices to +the extent required to remedy known factual inaccuracies. + +3.5. Application of Additional Terms + +You may choose to offer, and to charge a fee for, warranty, support, +indemnity or liability obligations to one or more recipients of Covered +Software. However, You may do so only on Your own behalf, and not on +behalf of any Contributor. You must make it absolutely clear that any +such warranty, support, indemnity, or liability obligation is offered by +You alone, and You hereby agree to indemnify every Contributor for any +liability incurred by such Contributor as a result of warranty, support, +indemnity or liability terms You offer. You may include additional +disclaimers of warranty and limitations of liability specific to any +jurisdiction. + +4. Inability to Comply Due to Statute or Regulation +--------------------------------------------------- + +If it is impossible for You to comply with any of the terms of this +License with respect to some or all of the Covered Software due to +statute, judicial order, or regulation then You must: (a) comply with +the terms of this License to the maximum extent possible; and (b) +describe the limitations and the code they affect. Such description must +be placed in a text file included with all distributions of the Covered +Software under this License. Except to the extent prohibited by statute +or regulation, such description must be sufficiently detailed for a +recipient of ordinary skill to be able to understand it. + +5. Termination +-------------- + +5.1. The rights granted under this License will terminate automatically +if You fail to comply with any of its terms. However, if You become +compliant, then the rights granted under this License from a particular +Contributor are reinstated (a) provisionally, unless and until such +Contributor explicitly and finally terminates Your grants, and (b) on an +ongoing basis, if such Contributor fails to notify You of the +non-compliance by some reasonable means prior to 60 days after You have +come back into compliance. Moreover, Your grants from a particular +Contributor are reinstated on an ongoing basis if such Contributor +notifies You of the non-compliance by some reasonable means, this is the +first time You have received notice of non-compliance with this License +from such Contributor, and You become compliant prior to 30 days after +Your receipt of the notice. + +5.2. If You initiate litigation against any entity by asserting a patent +infringement claim (excluding declaratory judgment actions, +counter-claims, and cross-claims) alleging that a Contributor Version +directly or indirectly infringes any patent, then the rights granted to +You by any and all Contributors for the Covered Software under Section +2.1 of this License shall terminate. + +5.3. In the event of termination under Sections 5.1 or 5.2 above, all +end user license agreements (excluding distributors and resellers) which +have been validly granted by You or Your distributors under this License +prior to termination shall survive termination. + +************************************************************************ +* * +* 6. Disclaimer of Warranty * +* ------------------------- * +* * +* Covered Software is provided under this License on an "as is" * +* basis, without warranty of any kind, either expressed, implied, or * +* statutory, including, without limitation, warranties that the * +* Covered Software is free of defects, merchantable, fit for a * +* particular purpose or non-infringing. The entire risk as to the * +* quality and performance of the Covered Software is with You. * +* Should any Covered Software prove defective in any respect, You * +* (not any Contributor) assume the cost of any necessary servicing, * +* repair, or correction. This disclaimer of warranty constitutes an * +* essential part of this License. No use of any Covered Software is * +* authorized under this License except under this disclaimer. * +* * +************************************************************************ + +************************************************************************ +* * +* 7. Limitation of Liability * +* -------------------------- * +* * +* Under no circumstances and under no legal theory, whether tort * +* (including negligence), contract, or otherwise, shall any * +* Contributor, or anyone who distributes Covered Software as * +* permitted above, be liable to You for any direct, indirect, * +* special, incidental, or consequential damages of any character * +* including, without limitation, damages for lost profits, loss of * +* goodwill, work stoppage, computer failure or malfunction, or any * +* and all other commercial damages or losses, even if such party * +* shall have been informed of the possibility of such damages. This * +* limitation of liability shall not apply to liability for death or * +* personal injury resulting from such party's negligence to the * +* extent applicable law prohibits such limitation. Some * +* jurisdictions do not allow the exclusion or limitation of * +* incidental or consequential damages, so this exclusion and * +* limitation may not apply to You. * +* * +************************************************************************ + +8. Litigation +------------- + +Any litigation relating to this License may be brought only in the +courts of a jurisdiction where the defendant maintains its principal +place of business and such litigation shall be governed by laws of that +jurisdiction, without reference to its conflict-of-law provisions. +Nothing in this Section shall prevent a party's ability to bring +cross-claims or counter-claims. + +9. Miscellaneous +---------------- + +This License represents the complete agreement concerning the subject +matter hereof. If any provision of this License is held to be +unenforceable, such provision shall be reformed only to the extent +necessary to make it enforceable. Any law or regulation which provides +that the language of a contract shall be construed against the drafter +shall not be used to construe this License against a Contributor. + +10. Versions of the License +--------------------------- + +10.1. New Versions + +Mozilla Foundation is the license steward. Except as provided in Section +10.3, no one other than the license steward has the right to modify or +publish new versions of this License. Each version will be given a +distinguishing version number. + +10.2. Effect of New Versions + +You may distribute the Covered Software under the terms of the version +of the License under which You originally received the Covered Software, +or under the terms of any subsequent version published by the license +steward. + +10.3. Modified Versions + +If you create software not governed by this License, and you want to +create a new license for such software, you may create and use a +modified version of this License if you rename the license and remove +any references to the name of the license steward (except to note that +such modified license differs from this License). + +10.4. Distributing Source Code Form that is Incompatible With Secondary +Licenses + +If You choose to distribute Source Code Form that is Incompatible With +Secondary Licenses under the terms of this version of the License, the +notice described in Exhibit B of this License must be attached. + +Exhibit A - Source Code Form License Notice +------------------------------------------- + + This Source Code Form is subject to the terms of the Mozilla Public + License, v. 2.0. If a copy of the MPL was not distributed with this + file, You can obtain one at http://mozilla.org/MPL/2.0/. + +If it is not possible or desirable to put the notice in a particular +file, then You may include the notice in a location (such as a LICENSE +file in a relevant directory) where a recipient would be likely to look +for such a notice. + +You may add additional accurate notices of copyright ownership. + +Exhibit B - "Incompatible With Secondary Licenses" Notice +--------------------------------------------------------- + + This Source Code Form is "Incompatible With Secondary Licenses", as + defined by the Mozilla Public License, v. 2.0. diff --git a/deps/rabbitmq_auth_backend_internal_loopback/Makefile b/deps/rabbitmq_auth_backend_internal_loopback/Makefile new file mode 100644 index 000000000000..6f639b7de388 --- /dev/null +++ b/deps/rabbitmq_auth_backend_internal_loopback/Makefile @@ -0,0 +1,22 @@ +PROJECT = rabbitmq_auth_backend_internal_loopback +PROJECT_DESCRIPTION = RabbitMQ Internal Loopback Authentication Backend +PROJECT_MOD = rabbit_auth_backend_internal_loopback_app + +define PROJECT_ENV +[ + + ] +endef + +define PROJECT_APP_EXTRA_KEYS + {broker_version_requirements, []} +endef + +DEPS = rabbit_common rabbit +TEST_DEPS = rabbitmq_ct_helpers rabbitmq_ct_client_helpers + +DEP_EARLY_PLUGINS = rabbit_common/mk/rabbitmq-early-plugin.mk +DEP_PLUGINS = rabbit_common/mk/rabbitmq-plugin.mk + +include ../../rabbitmq-components.mk +include ../../erlang.mk diff --git a/deps/rabbitmq_auth_backend_internal_loopback/README.md b/deps/rabbitmq_auth_backend_internal_loopback/README.md new file mode 100644 index 000000000000..59fdda677cda --- /dev/null +++ b/deps/rabbitmq_auth_backend_internal_loopback/README.md @@ -0,0 +1,32 @@ +# RabbitMQ Internal Loopback Authentication Backend + +This plugin provides [authentication and authorisation backends](https://rabbitmq.com/access-control.html) +for RabbitMQ for basic authentication for only (loopback) localhost connections. + +## Installation + +As of 4.1.1, this plugin is distributed with RabbitMQ. Enable it with + + rabbitmq-plugins enable rabbitmq_auth_backend_internal_loopback + +## Documentation + +[See the Access Control guide](https://www.rabbitmq.com/access-control.html) on rabbitmq.com. + + +## Building from Source + +See [Plugin Development guide](https://www.rabbitmq.com/plugin-development.html). + +TL;DR: running + + make dist + +will build the plugin and put build artifacts under the `./plugins` directory. + + +## Copyright and License + +(c) 2007-2024 Broadcom. The term “Broadcom” refers to Broadcom Inc. and/or its subsidiaries. All rights reserved. + +Released under the MPL, the same license as RabbitMQ. diff --git a/deps/rabbitmq_auth_backend_internal_loopback/schema/rabbitmq_auth_backend_internal_loopback.schema b/deps/rabbitmq_auth_backend_internal_loopback/schema/rabbitmq_auth_backend_internal_loopback.schema new file mode 100644 index 000000000000..01593372cf39 --- /dev/null +++ b/deps/rabbitmq_auth_backend_internal_loopback/schema/rabbitmq_auth_backend_internal_loopback.schema @@ -0,0 +1,3 @@ +%% ---------------------------------------------------------------------------- +%% RabbitMQ Internal Loopback Authorization +%% ---------------------------------------------------------------------------- diff --git a/deps/rabbitmq_auth_backend_internal_loopback/src/rabbit_auth_backend_internal_loopback.erl b/deps/rabbitmq_auth_backend_internal_loopback/src/rabbit_auth_backend_internal_loopback.erl new file mode 100644 index 000000000000..96274a5cdfd4 --- /dev/null +++ b/deps/rabbitmq_auth_backend_internal_loopback/src/rabbit_auth_backend_internal_loopback.erl @@ -0,0 +1,313 @@ +%% This Source Code Form is subject to the terms of the Mozilla Public +%% License, v. 2.0. If a copy of the MPL was not distributed with this +%% file, You can obtain one at https://mozilla.org/MPL/2.0/. +%% +%% Copyright (c) 2007-2025 Broadcom. All Rights Reserved. The term “Broadcom” refers to Broadcom Inc. and/or its subsidiaries. All rights reserved. +%% + +-module(rabbit_auth_backend_internal_loopback). +-include_lib("rabbit_common/include/rabbit.hrl"). + +-behaviour(rabbit_authn_backend). +-behaviour(rabbit_authz_backend). + +-export([user_login_authentication/2, user_login_authorization/2, + check_vhost_access/3, check_resource_access/4, check_topic_access/4]). + +-export([add_user/3, add_user/4, add_user/5, delete_user/2, lookup_user/1, exists/1, + change_password/3, clear_password/2, + hash_password/2, change_password_hash/2, change_password_hash/3, + set_tags/3, set_permissions/6, clear_permissions/3, set_permissions_globally/5, + set_topic_permissions/6, clear_topic_permissions/3, clear_topic_permissions/4, + clear_all_permissions_for_vhost/2, + add_user_sans_validation/3, put_user/2, put_user/3, + update_user/5, + update_user_with_hash/5, + add_user_sans_validation/6, + add_user_with_pre_hashed_password_sans_validation/3 +]). + +-export([set_user_limits/3, clear_user_limits/3, is_over_connection_limit/1, + is_over_channel_limit/1, get_user_limits/0, get_user_limits/1]). + +-export([user_info_keys/0, perms_info_keys/0, + user_perms_info_keys/0, vhost_perms_info_keys/0, + user_vhost_perms_info_keys/0, all_users/0, + user_topic_perms_info_keys/0, vhost_topic_perms_info_keys/0, + user_vhost_topic_perms_info_keys/0, + list_users/0, list_users/2, list_permissions/0, + list_user_permissions/1, list_user_permissions/3, + list_topic_permissions/0, + list_vhost_permissions/1, list_vhost_permissions/3, + list_user_vhost_permissions/2, + list_user_topic_permissions/1, list_vhost_topic_permissions/1, list_user_vhost_topic_permissions/2]). + +-export([expiry_timestamp/1]). + +-export([hashing_module_for_user/1, expand_topic_permission/2]). + +-import(rabbit_data_coercion, [to_atom/1, to_list/1, to_binary/1]). + +%%---------------------------------------------------------------------------- +%% Implementation of rabbit_auth_backend + +hashing_module_for_user(User) -> + rabbit_auth_backend_internal:hashing_module_for_user(User). + +-define(BLANK_PASSWORD_REJECTION_MESSAGE, + "user '~ts' attempted to log in with a blank password, which is prohibited by the internal authN backend. " + "To use TLS/x509 certificate-based authentication, see the rabbitmq_auth_mechanism_ssl plugin and configure the client to use the EXTERNAL authentication mechanism. " + "Alternatively change the password for the user to be non-blank."). + +-define(NO_SOCKET_OR_ADDRESS_REJECTION_MESSAGE, + "user '~ts' attempted to log in, but no socket or address was provided " + "to the internal_loopback auth backend, so cannot verify if connection " + "is from localhost or not."). + +-define(NOT_LOOPBACK_REJECTION_MESSAGE, + "user '~ts' attempted to log in, but the socket or address was not from " + "loopback/localhost, which is prohibited by the internal loopback authN " + "backend."). + +%% For cases when we do not have a set of credentials, +%% namely when x509 (TLS) certificates are used. This should only be +%% possible when the EXTERNAL authentication mechanism is used, see +%% rabbit_auth_mechanism_plain:handle_response/2 and rabbit_reader:auth_phase/2. +user_login_authentication(Username, []) -> + user_login_authentication(Username, [{password, none}]); +%% For cases when we do have a set of credentials. rabbit_auth_mechanism_plain:handle_response/2 +%% performs initial validation. +user_login_authentication(Username, AuthProps) -> + case proplists:lookup(sockOrAddr, AuthProps) of + none -> {refused, ?NO_SOCKET_OR_ADDRESS_REJECTION_MESSAGE, [Username]}; % sockOrAddr doesn't exist + {sockOrAddr, SockOrAddr} -> + case rabbit_net:is_loopback(SockOrAddr) of + true -> + case lists:keyfind(password, 1, AuthProps) of + {password, <<"">>} -> + {refused, ?BLANK_PASSWORD_REJECTION_MESSAGE, + [Username]}; + {password, ""} -> + {refused, ?BLANK_PASSWORD_REJECTION_MESSAGE, + [Username]}; + {password, none} -> %% For cases when authenticating using an x.509 certificate + internal_check_user_login(Username, fun(_) -> true end); + {password, Cleartext} -> + internal_check_user_login( + Username, + fun(User) -> + case internal_user:get_password_hash(User) of + <> -> + Hash =:= rabbit_password:salted_hash( + hashing_module_for_user(User), Salt, Cleartext); + _ -> + false + end + end); + false -> + case proplists:get_value(rabbit_auth_backend_internal, AuthProps, undefined) of + undefined -> {refused, ?BLANK_PASSWORD_REJECTION_MESSAGE, [Username]}; + _ -> internal_check_user_login(Username, fun(_) -> true end) + end + end; + false -> + {refused, ?NOT_LOOPBACK_REJECTION_MESSAGE, [Username]} + end + + end. + + +expiry_timestamp(User) -> + rabbit_auth_backend_internal:expiry_timestamp(User). + +user_login_authorization(Username, AuthProps) -> + rabbit_auth_backend_internal:user_login_authorization(Username, AuthProps). + +internal_check_user_login(Username, Fun) -> + Refused = {refused, "user '~ts' - invalid credentials", [Username]}, + case lookup_user(Username) of + {ok, User} -> + Tags = internal_user:get_tags(User), + case Fun(User) of + true -> {ok, #auth_user{username = Username, + tags = Tags, + impl = fun() -> none end}}; + _ -> Refused + end; + {error, not_found} -> + Refused + end. + +check_vhost_access(AuthUser, VHostPath, AuthzData) -> + rabbit_auth_backend_internal:check_vhost_access(AuthUser, VHostPath, AuthzData). + +check_resource_access(AuthUser, Resource, Permission, Context) -> + rabbit_auth_backend_internal:check_resource_access(AuthUser, Resource, Permission, Context). + +check_topic_access(AuthUser, Resource, Permission, Context) -> + rabbit_auth_backend_internal:check_topic_access(AuthUser, Resource, Permission, Context). + +add_user(Username, Password, ActingUser) -> + rabbit_auth_backend_internal:add_user(Username, Password, ActingUser). + +add_user(Username, Password, ActingUser, Tags) -> + rabbit_auth_backend_internal:add_user(Username, Password, ActingUser, Tags). + +add_user(Username, Password, ActingUser, Limits, Tags) -> + rabbit_auth_backend_internal:add_user(Username, Password, ActingUser, Limits, Tags). + +delete_user(Username, ActingUser) -> + rabbit_auth_backend_internal:delete_user(Username, ActingUser). + +lookup_user(Username) -> + rabbit_auth_backend_internal:lookup_user(Username). + +exists(Username) -> + rabbit_auth_backend_internal:exists(Username). + +change_password(Username, Password, ActingUser) -> + rabbit_auth_backend_internal:change_password(Username, Password, ActingUser). + +update_user(Username, Password, Tags, HashingAlgorithm, ActingUser) -> + rabbit_auth_backend_internal:update_user(Username, Password, Tags, HashingAlgorithm, ActingUser). + +clear_password(Username, ActingUser) -> + rabbit_auth_backend_internal:clear_password(Username, ActingUser). + +hash_password(HashingMod, Cleartext) -> + rabbit_auth_backend_internal:hash_password(HashingMod, Cleartext). + +change_password_hash(Username, PasswordHash) -> + rabbit_auth_backend_internal:change_password_hash(Username, PasswordHash). + +change_password_hash(Username, PasswordHash, HashingAlgorithm) -> + rabbit_auth_backend_internal:change_password_hash(Username, PasswordHash, HashingAlgorithm). + +update_user_with_hash(Username, PasswordHash, HashingAlgorithm, ConvertedTags, Limits) -> + rabbit_auth_backend_internal:update_user_with_hash(Username, PasswordHash, HashingAlgorithm, ConvertedTags, Limits). + +set_tags(Username, Tags, ActingUser) -> + rabbit_auth_backend_internal:set_tags(Username, Tags, ActingUser). + +set_permissions(Username, VHost, ConfigurePerm, WritePerm, ReadPerm, ActingUser) -> + rabbit_auth_backend_internal:set_permissions(Username, VHost, ConfigurePerm, WritePerm, ReadPerm, ActingUser). + +clear_permissions(Username, VHost, ActingUser) -> + rabbit_auth_backend_internal:clear_permissions(Username, VHost, ActingUser). + +clear_all_permissions_for_vhost(VHost, ActingUser) -> + rabbit_auth_backend_internal:clear_all_permissions_for_vhost(VHost, ActingUser). + +set_permissions_globally(Username, ConfigurePerm, WritePerm, ReadPerm, ActingUser) -> + rabbit_auth_backend_internal:set_permissions_globally(Username, ConfigurePerm, WritePerm, ReadPerm, ActingUser). + +set_topic_permissions(Username, VHost, Exchange, WritePerm, ReadPerm, ActingUser) -> + rabbit_auth_backend_internal:set_topic_permissions(Username, VHost, Exchange, WritePerm, ReadPerm, ActingUser). + +clear_topic_permissions(Username, VHost, ActingUser) -> + rabbit_auth_backend_internal:clear_topic_permissions(Username, VHost, ActingUser). + +clear_topic_permissions(Username, VHost, Exchange, ActingUser) -> + rabbit_auth_backend_internal:clear_topic_permissions(Username, VHost, Exchange, ActingUser). + +put_user(User, ActingUser) -> + rabbit_auth_backend_internal:put_user(User, ActingUser). + +put_user(User, Version, ActingUser) -> + rabbit_auth_backend_internal:put_user(User, Version, ActingUser). + +set_user_limits(Username, Definition, ActingUser) -> + rabbit_auth_backend_internal:set_user_limits(Username, Definition, ActingUser). + +clear_user_limits(Username, LimitType, ActingUser) -> + rabbit_auth_backend_internal:clear_user_limits(Username, LimitType, ActingUser). + +is_over_connection_limit(Username) -> + rabbit_auth_backend_internal:is_over_connection_limit(Username). + +is_over_channel_limit(Username) -> + rabbit_auth_backend_internal:is_over_channel_limit(Username). + +get_user_limits() -> + rabbit_auth_backend_internal:get_user_limits(). + +get_user_limits(Username) -> + rabbit_auth_backend_internal:get_user_limits(Username). + +user_info_keys() -> + rabbit_auth_backend_internal:user_info_keys(). + +perms_info_keys() -> + rabbit_auth_backend_internal:perms_info_keys(). + +user_perms_info_keys() -> + rabbit_auth_backend_internal:user_perms_info_keys(). + +vhost_perms_info_keys() -> + rabbit_auth_backend_internal:vhost_perms_info_keys(). + +user_vhost_perms_info_keys() -> + rabbit_auth_backend_internal:user_vhost_perms_info_keys(). + +user_topic_perms_info_keys() -> + rabbit_auth_backend_internal:user_topic_perms_info_keys(). + +user_vhost_topic_perms_info_keys() -> + rabbit_auth_backend_internal:user_vhost_topic_perms_info_keys(). + +vhost_topic_perms_info_keys() -> + rabbit_auth_backend_internal:vhost_topic_perms_info_keys(). + +all_users() -> + rabbit_auth_backend_internal:all_users(). + +list_users() -> + rabbit_auth_backend_internal:list_users(). + +list_users(Reference, AggregatorPid) -> + rabbit_auth_backend_internal:list_users(Reference, AggregatorPid). + +list_permissions() -> + rabbit_auth_backend_internal:list_permissions(). + +list_user_permissions(Username) -> + rabbit_auth_backend_internal:list_user_permissions(Username). + +list_user_permissions(Username, Reference, AggregatorPid) -> + rabbit_auth_backend_internal:list_user_permissions(Username, Reference, AggregatorPid). + +list_vhost_permissions(VHost) -> + rabbit_auth_backend_internal:list_vhost_permissions(VHost). + +list_vhost_permissions(VHost, Reference, AggregatorPid) -> + rabbit_auth_backend_internal:list_vhost_permissions(VHost, Reference, AggregatorPid). + +list_user_vhost_permissions(Username, VHost) -> + rabbit_auth_backend_internal:list_user_vhost_permissions(Username, VHost). + +list_topic_permissions() -> + rabbit_auth_backend_internal:list_topic_permissions(). + +list_user_topic_permissions(Username) -> + rabbit_auth_backend_internal:list_user_topic_permissions(Username). + +list_vhost_topic_permissions(VHost) -> + rabbit_auth_backend_internal:list_vhost_topic_permissions(VHost). + +list_user_vhost_topic_permissions(Username, VHost) -> + rabbit_auth_backend_internal:list_user_vhost_topic_permissions(Username, VHost). + +expand_topic_permission(TopicPermission, Context) -> + rabbit_auth_backend_internal:expand_topic_permission(TopicPermission, Context). + +%%---------------------------------------------------------------------------- +%% Manipulation of the user database + +add_user_with_pre_hashed_password_sans_validation(Username, PasswordHash, ActingUser) -> + rabbit_auth_backend_internal:add_user_with_pre_hashed_password_sans_validation(Username, PasswordHash, ActingUser). + +add_user_sans_validation(Username, Password, ActingUser) -> + rabbit_auth_backend_internal:add_user_sans_validation(Username, Password, ActingUser). + +add_user_sans_validation(Username, PasswordHash, HashingMod, Tags, Limits, ActingUser) -> + rabbit_auth_backend_internal:add_user_sans_validation(Username, PasswordHash, HashingMod, Tags, Limits, ActingUser). diff --git a/deps/rabbitmq_auth_backend_internal_loopback/src/rabbit_auth_backend_internal_loopback_app.erl b/deps/rabbitmq_auth_backend_internal_loopback/src/rabbit_auth_backend_internal_loopback_app.erl new file mode 100644 index 000000000000..dbaf272adb29 --- /dev/null +++ b/deps/rabbitmq_auth_backend_internal_loopback/src/rabbit_auth_backend_internal_loopback_app.erl @@ -0,0 +1,25 @@ +%% This Source Code Form is subject to the terms of the Mozilla Public +%% License, v. 2.0. If a copy of the MPL was not distributed with this +%% file, You can obtain one at https://mozilla.org/MPL/2.0/. +%% +%% Copyright (c) 2007-2025 Broadcom. All Rights Reserved. The term “Broadcom” refers to Broadcom Inc. and/or its subsidiaries. All rights reserved. +%% + +-module(rabbit_auth_backend_internal_loopback_app). + +-behaviour(application). +-export([start/2, stop/1]). + +-behaviour(supervisor). +-export([init/1]). + +start(_Type, _StartArgs) -> + supervisor:start_link({local,?MODULE},?MODULE,[]). + +stop(_State) -> + ok. + +%%---------------------------------------------------------------------------- + +init([]) -> + {ok, {{one_for_one,3,10},[]}}. diff --git a/deps/rabbitmq_auth_backend_internal_loopback/test/rabbit_auth_backend_internal_loopback_SUITE.erl b/deps/rabbitmq_auth_backend_internal_loopback/test/rabbit_auth_backend_internal_loopback_SUITE.erl new file mode 100644 index 000000000000..6ebbd46f1cbe --- /dev/null +++ b/deps/rabbitmq_auth_backend_internal_loopback/test/rabbit_auth_backend_internal_loopback_SUITE.erl @@ -0,0 +1,103 @@ +%% This Source Code Form is subject to the terms of the Mozilla Public +%% License, v. 2.0. If a copy of the MPL was not distributed with this +%% file, You can obtain one at https://mozilla.org/MPL/2.0/. +%% +%% Copyright (c) 2007-2025 Broadcom. All Rights Reserved. The term “Broadcom” refers to Broadcom Inc. and/or its subsidiaries. All rights reserved. +%% +-module(rabbit_auth_backend_internal_loopback_SUITE). + +-include_lib("common_test/include/ct.hrl"). +-include_lib("eunit/include/eunit.hrl"). + +-compile(export_all). + +-define(NO_SOCKET_OR_ADDRESS_REJECTION_MESSAGE, + "user '~ts' attempted to log in, but no socket or address was provided " + "to the internal_loopback auth backend, so cannot verify if connection " + "is from localhost or not."). + +-define(NOT_LOOPBACK_REJECTION_MESSAGE, + "user '~ts' attempted to log in, but the socket or address was not from " + "loopback/localhost, which is prohibited by the internal loopback authN " + "backend."). + +-define(LOOPBACK_USER, #{username => <<"TestLoopbackUser">>, + password => <<"TestLoopbackUser">>, + expected_credentials => [username, password], + tags => [policymaker, monitoring]}). + +-define(NONLOOPBACK_USER, #{username => <<"TestNonLoopbackUser">>, + password => <<"TestNonLoopbackUser">>, + expected_credentials => [username, password], + tags => [policymaker, monitoring]}). +-define(LOCALHOST_ADDR, {127,0,0,1}). +-define(NONLOCALHOST_ADDR, {192,168,1,1}). + +all() -> + [ + {group, localhost_connection}, + {group, nonlocalhost_connection} + ]. + +groups() -> + [ + {localhost_connection, [], [ + login_from_localhost_with_loopback_user, + login_from_localhost_with_nonloopback_user + ]}, + {nonlocalhost_connection, [], [ + login_from_nonlocalhost_with_loopback_user, + login_from_nonlocalhost_with_nonloopback_user + ]} + ]. + +init_per_suite(Config) -> + rabbit_ct_helpers:log_environment(), + rabbit_ct_helpers:run_setup_steps(Config, rabbit_ct_broker_helpers:setup_steps() ++ [ fun setup_env/1 ]). + +setup_env(Config) -> + application:set_env(rabbit, auth_backends, [rabbit_auth_backend_internal_loopback]), + Config. + +end_per_suite(Config) -> + rabbit_ct_helpers:run_teardown_steps(Config, rabbit_ct_broker_helpers:teardown_steps()). + +init_per_group(localhost_connection, Config) -> + ok = rabbit_ct_broker_helpers:add_user(Config, maps:get(username, ?LOOPBACK_USER)), + ok = rabbit_ct_broker_helpers:add_user(Config, maps:get(username, ?NONLOOPBACK_USER)), + [{sockOrAddr, ?LOCALHOST_ADDR} | Config]; +init_per_group(nonlocalhost_connection, Config) -> + [{sockOrAddr, ?NONLOCALHOST_ADDR} | Config]; +init_per_group(_, Config) -> + Config. + +end_per_group(_, Config) -> + Config. + +% Test cases for localhost connections +login_from_localhost_with_loopback_user(Config) -> + AuthProps = build_auth_props(maps:get(password, ?LOOPBACK_USER), ?LOCALHOST_ADDR), + {ok, _AuthUser} = rpc(Config, rabbit_auth_backend_internal_loopback, user_login_authentication, + [maps:get(username, ?LOOPBACK_USER), AuthProps]). + +login_from_localhost_with_nonloopback_user(Config) -> + AuthProps = build_auth_props(maps:get(password, ?NONLOOPBACK_USER), ?LOCALHOST_ADDR), + {ok, _AuthUser} = rpc(Config, rabbit_auth_backend_internal_loopback, user_login_authentication, + [maps:get(username, ?NONLOOPBACK_USER), AuthProps]). + +% Test cases for non-localhost connections +login_from_nonlocalhost_with_loopback_user(Config) -> + AuthProps = build_auth_props(maps:get(password, ?LOOPBACK_USER), ?NONLOCALHOST_ADDR), + {refused, _FailMsg, _FailArgs} = rpc(Config, rabbit_auth_backend_internal_loopback, user_login_authentication, + [maps:get(username, ?LOOPBACK_USER), AuthProps]). + +login_from_nonlocalhost_with_nonloopback_user(Config) -> + AuthProps = build_auth_props(maps:get(password, ?NONLOOPBACK_USER), ?NONLOCALHOST_ADDR), + {refused, _FailMsg, _FailArgs} = rpc(Config, rabbit_auth_backend_internal_loopback, user_login_authentication, + [maps:get(username, ?NONLOOPBACK_USER), AuthProps]). + +rpc(Config, M, F, A) -> + rabbit_ct_broker_helpers:rpc(Config, 0, M, F, A). + +build_auth_props(Pass, Socket) -> + [{password, Pass}, {sockOrAddr, Socket}]. diff --git a/deps/rabbitmq_web_dispatch/priv/schema/rabbitmq_web_dispatch.schema b/deps/rabbitmq_web_dispatch/priv/schema/rabbitmq_web_dispatch.schema index f9f2705fea09..e704c5c35001 100644 --- a/deps/rabbitmq_web_dispatch/priv/schema/rabbitmq_web_dispatch.schema +++ b/deps/rabbitmq_web_dispatch/priv/schema/rabbitmq_web_dispatch.schema @@ -96,5 +96,3 @@ end}. {datatype, atom} ]}. -%{mapping, "management.test_config", "rabbitmq_management.test_config", -% [{datatype, {enum, [true, false]}}]}. diff --git a/deps/rabbitmq_web_dispatch/src/rabbit_web_dispatch_access_control.erl b/deps/rabbitmq_web_dispatch/src/rabbit_web_dispatch_access_control.erl index c4561c27d400..a918dce2af4e 100644 --- a/deps/rabbitmq_web_dispatch/src/rabbit_web_dispatch_access_control.erl +++ b/deps/rabbitmq_web_dispatch/src/rabbit_web_dispatch_access_control.erl @@ -136,11 +136,12 @@ is_authorized(ReqData, Context, Username, Password, ErrorMsg, Fun, AuthConfig, R false -> {false, ReqData, "Not_Authorized"} end end, - AuthProps = [{password, Password}] ++ case vhost(ReqData) of + {IP, _} = cowboy_req:peer(ReqData), + + AuthProps = [{password, Password}, {sockOrAddr, IP}] ++ case vhost(ReqData) of VHost when is_binary(VHost) -> [{vhost, VHost}]; _ -> [] end, - {IP, _} = cowboy_req:peer(ReqData), {ok, AuthBackends} = get_auth_backends(), diff --git a/plugins.mk b/plugins.mk index b822296da018..6fb3a72389e7 100644 --- a/plugins.mk +++ b/plugins.mk @@ -8,6 +8,7 @@ PLUGINS := rabbitmq_amqp1_0 \ rabbitmq_auth_backend_cache \ rabbitmq_auth_backend_http \ + rabbitmq_auth_backend_internal_loopback \ rabbitmq_auth_backend_ldap \ rabbitmq_auth_backend_oauth2 \ rabbitmq_auth_mechanism_ssl \ diff --git a/rabbitmq-components.mk b/rabbitmq-components.mk index e7bdc6f2b58c..e88ce7c9cb23 100644 --- a/rabbitmq-components.mk +++ b/rabbitmq-components.mk @@ -78,6 +78,7 @@ RABBITMQ_BUILTIN = \ rabbitmq_amqp_client \ rabbitmq_auth_backend_cache \ rabbitmq_auth_backend_http \ + rabbitmq_auth_backend_internal_loopback \ rabbitmq_auth_backend_ldap \ rabbitmq_auth_backend_oauth2 \ rabbitmq_auth_mechanism_ssl \