diff --git a/distribution/feature-packs/server-feature-pack/src/main/resources/modules/system/layers/keycloak/org/keycloak/keycloak-sssd-federation/main/module.xml b/distribution/feature-packs/server-feature-pack/src/main/resources/modules/system/layers/keycloak/org/keycloak/keycloak-sssd-federation/main/module.xml
index 58939eb49c..6d56d6e995 100644
--- a/distribution/feature-packs/server-feature-pack/src/main/resources/modules/system/layers/keycloak/org/keycloak/keycloak-sssd-federation/main/module.xml
+++ b/distribution/feature-packs/server-feature-pack/src/main/resources/modules/system/layers/keycloak/org/keycloak/keycloak-sssd-federation/main/module.xml
@@ -22,6 +22,7 @@
+
diff --git a/federation/sssd/pom.xml b/federation/sssd/pom.xml
index 29113f7c8e..a9029c4e93 100644
--- a/federation/sssd/pom.xml
+++ b/federation/sssd/pom.xml
@@ -49,6 +49,7 @@
net.java.dev.jna
jna
+ provided
org.keycloak
@@ -70,10 +71,6 @@
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
new file mode 100644
index 0000000000..4088d46ebb
--- /dev/null
+++ b/federation/sssd/src/main/java/cx/ath/matthew/LibraryLoader.java
@@ -0,0 +1,46 @@
+/*
+ * 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 b11609f8a2..eb143fe6a9 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(UnixSocketChannel channel, UnixSocket us) {
+ public USInputStream(int sock, UnixSocket us) {
+ this.sock = sock;
this.us = us;
- this.channel = channel;
}
public void close() throws IOException {
@@ -65,8 +65,7 @@ public class USInputStream extends InputStream {
public int read(byte[] b, int off, int len) throws IOException {
if (closed) throw new NotConnectedException();
- int count = receive(b, off, len);
-
+ int count = native_recv(sock, b, off, len, flags, timeout);
/* 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)
@@ -92,21 +91,4 @@ 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 1855b26a44..d8c85a7718 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,31 +26,22 @@
*/
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 UnixSocketChannel channel;
+ private native int native_send(int sock, byte[][] b) throws IOException;
private int sock;
boolean closed = false;
private byte[] onebuf = new byte[1];
private UnixSocket us;
- public USOutputStream(UnixSocketChannel channel, int sock, UnixSocket us) {
+ public USOutputStream(int sock, UnixSocket us) {
this.sock = sock;
this.us = us;
- this.channel = channel;
}
public void close() throws IOException {
@@ -61,9 +52,14 @@ 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();
- send(sock, b, off, len);
+ native_send(sock, b, off, len);
}
public void write(int b) throws IOException {
@@ -79,46 +75,4 @@ 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
new file mode 100644
index 0000000000..24fd20cd1f
--- /dev/null
+++ b/federation/sssd/src/main/java/cx/ath/matthew/unix/UnixIOException.java
@@ -0,0 +1,43 @@
+/*
+ * 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 7537f018ef..8851637436 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,11 +26,9 @@
*/
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;
@@ -39,8 +37,25 @@ import java.io.OutputStream;
* Represents a UnixSocket.
*/
public class UnixSocket {
+ static {
+ LibraryLoader.load();
+ }
- private UnixSocketChannel channel;
+ 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 UnixSocketAddress address = null;
private USOutputStream os = null;
@@ -58,8 +73,8 @@ public class UnixSocket {
this.sock = sock;
this.address = address;
this.connected = true;
- this.os = new USOutputStream(channel, sock, this);
- this.is = new USInputStream(channel, this);
+ this.os = new USOutputStream(sock, this);
+ this.is = new USInputStream(sock, this);
}
/**
@@ -83,7 +98,7 @@ public class UnixSocket {
* @param address The Unix Socket address to connect to
*/
public UnixSocket(String address) throws IOException {
- this(new UnixSocketAddress(new File(address)));
+ this(new UnixSocketAddress(address));
}
/**
@@ -93,11 +108,9 @@ public class UnixSocket {
*/
public void connect(UnixSocketAddress address) throws IOException {
if (connected) close();
- 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.sock = native_connect(address.path, address.abs);
+ this.os = new USOutputStream(this.sock, this);
+ this.is = new USInputStream(this.sock, this);
this.address = address;
this.connected = true;
this.closed = false;
@@ -110,7 +123,7 @@ public class UnixSocket {
* @param address The Unix Socket address to connect to
*/
public void connect(String address) throws IOException {
- connect(new UnixSocketAddress(new File(address)));
+ connect(new UnixSocketAddress(address));
}
public void finalize() {
@@ -125,7 +138,7 @@ public class UnixSocket {
*/
public synchronized void close() throws IOException {
if (Debug.debug) Debug.print(Debug.INFO, "Closing socket");
- channel.close();
+ native_close(sock);
sock = 0;
this.closed = true;
this.connected = false;
@@ -169,7 +182,91 @@ public class UnixSocket {
*/
public void sendCredentialByte(byte data) throws IOException {
if (!connected) throw new NotConnectedException();
- os.send(channel.getFD(), new byte[]{ data });
+ 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;
}
/**
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
new file mode 100644
index 0000000000..0baba479bb
--- /dev/null
+++ b/federation/sssd/src/main/java/cx/ath/matthew/unix/UnixSocketAddress.java
@@ -0,0 +1,86 @@
+/*
+ * 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 2a534263a3..45e8cb75f5 100644
--- a/federation/sssd/src/main/java/org/freedesktop/dbus/MessageWriter.java
+++ b/federation/sssd/src/main/java/org/freedesktop/dbus/MessageWriter.java
@@ -43,12 +43,20 @@ public class MessageWriter {
if (Debug.debug) Debug.print(Debug.WARN, "Message " + m + " wire-data was null!");
return;
}
- 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);
- }
+ 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);
+ }
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 0c997bd021..1745bcfec2 100644
--- a/federation/sssd/src/main/java/org/freedesktop/dbus/Transport.java
+++ b/federation/sssd/src/main/java/org/freedesktop/dbus/Transport.java
@@ -12,6 +12,7 @@ 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;
@@ -25,6 +26,7 @@ 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;
@@ -255,8 +257,10 @@ 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;
@@ -273,12 +277,15 @@ 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();
@@ -388,8 +395,89 @@ 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.
@@ -400,6 +488,7 @@ 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");
@@ -529,6 +618,110 @@ 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;
}
@@ -588,15 +781,25 @@ public class Transport {
types = SASL.AUTH_EXTERNAL;
mode = SASL.MODE_CLIENT;
us = new UnixSocket();
- if (null != address.getParameter("path"))
- us.connect(new jnr.unixsocket.UnixSocketAddress(new File(address.getParameter("path"))));
+ 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);
in = us.getInputStream();
out = us.getOutputStream();
} else if ("tcp".equals(address.getType())) {
types = SASL.AUTH_SHA;
- mode = SASL.MODE_CLIENT;
- s = new Socket();
- s.connect(new InetSocketAddress(address.getParameter("host"), Integer.parseInt(address.getParameter("port"))));
+ 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"))));
+ }
in = s.getInputStream();
out = s.getOutputStream();
} else {
diff --git a/pom.xml b/pom.xml
index 7918c6dade..2b2e697127 100755
--- a/pom.xml
+++ b/pom.xml
@@ -98,7 +98,6 @@
1.0.2.Final
4.0.4
4.1.0
- 0.14
1.3.1b
@@ -702,11 +701,6 @@
jna
${jna.version}
-
- com.github.jnr
- jnr-unixsocket
- ${jnr.version}
-
org.keycloak
keycloak-ldap-federation
diff --git a/testsuite/integration-arquillian/tests/other/sssd/src/test/java/org/keycloak/testsuite/sssd/SSSDTest.java b/testsuite/integration-arquillian/tests/other/sssd/src/test/java/org/keycloak/testsuite/sssd/SSSDTest.java
index b11d5e43b4..68488cce7d 100644
--- a/testsuite/integration-arquillian/tests/other/sssd/src/test/java/org/keycloak/testsuite/sssd/SSSDTest.java
+++ b/testsuite/integration-arquillian/tests/other/sssd/src/test/java/org/keycloak/testsuite/sssd/SSSDTest.java
@@ -2,6 +2,7 @@ package org.keycloak.testsuite.sssd;
import org.jboss.arquillian.graphene.page.Page;
import org.junit.Before;
+import org.junit.Ignore;
import org.junit.Rule;
import org.junit.Test;
import org.keycloak.representations.idm.GroupRepresentation;
@@ -72,6 +73,7 @@ public class SSSDTest extends AbstractKeycloakTest {
adminClient.realm(REALM_NAME).userFederation().create(userFederation);
}
+ @Ignore
@Test
public void testProviderFactories() {
List providerFactories = adminClient.realm(REALM_NAME).userFederation().getProviderFactories();