This is an automated email from the ASF dual-hosted git repository. spmallette pushed a commit to branch remove-kerberos in repository https://gitbox.apache.org/repos/asf/tinkerpop.git
commit 5df27524b2ae51a3f11bdd89983cb5171f64862c Author: Stephen Mallette <[email protected]> AuthorDate: Wed Jul 1 16:42:21 2026 -0400 Remove Kerberos/kerby support Kerberos (SASL) authentication is not supported in 4.x. Removes the Krb5Authenticator, the kerby-based KDC test fixture, related configs, and the kerby/wildfly-common dependencies. Also drops the now-dead Kerberos server port (45942) and KDC port (4588) from the GLV docker test setup, and the libkrb5 build packages. Assisted-by: Claude Code:claude-opus-4-8 --- NOTICE | 10 - docker/Dockerfile | 2 +- docker/gremlin-server.sh | 2 +- docker/gremlin-server/Dockerfile.template | 2 +- docker/gremlin-server/docker-entrypoint.sh | 10 - docker/gremlin-server/gremlin-console-jaas.conf | 24 --- .../gremlin-server-integration-krb5.yaml | 73 ------- docker/gremlin-server/krb5.conf | 30 --- docker/gremlin-test-server/Dockerfile | 2 +- docker/gremlin-test-server/krb5.conf | 32 --- gremlin-dotnet/docker-compose.yml | 2 - gremlin-dotnet/test/pom.xml | 4 +- gremlin-examples/gremlin-python/connections.py | 16 +- gremlin-go/docker-compose.yml | 2 - gremlin-go/pom.xml | 4 +- gremlin-js/gremlin-javascript/docker-compose.yml | 2 - gremlin-js/gremlin-javascript/pom.xml | 4 +- gremlin-python/docker-compose.yml | 1 - gremlin-python/pom.xml | 4 +- gremlin-python/src/main/python/pyproject.toml | 1 - .../tinkerpop/gremlin/server/auth/JaasKrbUtil.java | 226 --------------------- .../gremlin/server/auth/Krb5Authenticator.java | 197 ------------------ .../server/GremlinServerAuditLogIntegrateTest.java | 54 +---- .../tinkerpop/gremlin/server/KdcFixtureTest.java | 43 ---- .../gremlin/server/gremlin-console-jaas.conf | 41 ---- .../gremlin/server/gremlin-server-integration.yaml | 1 - .../src/test/scripts/test-server-stop.groovy | 8 - gremlin-test/pom.xml | 16 -- .../tinkerpop/gremlin/server/KdcFixture.java | 217 -------------------- pom.xml | 26 --- spark-gremlin/pom.xml | 9 - 31 files changed, 22 insertions(+), 1043 deletions(-) diff --git a/NOTICE b/NOTICE index bc85e61677..725f7be7f9 100644 --- a/NOTICE +++ b/NOTICE @@ -13,13 +13,3 @@ Copyright 2010-2014 Alfresco Software, Ltd. gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphml/GraphMLWriterHelper.java contains DelegatingXMLStreamWriter.java and IndentingXMLStreamWriter.java from https://github.com/Activiti/Activiti/tree/activiti-5.16/modules/activiti-bpmn-converter/src/main/java/org/activiti/bpmn/converter - ------------------------------------------------------------------------- -Apache Kerby ------------------------------------------------------------------------- -Apache Kerby -Copyright 2015-2017 The Apache Software Foundation - -gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/auth/JaasKrbUtil.java -from -https://github.com/apache/directory-kerby/blob/kerby-all-1.0.0/kerby-kerb/kerb-simplekdc/src/main/java/org/apache/kerby/kerberos/kerb/client/JaasKrbUtil.java diff --git a/docker/Dockerfile b/docker/Dockerfile index d82f6e5906..66a375384b 100644 --- a/docker/Dockerfile +++ b/docker/Dockerfile @@ -34,7 +34,7 @@ RUN apt-get install -y --force-yes dotnet-sdk-8.0 mono-devel ENV DEBIAN_FRONTEND=noninteractive RUN apt-get install -y python3 python3.8 python3-dev python3.8-dev python3-pip build-essential checkinstall zlib1g-dev libreadline-gplv2-dev \ - libncursesw5-dev libssl-dev libsqlite3-dev tk-dev libgdbm-dev libc6-dev libbz2-dev libkrb5-dev krb5-user + libncursesw5-dev libssl-dev libsqlite3-dev tk-dev libgdbm-dev libc6-dev libbz2-dev # make python3 be python 3.8 RUN rm /usr/bin/python3 diff --git a/docker/gremlin-server.sh b/docker/gremlin-server.sh index f3d8f85a3b..96a2fb7dae 100755 --- a/docker/gremlin-server.sh +++ b/docker/gremlin-server.sh @@ -61,7 +61,7 @@ echo "Using Gremlin Server $GREMLIN_SERVER_VERSION" sed -e "s/GREMLIN_SERVER_VERSION\$/${GREMLIN_SERVER_VERSION}/" docker/gremlin-server/Dockerfile.template > Dockerfile docker build -t tinkerpop:${BUILD_TAG} . -docker run ${TINKERPOP_TEST_DOCKER_OPTS} ${REMOVE_CONTAINER} -p 45940:45940 -p 45941:45941 -p 45942:45942 -p 4588:4588 -h gremlin-server-test -v "${HOME}"/.groovy:/root/.groovy \ +docker run ${TINKERPOP_TEST_DOCKER_OPTS} ${REMOVE_CONTAINER} -p 45940:45940 -p 45941:45941 -h gremlin-server-test -v "${HOME}"/.groovy:/root/.groovy \ -v "${HOME}"/.m2:/root/.m2 -v ${ABS_PROJECT_HOME}/gremlin-test/target:/opt/gremlin-test -ti tinkerpop:${BUILD_TAG} ${@} status=$? diff --git a/docker/gremlin-server/Dockerfile.template b/docker/gremlin-server/Dockerfile.template index cbb0611bdb..b5f77d5f7f 100644 --- a/docker/gremlin-server/Dockerfile.template +++ b/docker/gremlin-server/Dockerfile.template @@ -25,7 +25,7 @@ COPY docker/gremlin-server/docker-entrypoint.sh docker/gremlin-server/*.yaml /op RUN chmod 755 /opt/docker-entrypoint.sh ENV GREMLIN_SERVER_VERSION=GREMLIN_SERVER_VERSION -EXPOSE 45940-45942 4588 +EXPOSE 45940 45941 ENTRYPOINT ["/opt/docker-entrypoint.sh"] CMD [] diff --git a/docker/gremlin-server/docker-entrypoint.sh b/docker/gremlin-server/docker-entrypoint.sh index 4662211776..84d76c6647 100644 --- a/docker/gremlin-server/docker-entrypoint.sh +++ b/docker/gremlin-server/docker-entrypoint.sh @@ -45,7 +45,6 @@ echo echo Available Gremlin Server instances: echo "http://${IP}:45940/gremlin with anonymous access" echo "http://${IP}:45941/gremlin with basic authentication (stephen/password)" -echo "http://${IP}:45942/gremlin with kerberos authentication (stephen/password)" echo echo "See docker/gremlin-server/docker-entrypoints.sh for transcripts per GLV." echo "#############################################################################" @@ -70,21 +69,13 @@ dos2unix /opt/gremlin-server/bin/gremlin-server.conf # docker/gremlin-server.sh # cd ${APACHE_TINKERPOP} # second terminal -# export KRB5_CONFIG=`pwd`/docker/gremlin-server/krb5.conf -# echo 'password' | kinit stephen -# klist # Gremlin-Groovy # -------------- -# KRB5_OPTION="-Djava.security.krb5.conf=`pwd`/docker/gremlin-server/krb5.conf" -# JAAS_OPTION="-Djava.security.auth.login.config=`pwd`/docker/gremlin-server/gremlin-console-jaas.conf" -# export JAVA_OPTIONS="${KRB5_OPTION} ${JAAS_OPTION}" # cd gremlin-console/target/apache-tinkerpop-gremlin-console-3.x.y-SNAPSHOT-standalone -# If necessary (versions 3.4.2-3.4.6): in bin/gremlin.sh replace JVM_OPTS+=( "${JAVA_OPTIONS}" ) by JVM_OPTS+=( ${JAVA_OPTIONS} ) # bin/gremlin.sh # gremlin> cluster = Cluster.build("172.17.0.2").port(45940).create() # gremlin> cluster = Cluster.build("172.17.0.2").port(45941).credentials("stephen", "password").create() -# gremlin> cluster = Cluster.build("172.17.0.2").port(45942).addContactPoint("gremlin-server-test").protocol("test-service").jaasEntry("GremlinConsole").create() # gremlin> g = traversal().withRemote(DriverRemoteConnection.using(cluster, "gmodern")) # gremlin> g.V() @@ -97,5 +88,4 @@ dos2unix /opt/gremlin-server/bin/gremlin-server.conf # >>> from gremlin_python.driver.driver_remote_connection import DriverRemoteConnection # >>> g = traversal().withRemote(DriverRemoteConnection('ws://172.17.0.2:45940/gremlin','gmodern')) # >>> g = traversal().withRemote(DriverRemoteConnection('ws://172.17.0.2:45941/gremlin','gmodern', username='stephen', password='password')) -# >>> g = traversal().withRemote(DriverRemoteConnection('ws://172.17.0.2:45942/gremlin','gmodern', kerberized_service='test-service@gremlin-server-test')) # >>> g.V().toList() diff --git a/docker/gremlin-server/gremlin-console-jaas.conf b/docker/gremlin-server/gremlin-console-jaas.conf deleted file mode 100644 index a1170bceaa..0000000000 --- a/docker/gremlin-server/gremlin-console-jaas.conf +++ /dev/null @@ -1,24 +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. - */ - -GremlinConsole { - com.sun.security.auth.module.Krb5LoginModule required - doNotPrompt=true - useTicketCache=true; -}; diff --git a/docker/gremlin-server/gremlin-server-integration-krb5.yaml b/docker/gremlin-server/gremlin-server-integration-krb5.yaml deleted file mode 100644 index 6ba803b59d..0000000000 --- a/docker/gremlin-server/gremlin-server-integration-krb5.yaml +++ /dev/null @@ -1,73 +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. - -host: 0.0.0.0 -port: 45942 -evaluationTimeout: 30000 -graphs: { - graph: { - configuration: conf/tinkergraph-empty.properties, - traversalSources: [{name: g}, {name: ggraph}]}, - classic: { - configuration: conf/tinkergraph-empty.properties, - traversalSources: [{name: gclassic}]}, - modern: { - configuration: conf/tinkergraph-empty.properties, - traversalSources: [{name: gmodern}]}, - crew: { - configuration: conf/tinkergraph-empty.properties, - traversalSources: [{name: gcrew}]}, - grateful: { - configuration: conf/tinkergraph-empty.properties, - traversalSources: [{name: ggrateful}]}, - sink: { - configuration: conf/tinkergraph-empty.properties, - traversalSources: [{name: gsink}]}, - tx: { - configuration: conf/tinkertransactiongraph-empty.properties, - traversalSources: [{name: gtx}]}} -lifecycleHooks: - - { className: org.apache.tinkerpop.gremlin.server.util.TinkerFactoryDataLoader, config: {graph: classic, dataset: classic}} - - { className: org.apache.tinkerpop.gremlin.server.util.TinkerFactoryDataLoader, config: {graph: modern, dataset: modern}} - - { className: org.apache.tinkerpop.gremlin.server.util.TinkerFactoryDataLoader, config: {graph: crew, dataset: crew}} - - { className: org.apache.tinkerpop.gremlin.server.util.TinkerFactoryDataLoader, config: {graph: grateful, dataset: grateful}} - - { className: org.apache.tinkerpop.gremlin.server.util.TinkerFactoryDataLoader, config: {graph: sink, dataset: sink}} -serializers: - - { className: org.apache.tinkerpop.gremlin.util.ser.GraphSONMessageSerializerV3, config: { ioRegistries: [org.apache.tinkerpop.gremlin.tinkergraph.structure.TinkerIoRegistryV3] }} - - { className: org.apache.tinkerpop.gremlin.util.ser.GraphSONMessageSerializerV2, config: { ioRegistries: [org.apache.tinkerpop.gremlin.tinkergraph.structure.TinkerIoRegistryV2] }} - - { className: org.apache.tinkerpop.gremlin.util.ser.GraphSONMessageSerializerV1, config: { ioRegistries: [org.apache.tinkerpop.gremlin.tinkergraph.structure.TinkerIoRegistryV1] }} - - { className: org.apache.tinkerpop.gremlin.util.ser.GraphBinaryMessageSerializerV1 } - - { className: org.apache.tinkerpop.gremlin.util.ser.GraphBinaryMessageSerializerV1, config: { serializeResultToString: true }} -metrics: { - slf4jReporter: {enabled: true, interval: 180000}} -gremlinPool: 8 -strictTransactionManagement: false -idleConnectionTimeout: 0 -keepAliveInterval: 0 -maxInitialLineLength: 4096 -maxHeaderSize: 8192 -maxChunkSize: 8192 -maxRequestContentLength: 10485760 -maxAccumulationBufferComponents: 1024 -resultIterationBatchSize: 64 -writeBufferLowWaterMark: 32768 -writeBufferHighWaterMark: 65536 -authentication: { - authenticator: org.apache.tinkerpop.gremlin.server.auth.Krb5Authenticator, - config: { - principal: test-service/[email protected], - keytab: /opt/gremlin-server/target/kdc/test-service.keytab}} diff --git a/docker/gremlin-server/krb5.conf b/docker/gremlin-server/krb5.conf deleted file mode 100644 index 3ee9e3d482..0000000000 --- a/docker/gremlin-server/krb5.conf +++ /dev/null @@ -1,30 +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. -# - -[libdefaults] - kdc_realm = TEST.COM - default_realm = TEST.COM - udp_preference_limit = 4096 - kdc_tcp_port = 4588 - kdc_udp_port = 4588 - -[realms] - TEST.COM = { - kdc = 172.17.0.2:4588 - } diff --git a/docker/gremlin-test-server/Dockerfile b/docker/gremlin-test-server/Dockerfile index 3740499dcc..c7c8a767b2 100644 --- a/docker/gremlin-test-server/Dockerfile +++ b/docker/gremlin-test-server/Dockerfile @@ -36,7 +36,7 @@ RUN dos2unix /opt/docker-entrypoint.sh /opt/gremlin-server/bin/gremlin-server.sh ARG GREMLIN_SERVER ENV GREMLIN_SERVER_VERSION=$GREMLIN_SERVER -EXPOSE 45940-45942 4588 +EXPOSE 45940 45941 ENTRYPOINT ["/opt/docker-entrypoint.sh"] CMD [] diff --git a/docker/gremlin-test-server/krb5.conf b/docker/gremlin-test-server/krb5.conf deleted file mode 100644 index 1c870522e7..0000000000 --- a/docker/gremlin-test-server/krb5.conf +++ /dev/null @@ -1,32 +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. -# - -[libdefaults] - kdc_realm = TEST.COM - default_realm = TEST.COM - udp_preference_limit = 4096 - kdc_tcp_port = 4588 - kdc_udp_port = 4588 - dns_canonicalize_hostname = false - qualify_shortname = "" - -[realms] - TEST.COM = { - kdc = gremlin-server-test:4588 - } diff --git a/gremlin-dotnet/docker-compose.yml b/gremlin-dotnet/docker-compose.yml index d68175d0e3..2f7a60b01f 100644 --- a/gremlin-dotnet/docker-compose.yml +++ b/gremlin-dotnet/docker-compose.yml @@ -28,8 +28,6 @@ services: ports: - "45940:45940" - "45941:45941" - - "45942:45942" - - "4588:4588" volumes: - ${HOME}/.groovy:/root/.groovy - ${HOME}/.m2:/root/.m2 diff --git a/gremlin-dotnet/test/pom.xml b/gremlin-dotnet/test/pom.xml index d7d9f8842a..82b1037f32 100644 --- a/gremlin-dotnet/test/pom.xml +++ b/gremlin-dotnet/test/pom.xml @@ -109,7 +109,7 @@ limitations under the License. compose up - build images, start the server and test containers, and wait for the test container to finish compose down (second) - tear down this run's containers and network - port-wait loop - wait up to 30 s for ports 45940-45942 and 4588 to be released by + port-wait loop - wait up to 30 s for ports 45940 and 45941 to be released by the Docker daemon before returning to Maven; all GLV modules share these host ports and run sequentially, so the next module would fail to bind them if docker-proxy has not fully exited yet @@ -117,7 +117,7 @@ limitations under the License. --> <arguments> <argument>-c</argument> - <argument>docker compose down; docker compose up --build --exit-code-from gremlin-dotnet-integration-tests; EXIT=$?; docker compose down; for i in $(seq 1 30); do ss -tlnp | grep -qE ':(45940|45941|45942|4588) ' || break; sleep 1; done; docker image prune --filter [email protected] -f; exit $EXIT</argument> + <argument>docker compose down; docker compose up --build --exit-code-from gremlin-dotnet-integration-tests; EXIT=$?; docker compose down; for i in $(seq 1 30); do ss -tlnp | grep -qE ':(45940|45941) ' || break; sleep 1; done; docker image prune --filter [email protected] -f; exit $EXIT</argument> </arguments> </configuration> </execution> diff --git a/gremlin-examples/gremlin-python/connections.py b/gremlin-examples/gremlin-python/connections.py index 7008ddac72..8f06fe27a3 100644 --- a/gremlin-examples/gremlin-python/connections.py +++ b/gremlin-examples/gremlin-python/connections.py @@ -29,7 +29,6 @@ VERTEX_LABEL = 'connection' def main(): with_remote() with_auth() - with_kerberos() with_configs() @@ -67,25 +66,12 @@ def with_auth(): rc.close() -# connecting with Kerberos SASL authentication -def with_kerberos(): - server_url = 'ws://localhost:8182/gremlin' - rc = DriverRemoteConnection(server_url, 'g', kerberized_service='[email protected]') - g = traversal().with_remote(rc) - - v = g.add_v(VERTEX_LABEL).iterate() - count = g.V().has_label(VERTEX_LABEL).count().next() - print("Vertex count: " + str(count)) - - rc.close() - - # connecting with customized configurations def with_configs(): server_url = 'ws://localhost:8182/gremlin' rc = DriverRemoteConnection( server_url, 'g', - username="", password="", kerberized_service='', + username="", password="", message_serializer=GraphBinarySerializersV1(), graphson_reader=None, graphson_writer=None, headers=None, session=None, enable_user_agent_on_connect=True diff --git a/gremlin-go/docker-compose.yml b/gremlin-go/docker-compose.yml index 5df1561826..bcce6b8630 100644 --- a/gremlin-go/docker-compose.yml +++ b/gremlin-go/docker-compose.yml @@ -28,8 +28,6 @@ services: ports: - "45940:45940" - "45941:45941" - - "45942:45942" - - "4588:4588" volumes: - ${HOME}/.groovy:/root/.groovy - ${HOME}/.m2:/root/.m2 diff --git a/gremlin-go/pom.xml b/gremlin-go/pom.xml index 5d5019a476..355687582d 100644 --- a/gremlin-go/pom.xml +++ b/gremlin-go/pom.xml @@ -120,7 +120,7 @@ limitations under the License. compose up - build images, start the server and test containers, and wait for the test container to finish compose down (second) - tear down this run's containers and network - port-wait loop - wait up to 30 s for ports 45940-45942 and 4588 to be released by + port-wait loop - wait up to 30 s for ports 45940 and 45941 to be released by the Docker daemon before returning to Maven; all GLV modules share these host ports and run sequentially, so the next module would fail to bind them if docker-proxy has not fully exited yet @@ -128,7 +128,7 @@ limitations under the License. --> <arguments> <argument>-c</argument> - <argument>docker compose down; docker compose up --build --exit-code-from gremlin-go-integration-tests; EXIT=$?; docker compose down; for i in $(seq 1 30); do ss -tlnp | grep -qE ':(45940|45941|45942|4588) ' || break; sleep 1; done; docker image prune --filter [email protected] -f; exit $EXIT</argument> + <argument>docker compose down; docker compose up --build --exit-code-from gremlin-go-integration-tests; EXIT=$?; docker compose down; for i in $(seq 1 30); do ss -tlnp | grep -qE ':(45940|45941) ' || break; sleep 1; done; docker image prune --filter [email protected] -f; exit $EXIT</argument> </arguments> </configuration> </execution> diff --git a/gremlin-js/gremlin-javascript/docker-compose.yml b/gremlin-js/gremlin-javascript/docker-compose.yml index 6b90238a30..1c00082634 100644 --- a/gremlin-js/gremlin-javascript/docker-compose.yml +++ b/gremlin-js/gremlin-javascript/docker-compose.yml @@ -28,8 +28,6 @@ services: ports: - "45940:45940" - "45941:45941" - - "45942:45942" - - "4588:4588" volumes: - ${HOME}/.groovy:/root/.groovy - ${HOME}/.m2:/root/.m2 diff --git a/gremlin-js/gremlin-javascript/pom.xml b/gremlin-js/gremlin-javascript/pom.xml index a9adfe4d40..0957b4ec32 100644 --- a/gremlin-js/gremlin-javascript/pom.xml +++ b/gremlin-js/gremlin-javascript/pom.xml @@ -281,7 +281,7 @@ limitations under the License. compose up - build images, start the server and test containers, and wait for the test container to finish compose down (second) - tear down this run's containers and network - port-wait loop - wait up to 30 s for ports 45940-45942 and 4588 to be released by + port-wait loop - wait up to 30 s for ports 45940 and 45941 to be released by the Docker daemon before returning to Maven; all GLV modules share these host ports and run sequentially, so the next module would fail to bind them if docker-proxy has not fully exited yet @@ -289,7 +289,7 @@ limitations under the License. --> <arguments> <argument>-c</argument> - <argument>export HOST_UID=$(id -u) HOST_GID=$(id -g); docker compose down; docker compose up --build --exit-code-from gremlin-js-integration-tests; EXIT=$?; docker compose down; for i in $(seq 1 30); do ss -tlnp | grep -qE ':(45940|45941|45942|4588) ' || break; sleep 1; done; docker image prune --filter [email protected] -f; exit $EXIT</argument> + <argument>export HOST_UID=$(id -u) HOST_GID=$(id -g); docker compose down; docker compose up --build --exit-code-from gremlin-js-integration-tests; EXIT=$?; docker compose down; for i in $(seq 1 30); do ss -tlnp | grep -qE ':(45940|45941) ' || break; sleep 1; done; docker image prune --filter [email protected] -f; exit $EXIT</argument> </arguments> <workingDirectory>.</workingDirectory> </configuration> diff --git a/gremlin-python/docker-compose.yml b/gremlin-python/docker-compose.yml index 2876bbf048..cdb4cbfdcc 100644 --- a/gremlin-python/docker-compose.yml +++ b/gremlin-python/docker-compose.yml @@ -29,7 +29,6 @@ services: ports: - "45940:45940" - "45941:45941" - - "4588:4588" volumes: - ${HOME}/.groovy:/root/.groovy - ${HOME}/.m2:/root/.m2 diff --git a/gremlin-python/pom.xml b/gremlin-python/pom.xml index 9ef88c19df..63680b3dd4 100644 --- a/gremlin-python/pom.xml +++ b/gremlin-python/pom.xml @@ -161,7 +161,7 @@ limitations under the License. compose up - build images, start the server and test containers, and stop everything when either container exits compose down (second) - tear down this run's containers and network - port-wait loop - wait up to 30 s for ports 45940-45942 and 4588 to be released by + port-wait loop - wait up to 30 s for ports 45940 and 45941 to be released by the Docker daemon before returning to Maven; all GLV modules share these host ports and run sequentially, so the next module would fail to bind them if docker-proxy has not fully exited yet @@ -184,7 +184,7 @@ limitations under the License. <env key="PYTEST_ARGS" value="${pytestArgs}"/> <env key="RADISH_ARGS" value="${radishArgs}"/> <arg value="-c"/> - <arg value="docker compose down; docker compose up --build --abort-on-container-exit gremlin-server-test-python gremlin-python-integration-tests; EXIT=$?; docker compose down; for i in $(seq 1 30); do ss -tlnp | grep -qE ':(45940|45941|45942|4588) ' || break; sleep 1; done; docker image prune --filter [email protected] -f; exit $EXIT"/> + <arg value="docker compose down; docker compose up --build --abort-on-container-exit gremlin-server-test-python gremlin-python-integration-tests; EXIT=$?; docker compose down; for i in $(seq 1 30); do ss -tlnp | grep -qE ':(45940|45941) ' || break; sleep 1; done; docker image prune --filter [email protected] -f; exit $EXIT"/> </exec> </target> </configuration> diff --git a/gremlin-python/src/main/python/pyproject.toml b/gremlin-python/src/main/python/pyproject.toml index 8510bc701b..bccddf4cd6 100644 --- a/gremlin-python/src/main/python/pyproject.toml +++ b/gremlin-python/src/main/python/pyproject.toml @@ -51,7 +51,6 @@ classifiers = [ Homepage = "https://tinkerpop.apache.org" [project.optional-dependencies] -kerberos = ["kerberos>=1.3.0,<2.0.0; sys_platform != \"win32\""] ujson = ["ujson>=2.0.0"] test = [ "pytest>=6.2.5,<8.0.0", diff --git a/gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/auth/JaasKrbUtil.java b/gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/auth/JaasKrbUtil.java deleted file mode 100644 index 48c4546151..0000000000 --- a/gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/auth/JaasKrbUtil.java +++ /dev/null @@ -1,226 +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.tinkerpop.gremlin.server.auth; - -import javax.security.auth.Subject; -import javax.security.auth.callback.Callback; -import javax.security.auth.callback.CallbackHandler; -import javax.security.auth.callback.PasswordCallback; -import javax.security.auth.callback.UnsupportedCallbackException; -import javax.security.auth.kerberos.KerberosPrincipal; -import javax.security.auth.login.AppConfigurationEntry; -import javax.security.auth.login.Configuration; -import javax.security.auth.login.LoginContext; -import javax.security.auth.login.LoginException; -import java.io.File; -import java.io.IOException; -import java.security.Principal; -import java.util.HashMap; -import java.util.HashSet; -import java.util.Map; -import java.util.Set; - -/** - * JAAS utilities for Kerberos login. - * - * Except for the package name and this comment, this file is a literal copy from - * package org.apache.kerby.kerberos.kerb.client, see: - * https://github.com/apache/directory-kerby/blob/kerby-all-1.0.0-RC2/kerby-kerb/kerb-simplekdc/ - * src/main/java/org/apache/kerby/kerberos/kerb/client/JaasKrbUtil.java - */ -public final class JaasKrbUtil { - - public static final boolean ENABLE_DEBUG = false; - - private JaasKrbUtil() { } - - public static Subject loginUsingPassword( - String principal, String password) throws LoginException { - Set<Principal> principals = new HashSet<Principal>(); - principals.add(new KerberosPrincipal(principal)); - - Subject subject = new Subject(false, principals, - new HashSet<Object>(), new HashSet<Object>()); - - Configuration conf = usePassword(principal); - String confName = "PasswordConf"; - CallbackHandler callback = new KrbCallbackHandler(principal, password); - LoginContext loginContext = new LoginContext(confName, subject, callback, conf); - loginContext.login(); - return loginContext.getSubject(); - } - - public static Subject loginUsingTicketCache( - String principal, File cacheFile) throws LoginException { - Set<Principal> principals = new HashSet<Principal>(); - principals.add(new KerberosPrincipal(principal)); - - Subject subject = new Subject(false, principals, - new HashSet<Object>(), new HashSet<Object>()); - - Configuration conf = useTicketCache(principal, cacheFile); - String confName = "TicketCacheConf"; - LoginContext loginContext = new LoginContext(confName, subject, null, conf); - loginContext.login(); - return loginContext.getSubject(); - } - - public static Subject loginUsingKeytab( - String principal, File keytabFile) throws LoginException { - Set<Principal> principals = new HashSet<Principal>(); - principals.add(new KerberosPrincipal(principal)); - - Subject subject = new Subject(false, principals, - new HashSet<Object>(), new HashSet<Object>()); - - Configuration conf = useKeytab(principal, keytabFile); - String confName = "KeytabConf"; - LoginContext loginContext = new LoginContext(confName, subject, null, conf); - loginContext.login(); - return loginContext.getSubject(); - } - - public static Configuration usePassword(String principal) { - return new PasswordJaasConf(principal); - } - - public static Configuration useTicketCache(String principal, - File credentialFile) { - return new TicketCacheJaasConf(principal, credentialFile); - } - - public static Configuration useKeytab(String principal, File keytabFile) { - return new KeytabJaasConf(principal, keytabFile); - } - - private static String getKrb5LoginModuleName() { - return System.getProperty("java.vendor").contains("IBM") - ? "com.ibm.security.auth.module.Krb5LoginModule" - : "com.sun.security.auth.module.Krb5LoginModule"; - } - - static class KeytabJaasConf extends Configuration { - private String principal; - private File keytabFile; - - KeytabJaasConf(String principal, File keytab) { - this.principal = principal; - this.keytabFile = keytab; - } - - @Override - public AppConfigurationEntry[] getAppConfigurationEntry(String name) { - Map<String, String> options = new HashMap<String, String>(); - options.put("keyTab", keytabFile.getAbsolutePath()); - options.put("principal", principal); - options.put("useKeyTab", "true"); - options.put("storeKey", "true"); - options.put("doNotPrompt", "true"); - options.put("renewTGT", "false"); - options.put("refreshKrb5Config", "true"); - options.put("isInitiator", "true"); - options.put("debug", String.valueOf(ENABLE_DEBUG)); - - return new AppConfigurationEntry[]{ - new AppConfigurationEntry(getKrb5LoginModuleName(), - AppConfigurationEntry.LoginModuleControlFlag.REQUIRED, - options)}; - } - } - - static class TicketCacheJaasConf extends Configuration { - private String principal; - private File clientCredentialFile; - - TicketCacheJaasConf(String principal, File clientCredentialFile) { - this.principal = principal; - this.clientCredentialFile = clientCredentialFile; - } - - @Override - public AppConfigurationEntry[] getAppConfigurationEntry(String name) { - Map<String, String> options = new HashMap<String, String>(); - options.put("principal", principal); - options.put("storeKey", "false"); - options.put("doNotPrompt", "false"); - options.put("useTicketCache", "true"); - options.put("renewTGT", "true"); - options.put("refreshKrb5Config", "true"); - options.put("isInitiator", "true"); - options.put("ticketCache", clientCredentialFile.getAbsolutePath()); - options.put("debug", String.valueOf(ENABLE_DEBUG)); - - return new AppConfigurationEntry[]{ - new AppConfigurationEntry(getKrb5LoginModuleName(), - AppConfigurationEntry.LoginModuleControlFlag.REQUIRED, - options)}; - } - } - - static class PasswordJaasConf extends Configuration { - private String principal; - - PasswordJaasConf(String principal) { - this.principal = principal; - } - - @Override - public AppConfigurationEntry[] getAppConfigurationEntry(String name) { - Map<String, String> options = new HashMap<>(); - options.put("principal", principal); - options.put("storeKey", "true"); - options.put("useTicketCache", "true"); - options.put("useKeyTab", "false"); - options.put("renewTGT", "true"); - options.put("refreshKrb5Config", "true"); - options.put("isInitiator", "true"); - options.put("debug", String.valueOf(ENABLE_DEBUG)); - - return new AppConfigurationEntry[]{ - new AppConfigurationEntry(getKrb5LoginModuleName(), - AppConfigurationEntry.LoginModuleControlFlag.REQUIRED, - options)}; - } - } - - public static class KrbCallbackHandler implements CallbackHandler { - private String principal; - private String password; - - public KrbCallbackHandler(String principal, String password) { - this.principal = principal; - this.password = password; - } - - public void handle(Callback[] callbacks) - throws IOException, UnsupportedCallbackException { - for (int i = 0; i < callbacks.length; i++) { - if (callbacks[i] instanceof PasswordCallback) { - PasswordCallback pc = (PasswordCallback) callbacks[i]; - if (pc.getPrompt().contains(principal)) { - pc.setPassword(password.toCharArray()); - break; - } - } - } - } - } - -} diff --git a/gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/auth/Krb5Authenticator.java b/gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/auth/Krb5Authenticator.java deleted file mode 100644 index ed7640eb05..0000000000 --- a/gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/auth/Krb5Authenticator.java +++ /dev/null @@ -1,197 +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.tinkerpop.gremlin.server.auth; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import javax.security.auth.Subject; -import javax.security.auth.callback.Callback; -import javax.security.auth.callback.CallbackHandler; -import javax.security.auth.callback.UnsupportedCallbackException; -import javax.security.sasl.AuthorizeCallback; -import javax.security.sasl.Sasl; -import javax.security.sasl.SaslException; -import javax.security.sasl.SaslServer; -import java.io.File; -import java.net.InetAddress; -import java.security.PrivilegedAction; -import java.util.HashMap; -import java.util.Map; - - -/** - * A Kerberos (GSSAPI) implementation of an {@link Authenticator} - * This authenticator authenticates and autorizes all clients with a valid service ticket. - * - * @author Marc de Lignie - */ -public class Krb5Authenticator implements Authenticator { - private static final Logger logger = LoggerFactory.getLogger(Krb5Authenticator.class); - private Subject subject; - private String principalName; - - @Override - public boolean requireAuthentication() { - return true; - } - - /** - * Called once on server startup with the authentication.config from the *.yaml file - */ - @Override - public void setup(final Map<String, Object> config) { - final String KEYTAB_KEY = "keytab"; - final String PRINCIPAL_KEY = "principal"; - - logger.info("Config: {}", config); - - if (null == config || !config.containsKey(KEYTAB_KEY) || !config.containsKey(PRINCIPAL_KEY)) { - throw new IllegalArgumentException(String.format( - "Could not configure a %s - provide a 'config' in the 'authentication' settings", - Krb5Authenticator.class.getName())); - } - - try { - final File keytabFile = new File((String) config.get(KEYTAB_KEY)); - principalName = (String) config.get(PRINCIPAL_KEY); - subject = JaasKrbUtil.loginUsingKeytab(principalName, keytabFile); - } catch (Exception e) { - logger.warn("Failed to login to kdc:" + e.getMessage()); - } - - logger.debug("Done logging in to kdc"); - } - - @Override - public SaslNegotiator newSaslNegotiator(final InetAddress remoteAddress) { - logger.debug("newSaslNegotiator() called"); - return Subject.doAs(subject, (PrivilegedAction<SaslNegotiator>) Krb5SaslAuthenticator::new); - } - - public AuthenticatedUser authenticate(final Map<String, String> credentials) throws AuthenticationException { - logger.error("Authenticate() should not be called. Use getAuthenticatedUser() when isComplete() is true."); - return null; - } - - /* - * Krb5SaslAuthenticator is invoked by: - * org.apache.tinkerpop.gremlin.server.handler.SaslAuthenticationHandler - * Negotiates with evaluateChallenge() of the generic sasl handler in gremlin console: - * org.apache.tinkerpop.gremlin.driver.Handler.java - * See also: - * https://docs.oracle.com/javase/8/docs/technotes/guides/security/sasl/sasl-refguide.html - * https://docs.oracle.com/javase/8/docs/api/org/ietf/jgss/GSSContext.html - * Kerberos authentication/authorization message flow: - * http://www.roguelynn.com/words/explain-like-im-5-kerberos/ - */ - private class Krb5SaslAuthenticator implements Authenticator.SaslNegotiator, CallbackHandler { - private final String mechanism = "GSSAPI"; - private SaslServer saslServer; - - Krb5SaslAuthenticator() { - try { - // For sasl properties regarding GSSAPI, see: - // https://docs.oracle.com/javase/8/docs/technotes/guides/security/sasl/sasl-refguide.html#SERVER - // Rely on GSSAPI defaults for Sasl.MAX_BUFFER and Sasl.QOP. Note, however, that gremlin-driver has - // Sasl.SERVER_AUTH fixed to true (mutual authentication) and one can configure SSL for enhanced confidentiality, - // Sasl policy properties for negotiating the authentication mechanism are not relevant here, because - // GSSAPI is the only available mechanism for this authenticator - final Map<String, Object> props = new HashMap<>(); - if (principalName == null) { - throw new IllegalArgumentException("Principal name cannot be empty. Use principal name of format 'service/fqdn@kdcrealm'"); - } - final String[] principalParts = principalName.split("/|@"); - if (principalParts.length < 3) throw new IllegalArgumentException("Use principal name of format 'service/fqdn@kdcrealm'"); - saslServer = Sasl.createSaslServer(mechanism, principalParts[0], principalParts[1], props, Krb5SaslAuthenticator.this); - - } catch(SaslException e) { - logger.error("Creating sasl server failed: ", e); - throw new IllegalStateException(e); - } - - // createSaslServer() can return null - if (null == saslServer) { - logger.error("Could not a find a SaslServerFactory for mechanism of {}", mechanism); - throw new IllegalStateException("Creating sasl server failed"); - } - - logger.debug("SaslServer created with: {}", saslServer.getMechanismName()); - } - - /* - * This method is based on the handle() method from: - * https://github.com/apache/directory-kerby/blob/kerby-all-1.0.0-RC2/kerby-kerb/integration-test/src/main/java/org/apache/kerby/kerberos/kerb/integration/test/sasl/SaslAppServer.java - * - * This provides the simplest form of authorization, where each client that provides a valid service ticket, - * is authorized. More elaborate authorization schemes would interrogate a policy server like Apache Ranger - * or ACL's of a storage backend. - */ - @Override - public void handle(final Callback[] callbacks) throws UnsupportedCallbackException { - logger.debug("Krb5 AuthorizeCallback number: " + callbacks.length); - AuthorizeCallback ac = null; - for (Callback callback : callbacks) { - if (callback instanceof AuthorizeCallback) { - ac = (AuthorizeCallback) callback; - } else { - throw new UnsupportedCallbackException(callback, "Unrecognized SASL GSSAPI Callback"); - } - } - if (ac != null) { - final String authid = ac.getAuthenticationID(); - final String authzid = ac.getAuthorizationID(); - if (authid.equals(authzid)) { // Check whether the service ticket belongs to the authenticated user - ac.setAuthorized(true); - } else { - ac.setAuthorized(false); - } - if (ac.isAuthorized()) { // Get user name from his principal name - final String[] authidParts = authid.split("@"); - ac.setAuthorizedID(authidParts[0]); - } - } - } - - @Override - public byte[] evaluateResponse(final byte[] clientResponse) throws AuthenticationException { - logger.debug("evaluateResponse() length: " + clientResponse.length); - byte[] response; - try { - response = saslServer.evaluateResponse(clientResponse); - } catch (Exception e) { - logger.warn("Sasl krb5 evaluateResponse failed: " + e); - throw new AuthenticationException(e); - } - return response; - } - - @Override - public boolean isComplete() { - return saslServer.isComplete(); - } - - @Override - public AuthenticatedUser getAuthenticatedUser() throws AuthenticationException { - logger.debug("getAuthenticatedUser called: " + saslServer.getAuthorizationID()); - return new AuthenticatedUser(saslServer.getAuthorizationID()); - } - - } -} \ No newline at end of file diff --git a/gremlin-server/src/test/java/org/apache/tinkerpop/gremlin/server/GremlinServerAuditLogIntegrateTest.java b/gremlin-server/src/test/java/org/apache/tinkerpop/gremlin/server/GremlinServerAuditLogIntegrateTest.java index 0c8e065563..d17ef1ac50 100644 --- a/gremlin-server/src/test/java/org/apache/tinkerpop/gremlin/server/GremlinServerAuditLogIntegrateTest.java +++ b/gremlin-server/src/test/java/org/apache/tinkerpop/gremlin/server/GremlinServerAuditLogIntegrateTest.java @@ -33,7 +33,6 @@ import org.apache.tinkerpop.gremlin.process.traversal.AnonymousTraversalSource; import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.GraphTraversalSource; import org.apache.tinkerpop.gremlin.server.auth.AllowAllAuthenticator; import org.apache.tinkerpop.gremlin.server.auth.AuthenticatedUser; -import org.apache.tinkerpop.gremlin.server.auth.Krb5Authenticator; import org.apache.tinkerpop.gremlin.server.auth.SimpleAuthenticator; import org.apache.tinkerpop.gremlin.server.channel.HttpChannelizer; import org.apache.tinkerpop.gremlin.server.handler.HttpBasicAuthenticationHandler; @@ -45,7 +44,6 @@ import org.junit.AfterClass; import org.junit.Before; import org.junit.BeforeClass; import org.junit.Test; -import org.slf4j.LoggerFactory; import java.util.Base64; import java.util.HashMap; @@ -59,12 +57,11 @@ import static org.junit.Assert.assertTrue; /** * Test audit logs. Like other descendants of AbstractGremlinServerIntegrationTest this test suite assumes that - * tests are run sequentially and thus the server and kdcServer variables can be reused. + * tests are run sequentially and thus the server variable can be reused. * * @author Marc de Lignie */ public class GremlinServerAuditLogIntegrateTest extends AbstractGremlinServerIntegrationTest { - private static final org.slf4j.Logger logger = LoggerFactory.getLogger(GremlinServerAuditLogIntegrateTest.class); private static LogCaptor logCaptor; @@ -75,8 +72,6 @@ public class GremlinServerAuditLogIntegrateTest extends AbstractGremlinServerInt private static final boolean AUDIT_LOG_DISABLED = false; private static final String TESTCONSOLE2 = "GremlinConsole2"; - private KdcFixture kdcServer; - @BeforeClass public static void setupLogCaptor() { logCaptor = LogCaptor.forName(AUDIT_LOGGER_NAME); @@ -92,66 +87,35 @@ public class GremlinServerAuditLogIntegrateTest extends AbstractGremlinServerInt logCaptor.clearLogs(); } - @Override - public void setUp() throws Exception { - try { - final String moduleBaseDir = System.getProperty("basedir", "."); - final String authConfigName = moduleBaseDir + "/src/test/resources/org/apache/tinkerpop/gremlin/server/gremlin-console-jaas.conf"; - System.setProperty("java.security.auth.login.config", authConfigName); - kdcServer = new KdcFixture(moduleBaseDir); - kdcServer.setUp(); - } catch(Exception ex) { - logger.warn(String.format("Could not start Kerberos Server for %s", name.getMethodName()), ex); - } - super.setUp(); - } - - @Override - public void tearDown() throws Exception { - kdcServer.close(); - System.clearProperty("java.security.auth.login.config"); - super.tearDown(); - } - /** * Configure specific Gremlin Server settings for specific tests. */ @Override public Settings overrideSettings(final Settings settings) { - settings.host = kdcServer.gremlinHostname; + settings.host = "localhost"; final Settings.SslSettings sslConfig = new Settings.SslSettings(); sslConfig.enabled = false; settings.ssl = sslConfig; final Settings.AuthenticationSettings authSettings = new Settings.AuthenticationSettings(); settings.authentication = authSettings; settings.enableAuditLog = AUDIT_LOG_ENABLED; - authSettings.authenticator = Krb5Authenticator.class.getName(); + authSettings.authenticator = SimpleAuthenticator.class.getName(); final Map<String,Object> authConfig = new HashMap<>(); authSettings.config = authConfig; + authConfig.put(SimpleAuthenticator.CONFIG_CREDENTIALS_DB, "conf/tinkergraph-credentials.properties"); final String nameOfTest = name.getMethodName(); switch (nameOfTest) { case "shouldAuditLogWithAllowAllAuthenticator": authSettings.authenticator = AllowAllAuthenticator.class.getName(); - break; - case "shouldAuditLogWithTraversalOp": - case "shouldAuditLogWithSimpleAuthenticator": - authSettings.authenticator = SimpleAuthenticator.class.getName(); - authConfig.put(SimpleAuthenticator.CONFIG_CREDENTIALS_DB, "conf/tinkergraph-credentials.properties"); + authConfig.remove(SimpleAuthenticator.CONFIG_CREDENTIALS_DB); break; case "shouldNotAuditLogWhenDisabled": settings.enableAuditLog = AUDIT_LOG_DISABLED; - case "shouldAuditLogWithKrb5Authenticator": - case "shouldAuditLogTwoClientsWithKrb5Authenticator": - authConfig.put("keytab", kdcServer.serviceKeytabFile.getAbsolutePath()); - authConfig.put("principal", kdcServer.serverPrincipal); break; case "shouldAuditLogWithHttpTransport": - settings.host = "localhost"; settings.channelizer = HttpChannelizer.class.getName(); - authSettings.authenticator = SimpleAuthenticator.class.getName(); authSettings.authenticationHandler = HttpBasicAuthenticationHandler.class.getName(); - authConfig.put(SimpleAuthenticator.CONFIG_CREDENTIALS_DB, "conf/tinkergraph-credentials.properties"); break; } return settings; @@ -160,7 +124,7 @@ public class GremlinServerAuditLogIntegrateTest extends AbstractGremlinServerInt @Test public void shouldAuditLogWithAllowAllAuthenticator() throws Exception { - final Cluster cluster = TestClientFactory.build(kdcServer.gremlinHostname).create(); + final Cluster cluster = TestClientFactory.build().create(); final Client client = cluster.connect(); try { @@ -190,7 +154,7 @@ public class GremlinServerAuditLogIntegrateTest extends AbstractGremlinServerInt final String username = "stephen"; final String password = "password"; - final Cluster cluster = TestClientFactory.build(kdcServer.gremlinHostname).auth(basic(username, password)).create(); + final Cluster cluster = TestClientFactory.build().auth(basic(username, password)).create(); final Client client = cluster.connect(); try { @@ -222,7 +186,7 @@ public class GremlinServerAuditLogIntegrateTest extends AbstractGremlinServerInt final String username = "stephen"; final String password = "password"; - final Cluster cluster = TestClientFactory.build(kdcServer.gremlinHostname).auth(basic(username, password)).create(); + final Cluster cluster = TestClientFactory.build().auth(basic(username, password)).create(); final Client client = cluster.connect(); try { assertEquals(2, client.submit("g.inject(2)").all().get().get(0).getInt()); @@ -278,7 +242,7 @@ public class GremlinServerAuditLogIntegrateTest extends AbstractGremlinServerInt final String username = "stephen"; final String password = "password"; - final Cluster cluster = TestClientFactory.build(kdcServer.gremlinHostname).auth(basic(username, password)).create(); + final Cluster cluster = TestClientFactory.build().auth(basic(username, password)).create(); final GraphTraversalSource g = AnonymousTraversalSource.traversal(). withRemote(DriverRemoteConnection.using(cluster, "gmodern")); diff --git a/gremlin-server/src/test/java/org/apache/tinkerpop/gremlin/server/KdcFixtureTest.java b/gremlin-server/src/test/java/org/apache/tinkerpop/gremlin/server/KdcFixtureTest.java deleted file mode 100644 index d4a70c7e13..0000000000 --- a/gremlin-server/src/test/java/org/apache/tinkerpop/gremlin/server/KdcFixtureTest.java +++ /dev/null @@ -1,43 +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.tinkerpop.gremlin.server; - -import org.junit.Test; - -/** - * Validates the {@code KdcFixture} behavior a bit - tests for a tests. - */ -public class KdcFixtureTest { - - @Test - public void shouldCloseCleanly() throws Exception { - final KdcFixture kdc; - final String moduleBaseDir = System.getProperty("basedir"); - final String authConfigName = moduleBaseDir + "/src/test/resources/org/apache/tinkerpop/gremlin/server/gremlin-console-jaas.conf"; - System.setProperty("java.security.auth.login.config", authConfigName); - kdc = new KdcFixture(moduleBaseDir); - kdc.setUp(); - - // deleting the principals will force an exception when they are deleted a second time on close - kdc.deletePrincipals(); - - // expect a clean shutdown despite failures that will come from trying to delete principals that aren't there - kdc.close(); - } -} diff --git a/gremlin-server/src/test/resources/org/apache/tinkerpop/gremlin/server/gremlin-console-jaas.conf b/gremlin-server/src/test/resources/org/apache/tinkerpop/gremlin/server/gremlin-console-jaas.conf deleted file mode 100644 index a9ce21e865..0000000000 --- a/gremlin-server/src/test/resources/org/apache/tinkerpop/gremlin/server/gremlin-console-jaas.conf +++ /dev/null @@ -1,41 +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. - */ - -GremlinConsole { - com.sun.security.auth.module.Krb5LoginModule required - doNotPrompt=true - useTicketCache=true - ticketCache="target/kdc/test-tkt.cc"; -}; - - -UserNotLoggedIn { - com.sun.security.auth.module.Krb5LoginModule required - doNotPrompt=true - principal="[email protected]" - useTicketCache=true; -}; - - -GremlinConsole2 { - com.sun.security.auth.module.Krb5LoginModule required - doNotPrompt=true - useTicketCache=true - ticketCache="target/kdc/test-tkt2.cc"; -}; diff --git a/gremlin-server/src/test/resources/org/apache/tinkerpop/gremlin/server/gremlin-server-integration.yaml b/gremlin-server/src/test/resources/org/apache/tinkerpop/gremlin/server/gremlin-server-integration.yaml index ff84e4a5e0..53dcc407a6 100644 --- a/gremlin-server/src/test/resources/org/apache/tinkerpop/gremlin/server/gremlin-server-integration.yaml +++ b/gremlin-server/src/test/resources/org/apache/tinkerpop/gremlin/server/gremlin-server-integration.yaml @@ -21,7 +21,6 @@ # Changes to this file need to be appropriately replicated to # # - docker/gremlin-server/gremlin-server-integration.yaml -# - docker/gremlin-server/gremlin-server-integration-krb5.yaml # - docker/gremlin-server/gremlin-server-integration-secure.yaml # # Without such changes, the test docker server can't be started for independent diff --git a/gremlin-server/src/test/scripts/test-server-stop.groovy b/gremlin-server/src/test/scripts/test-server-stop.groovy index 51d1a158ab..f73842ea98 100644 --- a/gremlin-server/src/test/scripts/test-server-stop.groovy +++ b/gremlin-server/src/test/scripts/test-server-stop.groovy @@ -29,12 +29,4 @@ def serverSecure = project.getContextValue("gremlin.server.secure") log.info("Shutting down $serverSecure") serverSecure.stop().join() -def kdcServer = project.getContextValue("gremlin.server.kdcserver") -log.info("Shutting down $kdcServer") -kdcServer.close() - -def serverKrb5 = project.getContextValue("gremlin.server.krb5") -log.info("Shutting down $serverKrb5") -serverKrb5.stop().join() - log.info("All Gremlin Server instances are shutdown for ${executionName}") \ No newline at end of file diff --git a/gremlin-test/pom.xml b/gremlin-test/pom.xml index 62ad88c75f..1c5c7985a6 100644 --- a/gremlin-test/pom.xml +++ b/gremlin-test/pom.xml @@ -83,22 +83,6 @@ limitations under the License. <artifactId>logback-classic</artifactId> <optional>true</optional> </dependency> - <dependency> - <groupId>org.apache.kerby</groupId> - <artifactId>kerb-simplekdc</artifactId> - <version>${kerby.version}</version> - <exclusions> - <exclusion> - <groupId>org.wildfly.common</groupId> - <artifactId>wildfly-common</artifactId> - </exclusion> - </exclusions> - </dependency> - <dependency> - <groupId>org.wildfly.common</groupId> - <artifactId>wildfly-common</artifactId> - <version>1.5.4.Final</version> - </dependency> </dependencies> <build> <directory>${basedir}/target</directory> diff --git a/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/server/KdcFixture.java b/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/server/KdcFixture.java deleted file mode 100644 index 683c1d41bb..0000000000 --- a/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/server/KdcFixture.java +++ /dev/null @@ -1,217 +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.tinkerpop.gremlin.server; - -import org.apache.kerby.kerberos.kerb.KrbException; -import org.apache.kerby.kerberos.kerb.client.KrbClient; -import org.apache.kerby.kerberos.kerb.client.KrbConfig; -import org.apache.kerby.kerberos.kerb.client.KrbConfigKey; -import org.apache.kerby.kerberos.kerb.server.SimpleKdcServer; -import org.apache.kerby.kerberos.kerb.type.ticket.TgtTicket; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.io.File; -import java.net.Inet4Address; - -/** - * This class is derived from the following classes from https://github.com/apache/directory-kerby/blob/kerby-all-1.0.0-RC2: - * - org.apache.kerby.kerberos.kerb.server.TestKdcServer - * - org.apache.kerby.kerberos.kerb.server.KdcTestBase - * - org.apache.kerby.kerberos.kerb.server.LoginTestBase - * - * See also: gremlin-server/src/main/static/NOTICE - * - * @author Marc de Lignie - */ -public class KdcFixture { - - private static final Logger logger = LoggerFactory.getLogger(KdcFixture.class); - - final String clientPassword = "123456"; - final String clientPassword2 = "1234562"; - final String userPassword = "password"; - final String clientPrincipalName = "drankye"; - final String clientPrincipalName2 = "drankye2"; - final String userPrincipalName = "stephen"; - final String serverPrincipalName = "test-service"; - final String ticketCacheFileName = "test-tkt.cc"; - final String ticketCacheFileName2 = "test-tkt2.cc"; - final String serviceKeytabFileName = "test-service.keytab"; - - final String clientPrincipal; - final String clientPrincipal2; - final String serverPrincipal; - final String userPrincipal; - final File testDir; - final File ticketCacheFile; - final File ticketCacheFile2; - final File serviceKeytabFile; - - final String gremlinHostname; - final String kdcHostname; - private SimpleKdcServer kdcServer; - - public KdcFixture(final String moduleBaseDir) { - this(moduleBaseDir, "localhost"); - } - - public KdcFixture(final String moduleBaseDir, final String kdcHostName) { - this.kdcHostname = kdcHostName; - gremlinHostname = findHostname(); - serverPrincipal = serverPrincipalName + "/" + gremlinHostname + "@" + KdcFixture.TestKdcServer.KDC_REALM; - clientPrincipal = clientPrincipalName + "@" + KdcFixture.TestKdcServer.KDC_REALM; - clientPrincipal2 = clientPrincipalName2 + "@" + KdcFixture.TestKdcServer.KDC_REALM; - userPrincipal = userPrincipalName + "@" + KdcFixture.TestKdcServer.KDC_REALM; - - final File targetDir = new File(moduleBaseDir, "target"); - testDir = new File(targetDir, "kdc"); - testDir.mkdirs(); - ticketCacheFile = new File(testDir, ticketCacheFileName); - ticketCacheFile2 = new File(testDir, ticketCacheFileName2); - serviceKeytabFile = new File(testDir, serviceKeytabFileName); - } - - private String findHostname() { - // Hostname setting must be consistent with the way gremlin-console sets gremlin-server's hostname - // and derives gremlin-server's principal name. Also, the hostname needs to be lowercase for use - // in principal names. - String hostname = ""; - try { - hostname = Inet4Address.getLocalHost().getCanonicalHostName().toLowerCase(); - } catch (Exception e) { - logger.error("Hostname not found: " + e.getMessage()); - } - return hostname; - } - - private class TestKdcServer extends SimpleKdcServer { - public static final String KDC_REALM = "TEST.COM"; - public final String HOSTNAME = kdcHostname; - public static final int KDC_PORT = 4588; - - TestKdcServer() throws KrbException { - setKdcRealm(KDC_REALM); - setKdcHost(HOSTNAME); - setAllowTcp(true); - setAllowUdp(true); - setKdcTcpPort(KDC_PORT); - setKdcUdpPort(KDC_PORT); - - final KrbClient krbClnt = getKrbClient(); - final KrbConfig krbConfig = krbClnt.getKrbConfig(); - krbConfig.setString(KrbConfigKey.PERMITTED_ENCTYPES, - "aes128-cts-hmac-sha1-96 des-cbc-crc des-cbc-md5 des3-cbc-sha1"); - krbConfig.setString(KrbConfigKey.DEFAULT_REALM, KDC_REALM); - krbClnt.setTimeout(10 * 1000); - } - } - - public void setUp() throws Exception { - setUpKdcServer(); - setUpPrincipals(); - } - - private void setUpKdcServer() throws Exception { - kdcServer = new TestKdcServer(); - kdcServer.setWorkDir(testDir); - kdcServer.init(); - - // we start/stop the Kdc Server with some rapidity in tests. in low resource environments (travis or docker), - // it's possible that the socket for the server is left in TIME_WAIT when it comes time to restart. with a - // bit of retry and pausing perhaps it will make tests less flaky in those environments - for (int ix = 0; ix < 10; ix++) { - try { - kdcServer.start(); - break; - } catch (Exception ex) { - // on the last try ending in failure just toss the exception - if (ix == 9) throw ex; - final int pause = (ix + 1) * 1500; - logger.warn(String.format("Failed to start Kerberos Server - pausing for %s milliseconds and trying again - try #%s", pause, ix + 1), ex); - Thread.sleep(pause); - } - } - } - - private void setUpPrincipals() throws KrbException { - kdcServer.createPrincipals(serverPrincipal); - kdcServer.exportPrincipal(serverPrincipal, serviceKeytabFile); - - kdcServer.createPrincipal(clientPrincipal, clientPassword); - final TgtTicket tgt = kdcServer.getKrbClient().requestTgt(clientPrincipal, clientPassword); - kdcServer.getKrbClient().storeTicket(tgt, ticketCacheFile); - - kdcServer.createPrincipal(clientPrincipal2, clientPassword2); - final TgtTicket tgt2 = kdcServer.getKrbClient().requestTgt(clientPrincipal2, clientPassword2); - kdcServer.getKrbClient().storeTicket(tgt2, ticketCacheFile2); - - kdcServer.createPrincipal(userPrincipal, userPassword); - } - - public void close() { - deletePrincipals(); - - try { - kdcServer.stop(); - } catch (KrbException krbex) { - logger.warn("Tried to stop KdcServer but encountered an exception", krbex); - } - - ticketCacheFile.delete(); - ticketCacheFile2.delete(); - serviceKeytabFile.delete(); - testDir.delete(); - } - - void deletePrincipals() { - try { - kdcServer.getKadmin().deleteBuiltinPrincipals(); - } catch (KrbException krbex) { - logger.warn("Tried to delete builtin Principals on teardown but failed", krbex); - } - - deletePrincipal(serverPrincipal); - deletePrincipal(clientPrincipal); - deletePrincipal(clientPrincipal2); - } - - private void deletePrincipal(final String principalToDelete) { - try { - kdcServer.deletePrincipal(principalToDelete); - } catch (KrbException krbex) { - logger.warn(String.format("Tried to delete %s Principals on teardown but failed", principalToDelete), krbex); - } - } - - public void createPrincipal(final String principal) throws KrbException { - kdcServer.createPrincipal(principal); - } - - public static void main(final String[] args) throws Exception{ - final String projectBaseDir = args[0]; - // The KDC in docker/gremlin-server.sh needs to be exposed to both the container and the host - final KdcFixture kdcFixture = new KdcFixture(projectBaseDir, "0.0.0.0"); - kdcFixture.setUp(); - logger.info("KDC started with configuration {}/target/kdc/krb5.conf", projectBaseDir); - while (true) { - Thread.sleep(1000); - } - } -} diff --git a/pom.xml b/pom.xml index 646b2ddf19..ed7eb764b7 100644 --- a/pom.xml +++ b/pom.xml @@ -177,7 +177,6 @@ limitations under the License. <javapoet.version>1.13.0</javapoet.version> <jbcrypt.version>0.4</jbcrypt.version> <junit.version>4.13.1</junit.version> - <kerby.version>2.0.3</kerby.version> <logback.version>1.3.15</logback.version> <metrics.version>3.0.2</metrics.version> <mockito.version>5.19.0</mockito.version> @@ -1610,31 +1609,6 @@ limitations under the License. <artifactId>junit</artifactId> <version>${junit.version}</version> </additionalDependency> - <additionalDependency> - <groupId>org.apache.kerby</groupId> - <artifactId>kerb-simplekdc</artifactId> - <version>${kerby.version}</version> - </additionalDependency> - <additionalDependency> - <groupId>org.apache.kerby</groupId> - <artifactId>kerb-server</artifactId> - <version>${kerby.version}</version> - </additionalDependency> - <additionalDependency> - <groupId>org.apache.kerby</groupId> - <artifactId>kerb-client</artifactId> - <version>${kerby.version}</version> - </additionalDependency> - <additionalDependency> - <groupId>org.apache.kerby</groupId> - <artifactId>kerb-common</artifactId> - <version>${kerby.version}</version> - </additionalDependency> - <additionalDependency> - <groupId>org.apache.kerby</groupId> - <artifactId>kerb-core</artifactId> - <version>${kerby.version}</version> - </additionalDependency> <additionalDependency> <groupId>org.javatuples</groupId> <artifactId>javatuples</artifactId> diff --git a/spark-gremlin/pom.xml b/spark-gremlin/pom.xml index d80e0f3e16..ce0eff687e 100644 --- a/spark-gremlin/pom.xml +++ b/spark-gremlin/pom.xml @@ -41,11 +41,6 @@ limitations under the License. <groupId>io.dropwizard.metrics</groupId> <artifactId>metrics-core</artifactId> </exclusion> - <!-- prefer gremlin-test/spark kerby --> - <exclusion> - <groupId>org.apache.kerby</groupId> - <artifactId>kerb-simplekdc</artifactId> - </exclusion> <!-- prefer spark snappy --> <exclusion> <groupId>org.xerial.snappy</groupId> @@ -56,10 +51,6 @@ limitations under the License. <groupId>com.google.code.gson</groupId> <artifactId>gson</artifactId> </exclusion> - <exclusion> - <groupId>org.apache.kerby</groupId> - <artifactId>kerb-core</artifactId> - </exclusion> <exclusion> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-annotations</artifactId>
