Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions assemblies/features/standard/src/main/feature/feature.xml
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,15 @@ uninstall = admin
start = admin
stop = admin
#
# requirement-add/requirement-remove add or remove provisioning requirements. The resolver
# turns these into installing and starting (or uninstalling) bundles and features exactly as
# feature:install/feature:uninstall do -- a "bundle:" requirement downloads and starts an
# arbitrary bundle, and a "feature:" requirement installs that feature. They are gated to
# admin for the same reason as install/uninstall; otherwise they bypass those ACLs.
#
requirement-add = admin
requirement-remove = admin
#
# repo-add/repo-remove stay open to the viewer role (the plain form only reads/lists
# a repository), but installing/uninstalling every feature in it via -i/-u requires
# admin. The bare "= viewer" fallback is required: a command with a regex-only ACL
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,15 @@ uninstall = admin
start = admin
stop = admin
#
# requirement-add/requirement-remove add or remove provisioning requirements. The resolver
# turns these into installing and starting (or uninstalling) bundles and features exactly as
# feature:install/feature:uninstall do -- a "bundle:" requirement downloads and starts an
# arbitrary bundle, and a "feature:" requirement installs that feature. They are gated to
# admin for the same reason as install/uninstall; otherwise they bypass those ACLs.
#
requirement-add = admin
requirement-remove = admin
#
# repo-add/repo-remove stay open to the viewer role (the plain form only reads/lists
# a repository), but installing/uninstalling every feature in it via -i/-u requires
# admin. The bare "= viewer" fallback is required: a command with a regex-only ACL
Expand Down
2 changes: 2 additions & 0 deletions itests/test/src/test/filtered-resources/etc/feature.xml
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,8 @@
uninstall = admin
start = admin
stop = admin
requirement-add = admin
requirement-remove = admin
repo-add[/.*[-][i].*/] = admin
repo-add = viewer
repo-remove[/.*[-][u].*/] = admin
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -94,4 +94,30 @@ public void testFeatureRepoCommandSecurityViaSsh() throws Exception {
assertCommand("karaf", "feature:repo-add -i " + bogusUrl, Result.OK);
assertCommand("karaf", "feature:repo-remove -u " + bogusUrl, Result.OK);
}

@Test
public void testFeatureRequirementCommandSecurityViaSsh() throws Exception {
// Skip on Windows where PTY output can be garbled,
// when upgrading to Junit5, this can be replaced with @DisabledOnOs(OS.WINDOWS)
// TODO: remove this once we have a better solution for PTY output on Windows
Assume.assumeFalse(System.getProperty("os.name", "").toLowerCase().contains("win"));

String vieweruser = "viewer" + System.nanoTime() + "_requirements";

addViewer(vieweruser);

// feature:requirement-add adds a provisioning requirement that the resolver installs and
// starts exactly like feature:install -- a "bundle:<uri>" requirement downloads and starts
// an arbitrary bundle. feature:requirement-remove is the uninstall equivalent. Both must be
// admin-only, like install/uninstall, so a viewer cannot bypass those ACLs. As plain
// name-only ACL rules (requirement-add = admin), the command guard hides them from the
// viewer, so the denial surfaces as "Command not found", same as feature:install.
assertCommand(vieweruser, "feature:requirement-add bundle:mvn:org.example/evil/1.0", Result.NOT_FOUND);
assertCommand(vieweruser, "feature:requirement-remove bundle:mvn:org.example/evil/1.0", Result.NOT_FOUND);

// The admin role may run them. Use -t (simulate) with a non-existent requirement so nothing
// is actually downloaded, installed or persisted; this test only cares about the ACL decision.
assertCommand("karaf", "feature:requirement-add -t feature:karaf-test-nonexistent-requirement", Result.OK);
assertCommand("karaf", "feature:requirement-remove -t feature:karaf-test-nonexistent-requirement", Result.OK);
}
}
5 changes: 4 additions & 1 deletion manual/src/main/asciidoc/user-guide/security.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -492,7 +492,10 @@ By default, Apache Karaf defines the following commands ACLs:
the users with the `manager` role can execute `config:*` commands. As `config:install` writes an arbitrary file into
the `etc` folder, it is restricted to the users with the `admin` role.
* `etc/org.apache.karaf.command.acl.feature.cfg` configuration file defines the ACL for `feature:*` commands.
Only the users with `admin` role can execute `feature:install`, `feature:uninstall`,`feature:start`, `feature:stop` and `feature:update` commands. `feature:repo-add`
Only the users with `admin` role can execute `feature:install`, `feature:uninstall`,`feature:start`, `feature:stop` and `feature:update` commands.
`feature:requirement-add` and `feature:requirement-remove` are also restricted to the `admin` role: they add or remove provisioning requirements that the
resolver turns into installing and starting (or uninstalling) bundles and features exactly as `feature:install`/`feature:uninstall` do, so without this a `viewer`
could bypass those ACLs (for instance a `bundle:<uri>` requirement downloads and starts an arbitrary bundle). `feature:repo-add`
and `feature:repo-remove` require the `admin` role only when used with the `-i`/`--install` or `-u`/`--uninstall` option, which installs or uninstalls every
feature in the repository; otherwise they only require the `viewer` role. The other `feature:*` commands can be executed by any user.
* `etc/org.apache.karaf.command.acl.jaas.cfg` configuration file defines the ACL for `jaas:*` commands.
Expand Down
Loading