[KARAF-2948] Add su and sudo commands
Project: http://git-wip-us.apache.org/repos/asf/karaf/repo Commit: http://git-wip-us.apache.org/repos/asf/karaf/commit/c10dde0c Tree: http://git-wip-us.apache.org/repos/asf/karaf/tree/c10dde0c Diff: http://git-wip-us.apache.org/repos/asf/karaf/diff/c10dde0c Branch: refs/heads/master Commit: c10dde0cd6dec1bec7700c1762a26989944b125d Parents: dde4a38 Author: Guillaume Nodet <gno...@gmail.com> Authored: Mon Apr 28 10:46:51 2014 +0200 Committer: Guillaume Nodet <gno...@gmail.com> Committed: Mon Apr 28 20:01:25 2014 +0200 ---------------------------------------------------------------------- .../apache/karaf/jaas/command/SuCommand.java | 93 ++++++++++++++++++++ .../apache/karaf/jaas/command/SudoCommand.java | 92 +++++++++++++++++++ 2 files changed, 185 insertions(+) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/karaf/blob/c10dde0c/jaas/command/src/main/java/org/apache/karaf/jaas/command/SuCommand.java ---------------------------------------------------------------------- diff --git a/jaas/command/src/main/java/org/apache/karaf/jaas/command/SuCommand.java b/jaas/command/src/main/java/org/apache/karaf/jaas/command/SuCommand.java new file mode 100644 index 0000000..9a1a265 --- /dev/null +++ b/jaas/command/src/main/java/org/apache/karaf/jaas/command/SuCommand.java @@ -0,0 +1,93 @@ +/* + * 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.karaf.jaas.command; + +import java.io.IOException; +import java.security.PrivilegedExceptionAction; + +import javax.security.auth.Subject; +import javax.security.auth.callback.Callback; +import javax.security.auth.callback.CallbackHandler; +import javax.security.auth.callback.NameCallback; +import javax.security.auth.callback.PasswordCallback; +import javax.security.auth.callback.UnsupportedCallbackException; +import javax.security.auth.login.LoginContext; + +import org.apache.karaf.jaas.modules.JaasHelper; +import org.apache.karaf.shell.api.action.Action; +import org.apache.karaf.shell.api.action.Argument; +import org.apache.karaf.shell.api.action.Command; +import org.apache.karaf.shell.api.action.Option; +import org.apache.karaf.shell.api.action.lifecycle.Reference; +import org.apache.karaf.shell.api.action.lifecycle.Service; +import org.apache.karaf.shell.api.console.Session; +import org.apache.karaf.shell.support.ShellUtil; + +@Command(scope = "jaas", name = "su", description = "Substitute user identity") +@Service +public class SuCommand implements Action { + + @Option(name = "--realm") + String realm = "karaf"; + + @Argument(description = "Name of the user to substitute") + String user = "karaf"; + + @Reference + Session session; + + @Override + public Object execute() throws Exception { + Subject subject = new Subject(); + LoginContext loginContext = new LoginContext(realm, subject, new CallbackHandler() { + public void handle(Callback[] callbacks) throws IOException, UnsupportedCallbackException { + for (Callback callback : callbacks) { + if (callback instanceof NameCallback) { + ((NameCallback) callback).setName(user); + } else if (callback instanceof PasswordCallback) { + String password = SuCommand.this.session.readLine("Password: ", '*'); + ((PasswordCallback) callback).setPassword(password.toCharArray()); + } else { + throw new UnsupportedCallbackException(callback); + } + } + } + }); + loginContext.login(); + + JaasHelper.doAs(subject, new PrivilegedExceptionAction<Object>() { + public Object run() throws InterruptedException { + final Session newSession = session.getFactory().create( + System.in, System.out, System.err, SuCommand.this.session.getTerminal(), null, null); + Object oldIgnoreInterrupts = session.get(Session.IGNORE_INTERRUPTS); + try { + session.put(Session.IGNORE_INTERRUPTS, Boolean.TRUE); + String name = "Karaf local console user " + ShellUtil.getCurrentUserName(); + Thread thread = new Thread(newSession, name); + thread.start(); + thread.join(); + } finally { + session.put(Session.IGNORE_INTERRUPTS, oldIgnoreInterrupts); + } + return null; + } + }); + + loginContext.logout(); + return null; + } + +} http://git-wip-us.apache.org/repos/asf/karaf/blob/c10dde0c/jaas/command/src/main/java/org/apache/karaf/jaas/command/SudoCommand.java ---------------------------------------------------------------------- diff --git a/jaas/command/src/main/java/org/apache/karaf/jaas/command/SudoCommand.java b/jaas/command/src/main/java/org/apache/karaf/jaas/command/SudoCommand.java new file mode 100644 index 0000000..ba027c6 --- /dev/null +++ b/jaas/command/src/main/java/org/apache/karaf/jaas/command/SudoCommand.java @@ -0,0 +1,92 @@ +/* + * 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.karaf.jaas.command; + +import java.io.IOException; +import java.security.PrivilegedExceptionAction; +import java.util.List; + +import javax.security.auth.Subject; +import javax.security.auth.callback.Callback; +import javax.security.auth.callback.CallbackHandler; +import javax.security.auth.callback.NameCallback; +import javax.security.auth.callback.PasswordCallback; +import javax.security.auth.callback.UnsupportedCallbackException; +import javax.security.auth.login.LoginContext; + +import org.apache.karaf.jaas.modules.JaasHelper; +import org.apache.karaf.shell.api.action.Action; +import org.apache.karaf.shell.api.action.Argument; +import org.apache.karaf.shell.api.action.Command; +import org.apache.karaf.shell.api.action.Option; +import org.apache.karaf.shell.api.action.lifecycle.Reference; +import org.apache.karaf.shell.api.action.lifecycle.Service; +import org.apache.karaf.shell.api.console.Session; + +@Command(scope = "jaas", name = "sudo", description = "Execute a command as another user") +@Service +public class SudoCommand implements Action { + + @Option(name = "--realm") + String realm = "karaf"; + + @Option(name = "--user") + String user = "karaf"; + + @Argument(multiValued = true) + List<String> command; + + @Reference + Session session; + + @Override + public Object execute() throws Exception { + Subject subject = new Subject(); + LoginContext loginContext = new LoginContext(realm, subject, new CallbackHandler() { + public void handle(Callback[] callbacks) throws IOException, UnsupportedCallbackException { + for (Callback callback : callbacks) { + if (callback instanceof NameCallback) { + ((NameCallback) callback).setName(user); + } else if (callback instanceof PasswordCallback) { + String password = SudoCommand.this.session.readLine("Password: ", '*'); + ((PasswordCallback) callback).setPassword(password.toCharArray()); + } else { + throw new UnsupportedCallbackException(callback); + } + } + } + }); + loginContext.login(); + + final StringBuilder sb = new StringBuilder(); + for (String s : command) { + if (sb.length() > 0) { + sb.append(" "); + } + sb.append(s); + } + JaasHelper.doAs(subject, new PrivilegedExceptionAction<Object>() { + @Override + public Object run() throws Exception { + return session.execute(sb); + } + }); + + loginContext.logout(); + return null; + } + +}