From 50589d765782e3cc9a40b3d349fb3205fab46ded Mon Sep 17 00:00:00 2001 From: Bruno Oliveira Date: Wed, 4 Oct 2023 12:13:05 -0300 Subject: [PATCH] Weak hashing algorithm usage in SSSD User federation Closes #23713 --- .../org/freedesktop/dbus/bin/DBusDaemon.java | 875 ------------------ .../dbus/bin/EmbeddedDBusDaemon.java | 224 ----- .../connections/impl/DirectConnection.java | 300 ------ .../impl/DirectConnectionBuilder.java | 64 -- 4 files changed, 1463 deletions(-) delete mode 100644 federation/sssd/src/main/java/org/freedesktop/dbus/bin/DBusDaemon.java delete mode 100644 federation/sssd/src/main/java/org/freedesktop/dbus/bin/EmbeddedDBusDaemon.java delete mode 100644 federation/sssd/src/main/java/org/freedesktop/dbus/connections/impl/DirectConnection.java delete mode 100644 federation/sssd/src/main/java/org/freedesktop/dbus/connections/impl/DirectConnectionBuilder.java diff --git a/federation/sssd/src/main/java/org/freedesktop/dbus/bin/DBusDaemon.java b/federation/sssd/src/main/java/org/freedesktop/dbus/bin/DBusDaemon.java deleted file mode 100644 index 286fa8ffb0..0000000000 --- a/federation/sssd/src/main/java/org/freedesktop/dbus/bin/DBusDaemon.java +++ /dev/null @@ -1,875 +0,0 @@ -package org.freedesktop.dbus.bin; - -import org.freedesktop.dbus.Marshalling; -import org.freedesktop.dbus.connections.BusAddress; -import org.freedesktop.dbus.connections.transports.AbstractTransport; -import org.freedesktop.dbus.connections.transports.TransportBuilder; -import org.freedesktop.dbus.connections.transports.TransportBuilder.SaslAuthMode; -import org.freedesktop.dbus.connections.transports.TransportConnection; -import org.freedesktop.dbus.errors.AccessDenied; -import org.freedesktop.dbus.errors.Error; -import org.freedesktop.dbus.errors.MatchRuleInvalid; -import org.freedesktop.dbus.exceptions.DBusException; -import org.freedesktop.dbus.exceptions.DBusExecutionException; -import org.freedesktop.dbus.interfaces.DBus; -import org.freedesktop.dbus.interfaces.DBus.NameOwnerChanged; -import org.freedesktop.dbus.interfaces.FatalException; -import org.freedesktop.dbus.interfaces.Introspectable; -import org.freedesktop.dbus.interfaces.Peer; -import org.freedesktop.dbus.messages.DBusSignal; -import org.freedesktop.dbus.messages.Message; -import org.freedesktop.dbus.messages.MethodCall; -import org.freedesktop.dbus.messages.MethodReturn; -import org.freedesktop.dbus.types.UInt32; -import org.freedesktop.dbus.types.Variant; -import org.freedesktop.dbus.utils.Hexdump; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.io.Closeable; -import java.io.FileOutputStream; -import java.io.IOException; -import java.io.PrintWriter; -import java.lang.ref.WeakReference; -import java.lang.reflect.InvocationTargetException; -import java.net.InetAddress; -import java.net.UnknownHostException; -import java.security.MessageDigest; -import java.security.NoSuchAlgorithmException; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collections; -import java.util.HashMap; -import java.util.HashSet; -import java.util.List; -import java.util.Map; -import java.util.Objects; -import java.util.Set; -import java.util.concurrent.BlockingDeque; -import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.LinkedBlockingDeque; -import java.util.concurrent.atomic.AtomicBoolean; -import java.util.concurrent.atomic.AtomicInteger; - -/** - * A replacement DBusDaemon - */ -public class DBusDaemon extends Thread implements Closeable { - public static final int QUEUE_POLL_WAIT = 500; - - private static final Logger LOGGER = - LoggerFactory.getLogger(DBusDaemon.class); - - private final Map conns = - new ConcurrentHashMap<>(); - private final Map names = - Collections.synchronizedMap(new HashMap<>()); // required because of "null" key - - private final BlockingDeque>> outqueue = - new LinkedBlockingDeque<>(); - private final BlockingDeque>> inqueue = - new LinkedBlockingDeque<>(); - - private final List sigrecips = new ArrayList<>(); - private final DBusServer dbusServer = new DBusServer(); - - private final DBusDaemonSenderThread sender = - new DBusDaemonSenderThread(); - private final AtomicBoolean run = - new AtomicBoolean(false); - private final AtomicInteger nextUnique = new AtomicInteger(0); - - private final AbstractTransport transport; - - public DBusDaemon(AbstractTransport _transport) { - setName(getClass().getSimpleName() + "-Thread"); - transport = _transport; - names.put("org.freedesktop.DBus", null); - } - - private void send(ConnectionStruct _connStruct, Message _msg) { - send(_connStruct, _msg, false); - } - - private void send(ConnectionStruct _connStruct, Message _msg, boolean _head) { - - // send to all connections - if (null == _connStruct) { - LOGGER.trace("Queuing message {} for all connections", _msg); - synchronized (conns) { - for (ConnectionStruct d : conns.keySet()) { - if (_head) { - outqueue.addFirst(new Pair<>(_msg, new WeakReference<>(d))); - } else { - outqueue.addLast(new Pair<>(_msg, new WeakReference<>(d))); - } - } - } - } else { - LOGGER.trace("Queuing message {} for {}", _msg, _connStruct.unique); - if (_head) { - outqueue.addFirst(new Pair<>(_msg, new WeakReference<>(_connStruct))); - } else { - outqueue.addLast(new Pair<>(_msg, new WeakReference<>(_connStruct))); - } - } - } - - @Override - public void run() { - run.set(true); - sender.start(); - - while (isRunning()) { - try { - Pair> pollFirst = inqueue.take(); - ConnectionStruct connectionStruct = pollFirst.second.get(); - if (connectionStruct != null) { - Message m = pollFirst.first; - logMessage(" Got message {} from {}", m, connectionStruct.unique); - - // check if they have hello'd - if (null == connectionStruct.unique && (!(m instanceof MethodCall) || !"org.freedesktop.DBus".equals(m.getDestination()) || !"Hello".equals(m.getName()))) { - send(connectionStruct, new Error("org.freedesktop.DBus", null, "org.freedesktop.DBus.Error.AccessDenied", m.getSerial(), "s", "You must send a Hello message")); - } else { - try { - if (null != connectionStruct.unique) { - m.setSource(connectionStruct.unique); - LOGGER.trace("Updated source to {}", connectionStruct.unique); - } - } catch (DBusException _ex) { - LOGGER.debug("Error setting source", _ex); - send(connectionStruct, new Error("org.freedesktop.DBus", null, "org.freedesktop.DBus.Error.GeneralError", m.getSerial(), "s", "Sending message failed")); - } - - if ("org.freedesktop.DBus".equals(m.getDestination())) { - dbusServer.handleMessage(connectionStruct, pollFirst.first); - } else { - if (m instanceof DBusSignal) { - List l; - synchronized (sigrecips) { - l = new ArrayList<>(sigrecips); - } - List list = l; - for (ConnectionStruct d : list) { - send(d, m); - } - } else { - ConnectionStruct dest = names.get(m.getDestination()); - - if (null == dest) { - send(connectionStruct, new Error("org.freedesktop.DBus", null, - "org.freedesktop.DBus.Error.ServiceUnknown", m.getSerial(), "s", - String.format("The name `%s' does not exist", m.getDestination()))); - } else { - send(dest, m); - } - } - } - } - } - - } catch (DBusException _ex) { - LOGGER.debug("Error processing connection", _ex); - } catch (InterruptedException _ex) { - LOGGER.debug("Interrupted"); - close(); - interrupt(); - } - } - - } - - private static void logMessage(String _logStr, Message _m, String _connUniqueId) { - Object logMsg = _m; - if (_m != null && Introspectable.class.getName().equals(_m.getInterface()) && !LOGGER.isTraceEnabled()) { - logMsg = ""; - } - - if (LOGGER.isTraceEnabled()) { - LOGGER.trace(_logStr, logMsg, _connUniqueId); - } else { - LOGGER.debug(_logStr, _m, _connUniqueId); - } - } - - public synchronized boolean isRunning() { - return run.get(); - } - - @Override - public void close() { - run.set(false); - if (!conns.isEmpty()) { - // disconnect all remaining connection - Set connections = new HashSet<>(conns.keySet()); - for (ConnectionStruct c : connections) { - removeConnection(c); - } - } - sender.terminate(); - if (transport != null && transport.isConnected()) { - LOGGER.debug("Terminating transport {}", transport); - try { - // shutdown listener - transport.close(); - } catch (IOException _ex) { - LOGGER.debug("Error closing transport", _ex); - } - } - } - - private void removeConnection(ConnectionStruct _c) { - - boolean exists = false; - synchronized (conns) { - if (conns.containsKey(_c)) { - DBusDaemonReaderThread r = conns.get(_c); - exists = true; - r.terminate(); - conns.remove(_c); - } - } - if (exists) { - try { - if (null != _c.connection) { - _c.connection.close(); - } - } catch (IOException _exIo) { - LOGGER.trace("Error while closing socketchannel", _exIo); - } - - synchronized (names) { - List toRemove = new ArrayList<>(); - for (String name : names.keySet()) { - if (names.get(name) == _c) { - toRemove.add(name); - try { - send(null, new NameOwnerChanged("/org/freedesktop/DBus", name, _c.unique, "")); - } catch (DBusException _ex) { - LOGGER.debug("", _ex); - } - } - } - for (String name : toRemove) { - names.remove(name); - } - } - } - - } - - void addSock(TransportConnection _s) throws IOException { - LOGGER.debug("New Client"); - - ConnectionStruct c = new ConnectionStruct(_s); - DBusDaemonReaderThread r = new DBusDaemonReaderThread(c); - conns.put(c, r); - r.start(); - } - - public static void syntax() { - System.out.println("Syntax: DBusDaemon [--version] [-v] [--help] [-h] [--listen address] " - + "[-l address] [--print-address] [-r] [--pidfile file] [-p file] [--addressfile file] " - + "[--auth-mode AUTH_ANONYMOUS|AUTH_COOKIE|AUTH_EXTERNAL] [-m AUTH_ANONYMOUS|AUTH_COOKIE|AUTH_EXTERNAL]" - + "[-a file] [--unix] [-u] [--tcp] [-t] "); - System.exit(1); - } - - public static void version() { - System.out.println("D-Bus Java Version: " + System.getProperty("Version")); - System.exit(1); - } - - public static void saveFile(String _data, String _file) throws IOException { - try (PrintWriter w = new PrintWriter(new FileOutputStream(_file))) { - w.println(_data); - } - } - - public static void main(String[] _args) throws Exception { - - String addr = null; - String pidfile = null; - String addrfile = null; - String authModeStr = null; - boolean printaddress = false; - boolean unix = true; - boolean tcp = false; - // parse options - try { - for (int i = 0; i < _args.length; i++) { - if ("--help".equals(_args[i]) || "-h".equals(_args[i])) { - syntax(); - } else if ("--version".equals(_args[i]) || "-v".equals(_args[i])) { - version(); - } else if ("--listen".equals(_args[i]) || "-l".equals(_args[i])) { - addr = _args[++i]; - } else if ("--pidfile".equals(_args[i]) || "-p".equals(_args[i])) { - pidfile = _args[++i]; - } else if ("--addressfile".equals(_args[i]) || "-a".equals(_args[i])) { - addrfile = _args[++i]; - } else if ("--print-address".equals(_args[i]) || "-r".equals(_args[i])) { - printaddress = true; - } else if ("--unix".equals(_args[i]) || "-u".equals(_args[i])) { - unix = true; - tcp = false; - } else if ("--tcp".equals(_args[i]) || "-t".equals(_args[i])) { - tcp = true; - unix = false; - } else if ("--auth-mode".equals(_args[i]) || "-m".equals(_args[i])) { - authModeStr = _args[++i]; - } else { - syntax(); - } - } - } catch (ArrayIndexOutOfBoundsException _ex) { - syntax(); - } - - // generate a random address if none specified - if (null == addr && unix) { - addr = TransportBuilder.createDynamicSession("UNIX", true); - } else if (null == addr && tcp) { - addr = TransportBuilder.createDynamicSession("TCP", true); - } - - BusAddress address = BusAddress.of(addr); - - // print address to stdout - if (printaddress) { - System.out.println(addr); - } - - SaslAuthMode saslAuthMode = null; - if (authModeStr != null) { - String selectedMode = authModeStr; - saslAuthMode = Arrays.stream(SaslAuthMode.values()) - .filter(e -> e.name().toLowerCase().matches(selectedMode.toLowerCase())) - .findFirst() - .orElseThrow(() -> new IllegalArgumentException("Auth mode '" + selectedMode + "' unsupported")); - } - - // print address to file - if (null != addrfile) { - saveFile(addr, addrfile); - } - - // print PID to file - if (null != pidfile) { - saveFile(System.getProperty("Pid"), pidfile); - } - - // start the daemon - LOGGER.info("Binding to {}", addr); - try (EmbeddedDBusDaemon daemon = new EmbeddedDBusDaemon(address)) { - daemon.setSaslAuthMode(saslAuthMode); - daemon.startInForeground(); - } - - } - - /** - * Create a 'NameAcquired' signal manually. - * This is required because the implementation in DBusNameAquired is for receiving of this signal only. - * - * @param _name name to announce - * - * @return signal - * @throws DBusException if signal creation fails - */ - private DBusSignal generateNameAcquiredSignal(String _name) throws DBusException { - return new DBusSignal("org.freedesktop.DBus", "/org/freedesktop/DBus", "org.freedesktop.DBus", "NameAcquired", "s", _name); - } - - /** - * Create a 'NameOwnerChanged' signal manually. - * This is required because the implementation in DBusNameAquired is for receiving of this signal only. - * - * @param _name name to announce - * @param _oldOwner previous owner - * @param _newOwner new owner - * - * @return signal - * @throws DBusException if signal creation fails - */ - private DBusSignal generatedNameOwnerChangedSignal(String _name, String _oldOwner, String _newOwner) throws DBusException { - return new DBusSignal("org.freedesktop.DBus", "/org/freedesktop/DBus", "org.freedesktop.DBus", "NameOwnerChanged", "sss", _name, _oldOwner, _newOwner); - } - - public static class ConnectionStruct { - private final TransportConnection connection; - private String unique; - - ConnectionStruct(TransportConnection _c) throws IOException { - connection = _c; - } - - @Override - public String toString() { - return null == unique ? ":?-?" : unique; - } - } - - public class DBusServer implements DBus, Introspectable, Peer { - - private final String machineId; - private ConnectionStruct connStruct; - - public DBusServer() { - String ascii; - try { - ascii = Hexdump.toAscii(MessageDigest.getInstance("MD5").digest(InetAddress.getLocalHost().getHostName().getBytes())); - } catch (NoSuchAlgorithmException | UnknownHostException _ex) { - ascii = this.hashCode() + ""; - } - - machineId = ascii; - } - - @Override - public boolean isRemote() { - return false; - } - - @Override - public String Hello() { - synchronized (connStruct) { - if (null != connStruct.unique) { - throw new AccessDenied("Connection has already sent a Hello message"); - } - connStruct.unique = ":1." + nextUnique.incrementAndGet(); - } - names.put(connStruct.unique, connStruct); - - LOGGER.info("Client {} registered", connStruct.unique); - - try { - send(connStruct, generateNameAcquiredSignal(connStruct.unique)); - send(null, generatedNameOwnerChangedSignal(connStruct.unique, "", connStruct.unique)); - } catch (DBusException _ex) { - LOGGER.debug("", _ex); - } - - return connStruct.unique; - } - - @Override - public String[] ListNames() { - String[] ns; - Set nss = names.keySet(); - ns = nss.toArray(new String[0]); - return ns; - } - - @Override - public boolean NameHasOwner(String _name) { - return names.containsKey(_name); - } - - @Override - public String GetNameOwner(String _name) { - - ConnectionStruct owner = names.get(_name); - String o; - if (null == owner) { - o = ""; - } else { - o = owner.unique; - } - - return o; - } - - @Override - public UInt32 GetConnectionUnixUser(String _connectionName) { - return new UInt32(0); - } - - @Override - public UInt32 StartServiceByName(String _name, UInt32 _flags) { - return new UInt32(0); - } - - @Override - @SuppressWarnings("checkstyle:innerassignment") - public UInt32 RequestName(String _name, UInt32 _flags) { - boolean exists = false; - synchronized (names) { - if (!(exists = names.containsKey(_name))) { - names.put(_name, connStruct); - } - } - - int rv; - if (exists) { - rv = DBus.DBUS_REQUEST_NAME_REPLY_EXISTS; - } else { - - LOGGER.info("Client {} acquired name {}", connStruct.unique, _name); - - rv = DBus.DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER; - try { - send(connStruct, generateNameAcquiredSignal(_name)); - send(null, generatedNameOwnerChangedSignal(_name, "", connStruct.unique)); - } catch (DBusException _ex) { - LOGGER.debug("", _ex); - } - } - return new UInt32(rv); - } - - @Override - public UInt32 ReleaseName(String _name) { - - boolean exists = false; - synchronized (names) { - if (names.containsKey(_name) && names.get(_name).equals(connStruct)) { - exists = names.remove(_name) != null; - } - } - - int rv; - if (!exists) { - rv = DBus.DBUS_RELEASE_NAME_REPLY_NON_EXISTANT; - } else { - LOGGER.info("Client {} acquired name {}", connStruct.unique, _name); - rv = DBus.DBUS_RELEASE_NAME_REPLY_RELEASED; - try { - send(connStruct, new NameLost("/org/freedesktop/DBus", _name)); - send(null, new NameOwnerChanged("/org/freedesktop/DBus", _name, connStruct.unique, "")); - } catch (DBusException _ex) { - LOGGER.debug("", _ex); - } - } - - return new UInt32(rv); - } - - @Override - public void AddMatch(String _matchrule) throws MatchRuleInvalid { - - LOGGER.trace("Adding match rule: {}", _matchrule); - - synchronized (sigrecips) { - if (!sigrecips.contains(connStruct)) { - sigrecips.add(connStruct); - } - } - } - - @Override - public void RemoveMatch(String _matchrule) throws MatchRuleInvalid { - LOGGER.trace("Removing match rule: {}", _matchrule); - } - - @Override - public String[] ListQueuedOwners(String _name) { - return new String[0]; - } - - @Override - public UInt32 GetConnectionUnixProcessID(String _connectionName) { - return new UInt32(0); - } - - @Override - public Byte[] GetConnectionSELinuxSecurityContext(String _args) { - return new Byte[0]; - } - - @SuppressWarnings("unchecked") - private void handleMessage(ConnectionStruct _connStruct, Message _msg) throws DBusException { - LOGGER.trace("Handling message {} from {}", _msg, _connStruct.unique); - - if (!(_msg instanceof MethodCall)) { - return; - } - Object[] args = _msg.getParameters(); - - Class[] cs = new Class[args.length]; - - for (int i = 0; i < cs.length; i++) { - cs[i] = args[i].getClass(); - } - - java.lang.reflect.Method meth = null; - Object rv = null; - - try { - meth = DBusServer.class.getMethod(_msg.getName(), cs); - try { - this.connStruct = _connStruct; - rv = meth.invoke(dbusServer, args); - if (null == rv) { - - send(_connStruct, new MethodReturn("org.freedesktop.DBus", (MethodCall) _msg, null), true); - } else { - String sig = Marshalling.getDBusType(meth.getGenericReturnType())[0]; - send(_connStruct, new MethodReturn("org.freedesktop.DBus", (MethodCall) _msg, sig, rv), true); - } - } catch (InvocationTargetException _exIte) { - LOGGER.debug("", _exIte); - send(_connStruct, new Error("org.freedesktop.DBus", _msg, _exIte.getCause())); - } catch (DBusExecutionException _exDnEe) { - LOGGER.debug("", _exDnEe); - send(_connStruct, new Error("org.freedesktop.DBus", _msg, _exDnEe)); - } catch (Exception _ex) { - LOGGER.debug("", _ex); - send(_connStruct, new Error("org.freedesktop.DBus", _connStruct.unique, - "org.freedesktop.DBus.Error.GeneralError", _msg.getSerial(), "s", "An error occurred while calling " + _msg.getName())); - } - } catch (NoSuchMethodException _exNsm) { - send(_connStruct, new Error("org.freedesktop.DBus", _connStruct.unique, - "org.freedesktop.DBus.Error.UnknownMethod", _msg.getSerial(), "s", "This service does not support " + _msg.getName())); - } - - } - - @Override - public String getObjectPath() { - return null; - } - - @Override - public String Introspect() { - return "\n" - + "\n" - + " \n" - + " \n" - + " \n" - + " \n" - + " \n" - + " \n" - + " \n" - + " \n" - + " \n" - + " \n" - + " \n" - + " \n" - + " \n" - + " \n" - + " \n" - + " \n" - + " \n" - + " \n" - + " \n" - + " \n" - + " \n" - + " \n" - + " \n" - + " \n" - + " \n" - + " \n" - + " \n" - + " \n" - + " \n" - + " \n" - + " \n" - + " \n" - + " \n" + " \n" - + " \n" - + " \n" - + " \n" - + " \n" - + " \n" - + " \n" - + " \n" - + " \n" - + " \n" - + " \n" - + " \n" - + " \n" - + " \n" - + " \n" - + " \n" - + " \n" - + " \n" - + " \n" - + " \n" - + " \n" - + " \n" - + " \n" - + " \n" - + " \n" - + " \n" - + " \n" - + " \n" - + " \n" - + " \n" - + " \n" - + " \n" - + " \n" - + " \n" - + " \n" - + " \n" - + " \n" - + " \n" - + " \n" - + " \n" + ""; - } - - @Override - public void Ping() { - } - - @Override - public String[] ListActivatableNames() { - return null; - } - - @Override - public Map> GetConnectionCredentials(String _busName) { - return null; - } - - @Override - public Byte[] GetAdtAuditSessionData(String _busName) { - return null; - } - - @Override - public void UpdateActivationEnvironment(Map[] _environment) { - - } - - @Override - public String GetId() { - return null; - } - - @Override - public String GetMachineId() { - return machineId; - } - - } - - public class DBusDaemonSenderThread extends Thread { - private final Logger logger = LoggerFactory.getLogger(getClass()); - private final AtomicBoolean running = new AtomicBoolean(false); // switch running status when thread begins - - public DBusDaemonSenderThread() { - setName(getClass().getSimpleName().replace('$', '-')); - } - - @Override - public void run() { - logger.debug(">>>> Sender thread started <<<<"); - running.set(true); - while (isRunning() && running.get()) { - - logger.trace("Acquiring lock on outqueue and blocking for data"); - - // block on outqueue - try { - Pair> pollFirst = outqueue.take(); - if (pollFirst != null) { - ConnectionStruct connectionStruct = pollFirst.second.get(); - if (connectionStruct != null) { - if (connectionStruct.connection.getChannel().isConnected()) { - logger.debug(" Got message {} for {}", pollFirst.first, connectionStruct.unique); - - try { - connectionStruct.connection.getWriter().writeMessage(pollFirst.first); - } catch (IOException _ex) { - logger.debug("Disconnecting client due to previous exception", _ex); - removeConnection(connectionStruct); - } - } else { - logger.warn("Connection to {} broken", pollFirst.first.getDestination()); - removeConnection(connectionStruct); - } - - } else { - logger.info("Discarding {} connection reaped", pollFirst.first); - } - } - } catch (InterruptedException _ex) { - logger.debug("Got interrupted", _ex); - } - } - logger.debug(">>>> Sender Thread terminated <<<<"); - } - - public synchronized void terminate() { - running.set(false); - interrupt(); - } - } - - public class DBusDaemonReaderThread extends Thread { - private final Logger logger = LoggerFactory.getLogger(getClass()); - private ConnectionStruct conn; - private final WeakReference weakconn; - private final AtomicBoolean running = new AtomicBoolean(false); - - public DBusDaemonReaderThread(ConnectionStruct _conn) { - this.conn = _conn; - weakconn = new WeakReference<>(_conn); - setName(getClass().getSimpleName()); - } - - public void terminate() { - running.set(false); - } - - @Override - public void run() { - logger.debug(">>>> Reader Thread started <<<<"); - running.set(true); - while (isRunning() && running.get()) { - - Message m = null; - try { - m = conn.connection.getReader().readMessage(); - } catch (IOException _ex) { - LOGGER.debug("", _ex); - removeConnection(conn); - } catch (DBusException _ex) { - LOGGER.debug("", _ex); - if (_ex instanceof FatalException) { - removeConnection(conn); - } - } - - if (null != m) { - logMessage("Read {} from {}", m, conn.unique); - - inqueue.add(new Pair<>(m, weakconn)); - } - } - conn = null; - logger.debug(">>>> Reader Thread terminated <<<<"); - } - } - - static class Pair { - private final A first; - private final B second; - - Pair(A _first, B _second) { - first = _first; - second = _second; - } - - @Override - public int hashCode() { - return Objects.hash(first, second); - } - - @Override - public boolean equals(Object _obj) { - if (this == _obj) { - return true; - } - if (!(_obj instanceof Pair)) { - return false; - } - Pair other = (Pair) _obj; - return Objects.equals(first, other.first) && Objects.equals(second, other.second); - } - - } -} diff --git a/federation/sssd/src/main/java/org/freedesktop/dbus/bin/EmbeddedDBusDaemon.java b/federation/sssd/src/main/java/org/freedesktop/dbus/bin/EmbeddedDBusDaemon.java deleted file mode 100644 index b40792542d..0000000000 --- a/federation/sssd/src/main/java/org/freedesktop/dbus/bin/EmbeddedDBusDaemon.java +++ /dev/null @@ -1,224 +0,0 @@ -package org.freedesktop.dbus.bin; - -import org.freedesktop.dbus.connections.BusAddress; -import org.freedesktop.dbus.connections.transports.AbstractTransport; -import org.freedesktop.dbus.connections.transports.TransportBuilder; -import org.freedesktop.dbus.connections.transports.TransportBuilder.SaslAuthMode; -import org.freedesktop.dbus.connections.transports.TransportConnection; -import org.freedesktop.dbus.exceptions.AuthenticationException; -import org.freedesktop.dbus.exceptions.DBusException; -import org.freedesktop.dbus.exceptions.SocketClosedException; -import org.freedesktop.dbus.utils.Util; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.io.Closeable; -import java.io.IOException; -import java.nio.file.attribute.PosixFilePermission; -import java.util.Objects; -import java.util.concurrent.atomic.AtomicBoolean; - -/** - * Simple DBusDaemon implementation to use if no DBusDaemon is running on the OS level. - */ -public class EmbeddedDBusDaemon implements Closeable { - - private static final Logger LOGGER = LoggerFactory.getLogger(EmbeddedDBusDaemon.class); - - private final BusAddress address; - - private DBusDaemon daemon; - - private final AtomicBoolean closed = new AtomicBoolean(false); - private final AtomicBoolean connectionReady = new AtomicBoolean(false); - - private SaslAuthMode saslAuthMode; - - private String unixSocketFileOwner; - - private String unixSocketFileGroup; - - private PosixFilePermission[] unixSocketFilePermissions; - - public EmbeddedDBusDaemon(BusAddress _address) { - // create copy of address so manipulation happens later does not interfere with our instance - address = BusAddress.of(Objects.requireNonNull(_address, "Address required")); - } - - public EmbeddedDBusDaemon(String _address) throws DBusException { - this(BusAddress.of(_address)); - } - - /** - * Shutdown the running DBusDaemon instance. - */ - @Override - public synchronized void close() throws IOException { - closed.set(true); - connectionReady.set(false); - if (daemon != null) { - daemon.close(); - daemon = null; - } - } - - /** - * Run the DBusDaemon in foreground. - *

- * This is a blocking operation. - */ - public void startInForeground() { - try { - startListening(); - } catch (IOException | DBusException _ex) { - if (!closed.get()) { - throw new RuntimeException(_ex); - } - } - } - - /** - * Start the DBusDaemon in background and returns immediately. - *

- * This method may return before the background thread is ready. - * To ensure the the background thread is running on return use {@link #startInBackgroundAndWait(long)}. - */ - public void startInBackground() { - Thread thread = new Thread(this::startInForeground); - String threadName = address.toString().replaceAll("^([^,]+),.+", "$1"); - - thread.setName("EmbeddedDBusDaemon-" + threadName); - thread.setDaemon(true); - thread.setUncaughtExceptionHandler((th, ex) -> LOGGER.error("Got uncaught exception", ex)); - thread.start(); - } - - /** - * Starts the DBusDaemon in background. - *

- * Will wait up to the given period of milliseconds for the background thread to get ready. - * If given wait time exceeded, a {@link RuntimeException} is thrown. - * - * @param _maxWaitMillis maximum wait time in milliseconds - */ - public void startInBackgroundAndWait(long _maxWaitMillis) { - startInBackground(); - Util.waitFor("EmbeddedDbusDaemon", this::isRunning, _maxWaitMillis, 100); - } - - /** - * Whether the DBusDaemon is still running. - * - * @return true if running, false otherwise - */ - public synchronized boolean isRunning() { - return connectionReady.get() && daemon != null && daemon.isRunning(); - } - - /** - * The currently configured {@link SaslAuthMode}. - * When null is returned, the {@link SaslAuthMode} of the transport provider is used. - * - * @return {@link SaslAuthMode} or null - */ - public SaslAuthMode getSaslAuthMode() { - return saslAuthMode; - } - - /** - * Use this to override the default authentication mode which would - * be used by the transport based on the {@link BusAddress}. - * - * @param _saslAuthMode auth mode, null to use default - */ - public void setSaslAuthMode(SaslAuthMode _saslAuthMode) { - saslAuthMode = _saslAuthMode; - } - - /** - * The file owner for the created unix socket.
- * Ignored if TCP is used.
- *
- * Will only work if currently running JVM process user - * has suitable permissions to change the owner. - * - * @param _owner owner to set - */ - public void setUnixSocketOwner(String _owner) { - unixSocketFileOwner = _owner; - } - - /** - * The file group for the created unix socket.
- * Ignored if TCP is used.
- *
- * Will only work if currently running JVM process user - * has suitable permissions to change the group. - * - * @param _group group to set - */ - public void setUnixSocketGroup(String _group) { - unixSocketFileGroup = _group; - } - - /** - * The file permissions for the created unix socket.
- * Ignored if TCP is used or if the OS is Windows.
- *
- * Will only work if currently running JVM process user - * has suitable permissions to change the permissions. - * - * @param _permissions permissions to set - */ - public void setUnixSocketPermissions(PosixFilePermission... _permissions) { - unixSocketFilePermissions = _permissions; - } - - private synchronized void setDaemonAndStart(AbstractTransport _transport) { - daemon = new DBusDaemon(_transport); - daemon.start(); - } - - /** - * Start listening for incoming connections. - *

- * Will throw {@link IllegalArgumentException} if a unsupported transport is used. - * - * @throws IOException when connection fails - * @throws DBusException when the provided bus address is wrong - */ - private void startListening() throws IOException, DBusException { - if (!TransportBuilder.getRegisteredBusTypes().contains(address.getBusType())) { - throw new IllegalArgumentException("Unknown or unsupported address type: " + address.getType()); - } - - LOGGER.debug("About to initialize transport on: {}", address); - try (AbstractTransport transport = TransportBuilder.create(address).configure() - .withUnixSocketFileOwner(unixSocketFileOwner) - .withUnixSocketFileGroup(unixSocketFileGroup) - .withUnixSocketFilePermissions(unixSocketFilePermissions) - .withAutoConnect(false) - .configureSasl().withAuthMode(getSaslAuthMode()).back() - .back() - .build()) { - - setDaemonAndStart(transport); - - // use tail-controlled loop so we at least try to get a client connection once - do { - try { - LOGGER.debug("Begin listening to: {}", transport); - connectionReady.set(true); - TransportConnection s = transport.listen(); - daemon.addSock(s); - } catch (AuthenticationException _ex) { - LOGGER.error("Authentication failed", _ex); - } catch (SocketClosedException _ex) { - LOGGER.debug("Connection closed", _ex); - } - - } while (daemon.isRunning()); - - } - } -} diff --git a/federation/sssd/src/main/java/org/freedesktop/dbus/connections/impl/DirectConnection.java b/federation/sssd/src/main/java/org/freedesktop/dbus/connections/impl/DirectConnection.java deleted file mode 100644 index 60ba444b88..0000000000 --- a/federation/sssd/src/main/java/org/freedesktop/dbus/connections/impl/DirectConnection.java +++ /dev/null @@ -1,300 +0,0 @@ -package org.freedesktop.dbus.connections.impl; - -import static org.freedesktop.dbus.utils.CommonRegexPattern.IFACE_PATTERN; -import static org.freedesktop.dbus.utils.CommonRegexPattern.PROXY_SPLIT_PATTERN; - -import org.freedesktop.dbus.DBusMatchRule; -import org.freedesktop.dbus.RemoteInvocationHandler; -import org.freedesktop.dbus.RemoteObject; -import org.freedesktop.dbus.connections.AbstractConnection; -import org.freedesktop.dbus.connections.BusAddress; -import org.freedesktop.dbus.connections.config.ReceivingServiceConfig; -import org.freedesktop.dbus.connections.config.TransportConfig; -import org.freedesktop.dbus.exceptions.DBusException; -import org.freedesktop.dbus.interfaces.DBusInterface; -import org.freedesktop.dbus.interfaces.DBusSigHandler; -import org.freedesktop.dbus.interfaces.Introspectable; -import org.freedesktop.dbus.messages.DBusSignal; -import org.freedesktop.dbus.messages.ExportedObject; -import org.freedesktop.dbus.utils.Hexdump; -import org.freedesktop.dbus.utils.Util; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.lang.reflect.Proxy; -import java.net.InetAddress; -import java.net.UnknownHostException; -import java.security.MessageDigest; -import java.security.NoSuchAlgorithmException; -import java.util.Arrays; -import java.util.List; -import java.util.Queue; -import java.util.concurrent.ConcurrentLinkedQueue; -import java.util.stream.Collectors; - -/** - * Handles a peer to peer connection between two applications without a bus daemon. - *

- * Signal Handlers and method calls from remote objects are run in their own threads, you MUST handle the concurrency issues. - *

- */ -public class DirectConnection extends AbstractConnection { - private final Logger logger = LoggerFactory.getLogger(getClass()); - private final String machineId; - - /** - * Create a direct connection to another application. - * @param _address The address to connect to. This is a standard D-Bus address, except that the additional parameter 'listen=true' should be added in the application which is creating the socket. - * @throws DBusException on error - * @deprecated use {@link DirectConnectionBuilder} - */ - @Deprecated(since = "4.1.0", forRemoval = true) - public DirectConnection(String _address) throws DBusException { - this(_address, AbstractConnection.TCP_CONNECT_TIMEOUT); - } - - /** - * Create a direct connection to another application. - * @param _address The address to connect to. This is a standard D-Bus address, except that the additional parameter 'listen=true' should be added in the application which is creating the socket. - * @param _timeout the timeout set for the underlying socket. 0 will block forever on the underlying socket. - * @throws DBusException on error - * @deprecated use {@link DirectConnectionBuilder} - */ - @Deprecated(since = "4.1.0", forRemoval = true) - public DirectConnection(String _address, int _timeout) throws DBusException { - this(createTransportConfig(_address, _timeout), null); - } - - DirectConnection(TransportConfig _transportCfg, ReceivingServiceConfig _rsCfg) throws DBusException { - super(_transportCfg, _rsCfg); - machineId = createMachineId(); - if (!getAddress().isServer()) { - super.listen(); - } - } - - @Deprecated(since = "4.2.0", forRemoval = true) - static TransportConfig createTransportConfig(String _address, int _timeout) { - TransportConfig cfg = new TransportConfig(); - cfg.setBusAddress(BusAddress.of(_address)); - cfg.getAdditionalConfig().put("TIMEOUT", _timeout); - return cfg; - } - - /** - * Use this method when running on server side. - * Call will block. - */ - @Override - public void listen() { - if (getAddress().isServer()) { - super.listen(); - } - } - - private String createMachineId() { - String ascii; - - try { - ascii = Hexdump.toAscii(MessageDigest.getInstance("MD5").digest(InetAddress.getLocalHost().getHostName().getBytes())); - return ascii; - } catch (NoSuchAlgorithmException _ex) { - logger.trace("MD5 algorithm not present", _ex); - } catch (UnknownHostException _ex) { - logger.trace("Unable to determine this machines hostname", _ex); - } - - return Util.randomString(32); - } - - @SuppressWarnings("unchecked") - T dynamicProxy(String _path, Class _type) throws DBusException { - try { - Introspectable intro = getRemoteObject(_path, Introspectable.class); - String data = intro.Introspect(); - - String[] tags = PROXY_SPLIT_PATTERN.split(data); - - List ifaces = Arrays.stream(tags).filter(t -> t.startsWith("interface")) - .map(t -> IFACE_PATTERN.matcher(t).replaceAll("$1")) - .collect(Collectors.toList()); - - List> ifcs = findMatchingTypes(_type, ifaces); - - if (ifcs.isEmpty()) { - throw new DBusException("Could not find an interface to cast to"); - } - - RemoteObject ro = new RemoteObject(null, _path, _type, false); - DBusInterface newi = (DBusInterface) Proxy.newProxyInstance(ifcs.get(0).getClassLoader(), ifcs.toArray(new Class[0]), new RemoteInvocationHandler(this, ro)); - getImportedObjects().put(newi, ro); - return (T) newi; - } catch (Exception _ex) { - logger.debug("", _ex); - throw new DBusException(String.format("Failed to create proxy object for %s; reason: %s.", _path, _ex.getMessage())); - } - } - - @SuppressWarnings("unchecked") - T getExportedObject(String _path, Class _type) throws DBusException { - ExportedObject o = null; - synchronized (getExportedObjects()) { - o = getExportedObjects().get(_path); - } - if (null != o && null == o.getObject().get()) { - unExportObject(_path); - o = null; - } - if (null != o) { - return (T) o.getObject().get(); - } - return dynamicProxy(_path, _type); - } - - /** - * Return a reference to a remote object. - * This method will always refer to the well known name (if given) rather than resolving it to a unique bus name. - * In particular this means that if a process providing the well known name disappears and is taken over by another process - * proxy objects gained by this method will make calls on the new proccess. - * - * This method will use bus introspection to determine the interfaces on a remote object and so - * may block and may fail. The resulting proxy object will, however, be castable - * to any interface it implements. It will also autostart the process if applicable. Also note - * that the resulting proxy may fail to execute the correct method with overloaded methods - * and that complex types may fail in interesting ways. Basically, if something odd happens, - * try specifying the interface explicitly. - * - * @param _objectPath The path on which the process is exporting the object. - * @return A reference to a remote object. - * @throws ClassCastException If type is not a sub-type of DBusInterface - * @throws DBusException If busname or objectpath are incorrectly formatted. - */ - public DBusInterface getRemoteObject(String _objectPath) throws DBusException { - if (null == _objectPath) { - throw new DBusException("Invalid object path: null"); - } - - if (_objectPath.length() > MAX_NAME_LENGTH || !OBJECT_REGEX_PATTERN.matcher(_objectPath).matches()) { - throw new DBusException("Invalid object path: " + _objectPath); - } - - return dynamicProxy(_objectPath, null); - } - - /** - * Return a reference to a remote object. - * This method will always refer to the well known name (if given) rather than resolving it to a unique bus name. - * In particular this means that if a process providing the well known name disappears and is taken over by another process - * proxy objects gained by this method will make calls on the new proccess. - * @param _objectPath The path on which the process is exporting the object. - * @param _type The interface they are exporting it on. This type must have the same full class name and exposed method signatures - * as the interface the remote object is exporting. - * @param class which extends DBusInterface - * @return A reference to a remote object. - * @throws ClassCastException If type is not a sub-type of DBusInterface - * @throws DBusException If busname or objectpath are incorrectly formatted or type is not in a package. - */ - public T getRemoteObject(String _objectPath, Class _type) throws DBusException { - if (null == _objectPath) { - throw new DBusException("Invalid object path: null"); - } - if (null == _type) { - throw new ClassCastException("Not A DBus Interface"); - } - - if (_objectPath.length() > MAX_NAME_LENGTH || !OBJECT_REGEX_PATTERN.matcher(_objectPath).matches()) { - throw new DBusException("Invalid object path: " + _objectPath); - } - - if (!DBusInterface.class.isAssignableFrom(_type)) { - throw new ClassCastException("Not A DBus Interface"); - } - - // don't let people import things which don't have a - // valid D-Bus interface name - if (_type.getName().equals(_type.getSimpleName())) { - throw new DBusException("DBusInterfaces cannot be declared outside a package"); - } - - RemoteObject ro = new RemoteObject(null, _objectPath, _type, false); - - @SuppressWarnings("unchecked") - T i = (T) Proxy.newProxyInstance(_type.getClassLoader(), - new Class[] {_type}, new RemoteInvocationHandler(this, ro)); - - getImportedObjects().put(i, ro); - - return i; - } - - @Override - protected void removeSigHandler(DBusMatchRule _rule, DBusSigHandler _handler) throws DBusException { - Queue> v = getHandledSignals().get(_rule); - if (null != v) { - v.remove(_handler); - if (0 == v.size()) { - getHandledSignals().remove(_rule); - } - } - } - - @Override - protected AutoCloseable addSigHandler(DBusMatchRule _rule, DBusSigHandler _handler) throws DBusException { - Queue> v = - getHandledSignals().computeIfAbsent(_rule, val -> { - Queue> l = new ConcurrentLinkedQueue<>(); - return l; - }); - - v.add(_handler); - return new AutoCloseable() { - @Override - public void close() throws Exception { - removeSigHandler(_rule, _handler); - } - }; - } - - @Override - protected void removeGenericSigHandler(DBusMatchRule _rule, DBusSigHandler _handler) throws DBusException { - Queue> v = getGenericHandledSignals().get(_rule); - if (null != v) { - v.remove(_handler); - if (0 == v.size()) { - getGenericHandledSignals().remove(_rule); - } - } - } - - @Override - protected AutoCloseable addGenericSigHandler(DBusMatchRule _rule, DBusSigHandler _handler) throws DBusException { - Queue> v = - getGenericHandledSignals().computeIfAbsent(_rule, val -> { - Queue> l = new ConcurrentLinkedQueue<>(); - return l; - }); - - v.add(_handler); - return new AutoCloseable() { - @Override - public void close() throws Exception { - removeGenericSigHandler(_rule, _handler); - } - }; - } - - @Override - public T getExportedObject(String _source, String _path, Class _type) throws DBusException { - return getExportedObject(_path, _type); - } - - @Override - public String getMachineId() { - return machineId; - } - - @Override - public DBusInterface getExportedObject(String _source, String _path) throws DBusException { - return getExportedObject(_path, (Class) null); - } -} diff --git a/federation/sssd/src/main/java/org/freedesktop/dbus/connections/impl/DirectConnectionBuilder.java b/federation/sssd/src/main/java/org/freedesktop/dbus/connections/impl/DirectConnectionBuilder.java deleted file mode 100644 index 1e291656b1..0000000000 --- a/federation/sssd/src/main/java/org/freedesktop/dbus/connections/impl/DirectConnectionBuilder.java +++ /dev/null @@ -1,64 +0,0 @@ -package org.freedesktop.dbus.connections.impl; - -import org.freedesktop.dbus.connections.BusAddress; -import org.freedesktop.dbus.connections.config.ReceivingServiceConfig; -import org.freedesktop.dbus.connections.config.TransportConfig; -import org.freedesktop.dbus.exceptions.DBusException; -import org.freedesktop.dbus.messages.Message; - -import java.nio.ByteOrder; - -/** - * Builder to create a new DirectConnection. - * - * @author hypfvieh - * @version 4.1.0 - 2022-02-04 - */ -public final class DirectConnectionBuilder extends BaseConnectionBuilder { - - private DirectConnectionBuilder(BusAddress _address) { - super(DirectConnectionBuilder.class, _address); - } - - /** - * Use the given address to create the connection (e.g. used for remote TCP connected DBus daemons). - * - * @param _address address to use - * @return this - */ - public static DirectConnectionBuilder forAddress(String _address) { - DirectConnectionBuilder instance = new DirectConnectionBuilder(BusAddress.of(_address)); - return instance; - } - - /** - * Create the new {@link DBusConnection}. - * - * @return {@link DBusConnection} - * @throws DBusException when DBusConnection could not be opened - */ - @Override - public DirectConnection build() throws DBusException { - ReceivingServiceConfig rsCfg = buildThreadConfig(); - TransportConfig transportCfg = buildTransportConfig(); - - DirectConnection c = new DirectConnection(transportCfg, rsCfg); - c.setDisconnectCallback(getDisconnectCallback()); - c.setWeakReferences(isWeakReference()); - DirectConnection.setEndianness(getEndianess()); - return c; - } - - /** - * Get the default system endianness. - * - * @return LITTLE or BIG - * @deprecated if required, use {@link BaseConnectionBuilder#getSystemEndianness()} - */ - @Deprecated(forRemoval = true, since = "4.2.0") - public static byte getSystemEndianness() { - return ByteOrder.nativeOrder().equals(ByteOrder.BIG_ENDIAN) - ? Message.Endian.BIG - : Message.Endian.LITTLE; - } -}