From 6c5d1b92142fcb03dfec3c366fac0c126034e958 Mon Sep 17 00:00:00 2001 From: Bruno Oliveira Date: Wed, 26 Oct 2016 08:31:16 -0200 Subject: [PATCH] [KEYCLOAK-3580] - Migrate DBus Java from Unix Socket C library to jnr-unixsocket --- federation/sssd/pom.xml | 4 + .../java/cx/ath/matthew/LibraryLoader.java | 46 ---- .../cx/ath/matthew/unix/USInputStream.java | 32 ++- .../cx/ath/matthew/unix/USOutputStream.java | 64 +++++- .../cx/ath/matthew/unix/UnixIOException.java | 43 ---- .../java/cx/ath/matthew/unix/UnixSocket.java | 127 ++--------- .../ath/matthew/unix/UnixSocketAddress.java | 86 ------- .../org/freedesktop/dbus/MessageWriter.java | 20 +- .../java/org/freedesktop/dbus/Transport.java | 213 +----------------- .../keycloak/federation/sssd/api/Sssd.java | 26 +-- pom.xml | 6 + 11 files changed, 126 insertions(+), 541 deletions(-) delete mode 100644 federation/sssd/src/main/java/cx/ath/matthew/LibraryLoader.java delete mode 100644 federation/sssd/src/main/java/cx/ath/matthew/unix/UnixIOException.java delete mode 100644 federation/sssd/src/main/java/cx/ath/matthew/unix/UnixSocketAddress.java diff --git a/federation/sssd/pom.xml b/federation/sssd/pom.xml index 5126ab23da..8430e7cb17 100644 --- a/federation/sssd/pom.xml +++ b/federation/sssd/pom.xml @@ -65,6 +65,10 @@ jboss-logging provided + + com.github.jnr + jnr-unixsocket + diff --git a/federation/sssd/src/main/java/cx/ath/matthew/LibraryLoader.java b/federation/sssd/src/main/java/cx/ath/matthew/LibraryLoader.java deleted file mode 100644 index 4088d46ebb..0000000000 --- a/federation/sssd/src/main/java/cx/ath/matthew/LibraryLoader.java +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Copyright 2016 Red Hat, Inc. and/or its affiliates - * and other contributors as indicated by the @author tags. - * - * Licensed 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 cx.ath.matthew; - -/** - * @author Bruno Oliveira. - */ -public class LibraryLoader { - - private static final String[] PATHS = {"/usr/lib/", "/usr/lib64/", "/usr/local/lib/", "/opt/local/lib/"}; - private static final String LIBRARY_NAME = "libunix_dbus_java"; - private static final String VERSION = "0.0.8"; - private static boolean loadSucceeded; - - public static LibraryLoader load() { - for (String path : PATHS) { - try { - System.load(String.format("%s/%s.so.%s", path, LIBRARY_NAME, VERSION)); - loadSucceeded = true; - break; - } catch (UnsatisfiedLinkError e) { - loadSucceeded = false; - } - } - - return new LibraryLoader(); - } - - public boolean succeed() { - return loadSucceeded; - } -} diff --git a/federation/sssd/src/main/java/cx/ath/matthew/unix/USInputStream.java b/federation/sssd/src/main/java/cx/ath/matthew/unix/USInputStream.java index eb143fe6a9..b11609f8a2 100644 --- a/federation/sssd/src/main/java/cx/ath/matthew/unix/USInputStream.java +++ b/federation/sssd/src/main/java/cx/ath/matthew/unix/USInputStream.java @@ -26,25 +26,25 @@ */ package cx.ath.matthew.unix; +import jnr.unixsocket.UnixSocketChannel; + import java.io.IOException; import java.io.InputStream; +import java.nio.channels.Channels; public class USInputStream extends InputStream { public static final int MSG_DONTWAIT = 0x40; + private UnixSocketChannel channel; - private native int native_recv(int sock, byte[] b, int off, int len, int flags, int timeout) throws IOException; - - private int sock; boolean closed = false; private byte[] onebuf = new byte[1]; private UnixSocket us; - private boolean blocking = true; private int flags = 0; private int timeout = 0; - public USInputStream(int sock, UnixSocket us) { - this.sock = sock; + public USInputStream(UnixSocketChannel channel, UnixSocket us) { this.us = us; + this.channel = channel; } public void close() throws IOException { @@ -65,7 +65,8 @@ public class USInputStream extends InputStream { public int read(byte[] b, int off, int len) throws IOException { if (closed) throw new NotConnectedException(); - int count = native_recv(sock, b, off, len, flags, timeout); + int count = receive(b, off, len); + /* Yes, I really want to do this. Recv returns 0 for 'connection shut down'. * read() returns -1 for 'end of stream. * Recv returns -1 for 'EAGAIN' (all other errors cause an exception to be raised) @@ -91,4 +92,21 @@ public class USInputStream extends InputStream { public void setSoTimeout(int timeout) { this.timeout = timeout; } + + /* + * Taken from JRuby with small modifications + * @see RubyUNIXSocket.java + */ + private int receive(byte[] dataBytes, int off, int len) { + int recvStatus = -1; + try { + InputStream inputStream = Channels.newInputStream(channel); + recvStatus = inputStream.read(dataBytes, off, len); + + } catch (IOException e) { + e.printStackTrace(); + } + + return recvStatus; + } } diff --git a/federation/sssd/src/main/java/cx/ath/matthew/unix/USOutputStream.java b/federation/sssd/src/main/java/cx/ath/matthew/unix/USOutputStream.java index d8c85a7718..1855b26a44 100644 --- a/federation/sssd/src/main/java/cx/ath/matthew/unix/USOutputStream.java +++ b/federation/sssd/src/main/java/cx/ath/matthew/unix/USOutputStream.java @@ -26,22 +26,31 @@ */ package cx.ath.matthew.unix; +import jnr.constants.platform.linux.SocketLevel; +import jnr.posix.CmsgHdr; +import jnr.posix.MsgHdr; +import jnr.posix.POSIX; +import jnr.posix.POSIXFactory; +import jnr.unixsocket.UnixSocketChannel; + import java.io.IOException; import java.io.OutputStream; +import java.nio.ByteBuffer; +import java.nio.ByteOrder; public class USOutputStream extends OutputStream { - private native int native_send(int sock, byte[] b, int off, int len) throws IOException; - private native int native_send(int sock, byte[][] b) throws IOException; + private UnixSocketChannel channel; private int sock; boolean closed = false; private byte[] onebuf = new byte[1]; private UnixSocket us; - public USOutputStream(int sock, UnixSocket us) { + public USOutputStream(UnixSocketChannel channel, int sock, UnixSocket us) { this.sock = sock; this.us = us; + this.channel = channel; } public void close() throws IOException { @@ -52,14 +61,9 @@ public class USOutputStream extends OutputStream { public void flush() { } // no-op, we do not buffer - public void write(byte[][] b) throws IOException { - if (closed) throw new NotConnectedException(); - native_send(sock, b); - } - public void write(byte[] b, int off, int len) throws IOException { if (closed) throw new NotConnectedException(); - native_send(sock, b, off, len); + send(sock, b, off, len); } public void write(int b) throws IOException { @@ -75,4 +79,46 @@ public class USOutputStream extends OutputStream { public UnixSocket getSocket() { return us; } + + /* + * Taken from JRuby with small modifications + * @see RubyUNIXSocket.java + */ + private void send(int sock, ByteBuffer[] outIov) { + + final POSIX posix = POSIXFactory.getNativePOSIX(); + MsgHdr outMessage = posix.allocateMsgHdr(); + + outMessage.setIov(outIov); + + CmsgHdr outControl = outMessage.allocateControl(4); + outControl.setLevel(SocketLevel.SOL_SOCKET.intValue()); + outControl.setType(0x01); + + ByteBuffer fdBuf = ByteBuffer.allocateDirect(4); + fdBuf.order(ByteOrder.nativeOrder()); + fdBuf.putInt(0, channel.getFD()); + outControl.setData(fdBuf); + + posix.sendmsg(sock, outMessage, 0); + + } + + private void send(int sock, byte[] dataBytes, int off, int len) { + ByteBuffer[] outIov = new ByteBuffer[1]; + outIov[0] = ByteBuffer.allocateDirect(dataBytes.length); + outIov[0].put(dataBytes, off, len); + outIov[0].flip(); + + send(sock, outIov); + } + + protected void send(int sock, byte[] dataBytes) { + ByteBuffer[] outIov = new ByteBuffer[1]; + outIov[0] = ByteBuffer.allocateDirect(dataBytes.length); + outIov[0].put(dataBytes); + outIov[0].flip(); + + send(sock, outIov); + } } diff --git a/federation/sssd/src/main/java/cx/ath/matthew/unix/UnixIOException.java b/federation/sssd/src/main/java/cx/ath/matthew/unix/UnixIOException.java deleted file mode 100644 index 24fd20cd1f..0000000000 --- a/federation/sssd/src/main/java/cx/ath/matthew/unix/UnixIOException.java +++ /dev/null @@ -1,43 +0,0 @@ -/* - * Java Unix Sockets Library - * - * Copyright (c) Matthew Johnson 2004 - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - * - * To Contact the author, please email src@matthew.ath.cx - * - */ -package cx.ath.matthew.unix; - -import java.io.IOException; - -/** - * An IO Exception which occurred during UNIX Socket IO - */ -public class UnixIOException extends IOException { - private int no; - private String message; - - public UnixIOException(int no, String message) { - super(message); - this.message = message; - this.no = no; - } -} diff --git a/federation/sssd/src/main/java/cx/ath/matthew/unix/UnixSocket.java b/federation/sssd/src/main/java/cx/ath/matthew/unix/UnixSocket.java index 8851637436..7537f018ef 100644 --- a/federation/sssd/src/main/java/cx/ath/matthew/unix/UnixSocket.java +++ b/federation/sssd/src/main/java/cx/ath/matthew/unix/UnixSocket.java @@ -26,9 +26,11 @@ */ package cx.ath.matthew.unix; -import cx.ath.matthew.LibraryLoader; import cx.ath.matthew.debug.Debug; +import jnr.unixsocket.UnixSocketAddress; +import jnr.unixsocket.UnixSocketChannel; +import java.io.File; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; @@ -37,25 +39,8 @@ import java.io.OutputStream; * Represents a UnixSocket. */ public class UnixSocket { - static { - LibraryLoader.load(); - } - private native void native_set_pass_cred(int sock, boolean passcred) throws IOException; - - private native int native_connect(String address, boolean abs) throws IOException; - - private native void native_close(int sock) throws IOException; - - private native int native_getPID(int sock); - - private native int native_getUID(int sock); - - private native int native_getGID(int sock); - - private native void native_send_creds(int sock, byte data) throws IOException; - - private native byte native_recv_creds(int sock, int[] creds) throws IOException; + private UnixSocketChannel channel; private UnixSocketAddress address = null; private USOutputStream os = null; @@ -73,8 +58,8 @@ public class UnixSocket { this.sock = sock; this.address = address; this.connected = true; - this.os = new USOutputStream(sock, this); - this.is = new USInputStream(sock, this); + this.os = new USOutputStream(channel, sock, this); + this.is = new USInputStream(channel, this); } /** @@ -98,7 +83,7 @@ public class UnixSocket { * @param address The Unix Socket address to connect to */ public UnixSocket(String address) throws IOException { - this(new UnixSocketAddress(address)); + this(new UnixSocketAddress(new File(address))); } /** @@ -108,9 +93,11 @@ public class UnixSocket { */ public void connect(UnixSocketAddress address) throws IOException { if (connected) close(); - this.sock = native_connect(address.path, address.abs); - this.os = new USOutputStream(this.sock, this); - this.is = new USInputStream(this.sock, this); + this.channel = UnixSocketChannel.open(address); + this.channel = UnixSocketChannel.open(address); + this.sock = channel.getFD(); + this.os = new USOutputStream(channel, sock, this); + this.is = new USInputStream(channel, this); this.address = address; this.connected = true; this.closed = false; @@ -123,7 +110,7 @@ public class UnixSocket { * @param address The Unix Socket address to connect to */ public void connect(String address) throws IOException { - connect(new UnixSocketAddress(address)); + connect(new UnixSocketAddress(new File(address))); } public void finalize() { @@ -138,7 +125,7 @@ public class UnixSocket { */ public synchronized void close() throws IOException { if (Debug.debug) Debug.print(Debug.INFO, "Closing socket"); - native_close(sock); + channel.close(); sock = 0; this.closed = true; this.connected = false; @@ -182,91 +169,7 @@ public class UnixSocket { */ public void sendCredentialByte(byte data) throws IOException { if (!connected) throw new NotConnectedException(); - native_send_creds(sock, data); - } - - /** - * Receive a single byte of data, with credentials. - * (Works on BSDs) - * - * @param data The byte of data to send. - * @see getPeerUID - * @see getPeerPID - * @see getPeerGID - */ - public byte recvCredentialByte() throws IOException { - if (!connected) throw new NotConnectedException(); - int[] creds = new int[]{-1, -1, -1}; - byte data = native_recv_creds(sock, creds); - pid = creds[0]; - uid = creds[1]; - gid = creds[2]; - return data; - } - - /** - * Get the credential passing status. - * (only effective on linux) - * - * @return The current status of credential passing. - * @see setPassCred - */ - public boolean getPassCred() { - return passcred; - } - - /** - * Return the uid of the remote process. - * Some data must have been received on the socket to do this. - * Either setPassCred must be called on Linux first, or recvCredentialByte - * on BSD. - * - * @return the UID or -1 if it is not available - */ - public int getPeerUID() { - if (-1 == uid) - uid = native_getUID(sock); - return uid; - } - - /** - * Return the gid of the remote process. - * Some data must have been received on the socket to do this. - * Either setPassCred must be called on Linux first, or recvCredentialByte - * on BSD. - * - * @return the GID or -1 if it is not available - */ - public int getPeerGID() { - if (-1 == gid) - gid = native_getGID(sock); - return gid; - } - - /** - * Return the pid of the remote process. - * Some data must have been received on the socket to do this. - * Either setPassCred must be called on Linux first, or recvCredentialByte - * on BSD. - * - * @return the PID or -1 if it is not available - */ - public int getPeerPID() { - if (-1 == pid) - pid = native_getPID(sock); - return pid; - } - - /** - * Set the credential passing status. - * (Only does anything on linux, for other OS, you need - * to use send/recv credentials) - * - * @param enable Set to true for credentials to be passed. - */ - public void setPassCred(boolean enable) throws IOException { - native_set_pass_cred(sock, enable); - passcred = enable; + os.send(channel.getFD(), new byte[]{ data }); } /** diff --git a/federation/sssd/src/main/java/cx/ath/matthew/unix/UnixSocketAddress.java b/federation/sssd/src/main/java/cx/ath/matthew/unix/UnixSocketAddress.java deleted file mode 100644 index 0baba479bb..0000000000 --- a/federation/sssd/src/main/java/cx/ath/matthew/unix/UnixSocketAddress.java +++ /dev/null @@ -1,86 +0,0 @@ -/* - * Java Unix Sockets Library - * - * Copyright (c) Matthew Johnson 2004 - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - * - * To Contact the author, please email src@matthew.ath.cx - * - */ -package cx.ath.matthew.unix; - -/** - * Represents an address for a Unix Socket - */ -public class UnixSocketAddress { - String path; - boolean abs; - - /** - * Create the address. - * - * @param path The path to the Unix Socket. - * @param abs True if this should be an abstract socket. - */ - public UnixSocketAddress(String path, boolean abs) { - this.path = path; - this.abs = abs; - } - - /** - * Create the address. - * - * @param path The path to the Unix Socket. - */ - public UnixSocketAddress(String path) { - this.path = path; - this.abs = false; - } - - /** - * Return the path. - */ - public String getPath() { - return path; - } - - /** - * Returns true if this an address for an abstract socket. - */ - public boolean isAbstract() { - return abs; - } - - /** - * Return the Address as a String. - */ - public String toString() { - return "unix" + (abs ? ":abstract" : "") + ":path=" + path; - } - - public boolean equals(Object o) { - if (!(o instanceof UnixSocketAddress)) return false; - return ((UnixSocketAddress) o).path.equals(this.path); - } - - public int hashCode() { - return path.hashCode(); - } -} diff --git a/federation/sssd/src/main/java/org/freedesktop/dbus/MessageWriter.java b/federation/sssd/src/main/java/org/freedesktop/dbus/MessageWriter.java index 45e8cb75f5..2a534263a3 100644 --- a/federation/sssd/src/main/java/org/freedesktop/dbus/MessageWriter.java +++ b/federation/sssd/src/main/java/org/freedesktop/dbus/MessageWriter.java @@ -43,20 +43,12 @@ public class MessageWriter { if (Debug.debug) Debug.print(Debug.WARN, "Message " + m + " wire-data was null!"); return; } - if (isunix) { - if (Debug.debug) { - Debug.print(Debug.DEBUG, "Writing all " + m.getWireData().length + " buffers simultaneously to Unix Socket"); - for (byte[] buf : m.getWireData()) - Debug.print(Debug.VERBOSE, "(" + buf + "):" + (null == buf ? "" : Hexdump.format(buf))); - } - ((USOutputStream) out).write(m.getWireData()); - } else - for (byte[] buf : m.getWireData()) { - if (Debug.debug) - Debug.print(Debug.VERBOSE, "(" + buf + "):" + (null == buf ? "" : Hexdump.format(buf))); - if (null == buf) break; - out.write(buf); - } + for (byte[] buf : m.getWireData()) { + if (Debug.debug) + Debug.print(Debug.VERBOSE, "(" + buf + "):" + (null == buf ? "" : Hexdump.format(buf))); + if (null == buf) break; + out.write(buf); + } out.flush(); } diff --git a/federation/sssd/src/main/java/org/freedesktop/dbus/Transport.java b/federation/sssd/src/main/java/org/freedesktop/dbus/Transport.java index 1745bcfec2..0c997bd021 100644 --- a/federation/sssd/src/main/java/org/freedesktop/dbus/Transport.java +++ b/federation/sssd/src/main/java/org/freedesktop/dbus/Transport.java @@ -12,7 +12,6 @@ package org.freedesktop.dbus; import cx.ath.matthew.debug.Debug; import cx.ath.matthew.unix.UnixSocket; -import cx.ath.matthew.unix.UnixSocketAddress; import cx.ath.matthew.utils.Hexdump; import java.io.BufferedReader; @@ -26,7 +25,6 @@ import java.io.OutputStream; import java.io.PrintWriter; import java.lang.reflect.Method; import java.net.InetSocketAddress; -import java.net.ServerSocket; import java.net.Socket; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; @@ -257,10 +255,8 @@ public class Transport { return new String(res); } - public static final int MODE_SERVER = 1; public static final int MODE_CLIENT = 2; - public static final int AUTH_NONE = 0; public static final int AUTH_EXTERNAL = 1; public static final int AUTH_SHA = 2; public static final int AUTH_ANON = 4; @@ -277,15 +273,12 @@ public class Transport { public static final int WAIT_DATA = 1; public static final int WAIT_OK = 2; public static final int WAIT_REJECT = 3; - public static final int WAIT_AUTH = 4; - public static final int WAIT_BEGIN = 5; public static final int AUTHENTICATED = 6; public static final int FAILED = 7; public static final int OK = 1; public static final int CONTINUE = 2; public static final int ERROR = 3; - public static final int REJECT = 4; public Command receive(InputStream s) throws IOException { StringBuffer sb = new StringBuffer(); @@ -395,89 +388,8 @@ public class Transport { } } - public String challenge = ""; public String cookie = ""; - public int do_response(int auth, String Uid, String kernelUid, Command c) { - MessageDigest md = null; - try { - md = MessageDigest.getInstance("SHA"); - } catch (NoSuchAlgorithmException NSAe) { - if (Debug.debug && AbstractConnection.EXCEPTION_DEBUG) Debug.print(Debug.ERR, NSAe); - return ERROR; - } - switch (auth) { - case AUTH_NONE: - switch (c.getMechs()) { - case AUTH_ANON: - return OK; - case AUTH_EXTERNAL: - if (0 == col.compare(Uid, c.getData()) && - (null == kernelUid || 0 == col.compare(Uid, kernelUid))) - return OK; - else - return ERROR; - case AUTH_SHA: - String context = COOKIE_CONTEXT; - long id = System.currentTimeMillis(); - byte[] buf = new byte[8]; - Message.marshallintBig(id, buf, 0, 8); - challenge = stupidlyEncode(md.digest(buf)); - Random r = new Random(); - r.nextBytes(buf); - cookie = stupidlyEncode(md.digest(buf)); - try { - addCookie(context, "" + id, id / 1000, cookie); - } catch (IOException IOe) { - if (Debug.debug && AbstractConnection.EXCEPTION_DEBUG) Debug.print(Debug.ERR, IOe); - } - if (Debug.debug) - Debug.print(Debug.DEBUG, "Sending challenge: " + context + ' ' + id + ' ' + challenge); - c.setResponse(stupidlyEncode(context + ' ' + id + ' ' + challenge)); - return CONTINUE; - default: - return ERROR; - } - case AUTH_SHA: - String[] response = stupidlyDecode(c.getData()).split(" "); - if (response.length < 2) return ERROR; - String cchal = response[0]; - String hash = response[1]; - String prehash = challenge + ":" + cchal + ":" + cookie; - byte[] buf = md.digest(prehash.getBytes()); - String posthash = stupidlyEncode(buf); - if (Debug.debug) - Debug.print(Debug.DEBUG, "Authenticating Hash; data=" + prehash + " remote hash=" + hash + " local hash=" + posthash); - if (0 == col.compare(posthash, hash)) - return OK; - else - return ERROR; - default: - return ERROR; - } - } - - public String[] getTypes(int types) { - switch (types) { - case AUTH_EXTERNAL: - return new String[]{"EXTERNAL"}; - case AUTH_SHA: - return new String[]{"DBUS_COOKIE_SHA1"}; - case AUTH_ANON: - return new String[]{"ANONYMOUS"}; - case AUTH_SHA + AUTH_EXTERNAL: - return new String[]{"EXTERNAL", "DBUS_COOKIE_SHA1"}; - case AUTH_SHA + AUTH_ANON: - return new String[]{"ANONYMOUS", "DBUS_COOKIE_SHA1"}; - case AUTH_EXTERNAL + AUTH_ANON: - return new String[]{"ANONYMOUS", "EXTERNAL"}; - case AUTH_EXTERNAL + AUTH_ANON + AUTH_SHA: - return new String[]{"ANONYMOUS", "EXTERNAL", "DBUS_COOKIE_SHA1"}; - default: - return new String[]{}; - } - } - /** * performs SASL auth on the given streams. * Mode selects whether to run as a SASL server or client. @@ -488,7 +400,6 @@ public class Transport { public boolean auth(int mode, int types, String guid, OutputStream out, InputStream in, UnixSocket us) throws IOException { String username = System.getProperty("user.name"); String Uid = null; - String kernelUid = null; try { Class c = Class.forName("com.sun.security.auth.module.UnixSystem"); Method m = c.getMethod("getUid"); @@ -618,110 +529,6 @@ public class Transport { state = FAILED; } break; - case MODE_SERVER: - switch (state) { - case INITIAL_STATE: - byte[] buf = new byte[1]; - if (null == us) { - in.read(buf); - } else { - buf[0] = us.recvCredentialByte(); - int kuid = us.getPeerUID(); - if (kuid >= 0) - kernelUid = stupidlyEncode("" + kuid); - } - if (0 != buf[0]) state = FAILED; - else state = WAIT_AUTH; - break; - case WAIT_AUTH: - c = receive(in); - switch (c.getCommand()) { - case COMMAND_AUTH: - if (null == c.getData()) { - send(out, COMMAND_REJECTED, getTypes(types)); - } else { - switch (do_response(current, Uid, kernelUid, c)) { - case CONTINUE: - send(out, COMMAND_DATA, c.getResponse()); - current = c.getMechs(); - state = WAIT_DATA; - break; - case OK: - send(out, COMMAND_OK, guid); - state = WAIT_BEGIN; - current = 0; - break; - case REJECT: - send(out, COMMAND_REJECTED, getTypes(types)); - current = 0; - break; - } - } - break; - case COMMAND_ERROR: - send(out, COMMAND_REJECTED, getTypes(types)); - break; - case COMMAND_BEGIN: - state = FAILED; - break; - default: - send(out, COMMAND_ERROR, "Got invalid command"); - break; - } - break; - case WAIT_DATA: - c = receive(in); - switch (c.getCommand()) { - case COMMAND_DATA: - switch (do_response(current, Uid, kernelUid, c)) { - case CONTINUE: - send(out, COMMAND_DATA, c.getResponse()); - state = WAIT_DATA; - break; - case OK: - send(out, COMMAND_OK, guid); - state = WAIT_BEGIN; - current = 0; - break; - case REJECT: - send(out, COMMAND_REJECTED, getTypes(types)); - current = 0; - break; - } - break; - case COMMAND_ERROR: - case COMMAND_CANCEL: - send(out, COMMAND_REJECTED, getTypes(types)); - state = WAIT_AUTH; - break; - case COMMAND_BEGIN: - state = FAILED; - break; - default: - send(out, COMMAND_ERROR, "Got invalid command"); - break; - } - break; - case WAIT_BEGIN: - c = receive(in); - switch (c.getCommand()) { - case COMMAND_ERROR: - case COMMAND_CANCEL: - send(out, COMMAND_REJECTED, getTypes(types)); - state = WAIT_AUTH; - break; - case COMMAND_BEGIN: - state = AUTHENTICATED; - break; - default: - send(out, COMMAND_ERROR, "Got invalid command"); - break; - } - break; - default: - state = FAILED; - } - break; default: return false; } @@ -781,25 +588,15 @@ public class Transport { types = SASL.AUTH_EXTERNAL; mode = SASL.MODE_CLIENT; us = new UnixSocket(); - if (null != address.getParameter("abstract")) - us.connect(new UnixSocketAddress(address.getParameter("abstract"), true)); - else if (null != address.getParameter("path")) - us.connect(new UnixSocketAddress(address.getParameter("path"), false)); - us.setPassCred(true); + if (null != address.getParameter("path")) + us.connect(new jnr.unixsocket.UnixSocketAddress(new File(address.getParameter("path")))); in = us.getInputStream(); out = us.getOutputStream(); } else if ("tcp".equals(address.getType())) { types = SASL.AUTH_SHA; - if (null != address.getParameter("listen")) { - mode = SASL.MODE_SERVER; - ServerSocket ss = new ServerSocket(); - ss.bind(new InetSocketAddress(address.getParameter("host"), Integer.parseInt(address.getParameter("port")))); - s = ss.accept(); - } else { - mode = SASL.MODE_CLIENT; - s = new Socket(); - s.connect(new InetSocketAddress(address.getParameter("host"), Integer.parseInt(address.getParameter("port")))); - } + mode = SASL.MODE_CLIENT; + s = new Socket(); + s.connect(new InetSocketAddress(address.getParameter("host"), Integer.parseInt(address.getParameter("port")))); in = s.getInputStream(); out = s.getOutputStream(); } else { diff --git a/federation/sssd/src/main/java/org/keycloak/federation/sssd/api/Sssd.java b/federation/sssd/src/main/java/org/keycloak/federation/sssd/api/Sssd.java index 065eb98842..5d62ce4ba7 100644 --- a/federation/sssd/src/main/java/org/keycloak/federation/sssd/api/Sssd.java +++ b/federation/sssd/src/main/java/org/keycloak/federation/sssd/api/Sssd.java @@ -17,8 +17,6 @@ package org.keycloak.federation.sssd.api; -import cx.ath.matthew.LibraryLoader; -import org.freedesktop.DBus; import org.freedesktop.dbus.DBusConnection; import org.freedesktop.dbus.Variant; import org.freedesktop.dbus.exceptions.DBusException; @@ -26,6 +24,9 @@ import org.freedesktop.sssd.infopipe.InfoPipe; import org.freedesktop.sssd.infopipe.User; import org.jboss.logging.Logger; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; import java.util.Arrays; import java.util.List; import java.util.Map; @@ -110,24 +111,17 @@ public class Sssd { return userGroups; } - public static boolean isAvailable(){ + public static boolean isAvailable() { boolean sssdAvailable = false; try { - if (LibraryLoader.load().succeed()) { - DBusConnection connection = DBusConnection.getConnection(DBusConnection.SYSTEM); - DBus dbus = connection.getRemoteObject(DBus.BUSNAME, DBus.OBJECTPATH, DBus.class); - sssdAvailable = Arrays.asList(dbus.ListNames()).contains(InfoPipe.BUSNAME); - if (!sssdAvailable) { - logger.debugv("SSSD is not available in your system. Federation provider will be disabled."); - } else { - sssdAvailable = true; - } - connection.disconnect(); + Path path = Paths.get("/etc/sssd"); + if (!Files.exists(path)) { + logger.debugv("SSSD is not available in your system. Federation provider will be disabled."); } else { - logger.debugv("libunix_dbus_java not found. Federation provider will be disabled."); + sssdAvailable = true; } - } catch (DBusException e) { - logger.error("Failed to check the status of SSSD", e); + } catch (Exception e) { + logger.error("SSSD check failed", e); } return sssdAvailable; } diff --git a/pom.xml b/pom.xml index a5e376dd1e..8a61e5b0b4 100755 --- a/pom.xml +++ b/pom.xml @@ -98,6 +98,7 @@ 1.0.2.Final 4.0.4 4.1.0 + 0.14 1.3.1b @@ -700,6 +701,11 @@ jna ${jna.version} + + com.github.jnr + jnr-unixsocket + ${jnr.version} + org.keycloak keycloak-ldap-federation