[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;
+    }
+
+}

Reply via email to