package uc; import helpers.GH; import helpers.IObservable; import helpers.Observable; import helpers.PreferenceChangedAdapter; import java.security.SecureRandom; import java.util.ArrayList; import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; import uc.IStoppable.IStartable; import uc.IUser.Mode; import uc.crypto.CryptoManager; import uc.crypto.HashValue; import uc.crypto.Tiger; import uc.protocols.Socks; /** * TODO implement Identity concept --> rewrite DCClient to have one base-identity.. * -> make it so multiple identities are allowed/possible... * * * @author Quicksilver * */ public abstract class Identity extends Observable<ChangedAttribute> { private static final String[] IDENTITY_SETTINGS = new String[] {PI.allowTLS,PI.allowUPnP,PI.bindAddress, PI.externalIp,PI.inPort,PI.tlsPort,PI.passive,PI.uUID, PI.socksProxyEnabled,PI.socksProxyHost,PI.socksProxyPassword, PI.socksProxyPort,PI.socksProxyUsername}; private final String name; private final String certFileName; public String getCertFileName() { return certFileName; } private final HashValue pid; /** * stores all hubs running using this identity * used to start/stop included stuff based on * if in use.. */ protected final List<FavHub> runningHubs = new ArrayList<FavHub>(); // -> missing which dirs are included.. for own filelist.. private final ICryptoManager cryptoManager; private final ConnectionHandler connectionHandler; private final IConnectionDeterminator connectionDeterminator; /** * default identity * containing the usual settings.. */ public Identity(DCClient dcc,String name,String certFileName) { this.certFileName = certFileName; this.name = name; pid = loadPID(); cryptoManager = new CryptoManager(dcc, this); connectionHandler = new ConnectionHandler(dcc,this); connectionDeterminator = new ConnectionDeterminator(dcc, this); } protected HashValue loadPID() { String uuid = get(PI.uUID); if (GH.isNullOrEmpty(uuid)) { SecureRandom sr = new SecureRandom(); byte[] b = new byte[1024]; sr.nextBytes(b); HashValue hash = Tiger.tigerOfBytes(b); uuid = hash.toString(); put(PI.uUID, uuid); } return HashValue.createHash(get(PI.uUID)); } /** * must be added before hub is started * @param fh favHub added.. */ void addRunningHub(FavHub fh) { synchronized(runningHubs) { if (runningHubs.isEmpty()) { start(); } runningHubs.add(fh); } } void removeRunningHub(FavHub fh) { synchronized(runningHubs) { if (runningHubs.remove(fh) && runningHubs.isEmpty()) { stop(); } } } protected void start() { connectionHandler.start(); connectionDeterminator.start(); } protected void stop() { connectionHandler.stop(); connectionDeterminator.stop(); } public ConnectionHandler getConnectionHandler() { return connectionHandler; } public IConnectionDeterminator getConnectionDeterminator() { return connectionDeterminator; } public boolean isDefault() { return false; } /** * place holder should return true if * IPv4 is used * @return true */ public boolean isIPv4Used() { return connectionDeterminator.getPublicIP() != null; } /** * * @return true if IPv6 connections are possible.. */ public boolean isIPv6Used() { return connectionDeterminator.getIp6FoundandWorking() != null; } /** * check if TLS was enabled at start of Program .. and is now in a usable state. * @return true if TLS is fully initialized and running..(for this identity..) * */ public boolean currentlyTLSSupport() { return connectionHandler.isTLSRunning() && getBoolean(PI.allowTLS); } public abstract void put(String pref,String value); public void put(String pref,boolean value) { put(pref,Boolean.toString(value)); } public int getInt(String pref) { return Integer.parseInt(get(pref)); } public abstract String get(String pref); public boolean getBoolean(String pref) { return Boolean.parseBoolean(get(pref)); } public boolean isActive() { return !getBoolean(PI.passive); } public Mode getMode() { return isActive() ? Mode.ACTIVE : (Socks.isEnabled()? Mode.SOCKS:Mode.PASSIVE) ; } public String getName() { return name; } public HashValue getPID() { return pid; } public HashValue getCID() { return getPID().hashOfHash(); } public ICryptoManager getCryptoManager() { return cryptoManager; } public abstract static class FilteredChangedAttributeListener implements IObserver<ChangedAttribute> { private final String[] attribs; protected FilteredChangedAttributeListener(String... attributes ) { this.attribs = attributes; } public void update(IObservable<ChangedAttribute> o, ChangedAttribute arg) { for (String s: attribs) { if (s.equals(arg.getAttribute())) { preferenceChanged(arg.getAttribute(),arg.getOldValue(),arg.getNewValue()); break; } } } protected abstract void preferenceChanged(String pref,String oldValue,String newValue); } public static class DefaultIdentity extends Identity implements IStartable { public DefaultIdentity(DCClient dcc) { super(dcc, "<default>",".keystore"); new PreferenceChangedAdapter(PI.get(),IDENTITY_SETTINGS) { @Override public void preferenceChanged(String preference, String oldValue,String newValue) { notifyObservers(new ChangedAttribute(preference, oldValue, newValue)); } }; } public String get(String pref) { return PI.get(pref); } /** * must be added before hub is started * @param fh favHub added.. */ void addRunningHub(FavHub fh) { synchronized(runningHubs) { runningHubs.add(fh); } } void removeRunningHub(FavHub fh) { synchronized(runningHubs) { runningHubs.remove(fh); } } @Override public void put(String pref, String value) { PI.put(pref, value); } public boolean isDefault() { return true; } @Override public void start() { super.start(); } @Override public void stop() { super.stop(); } } public static class OtherIdentity extends Identity { private final Map<String,String> idSettings = Collections.synchronizedMap(new HashMap<String, String>()); public OtherIdentity(DCClient dcc) { super(dcc,"",""); } public String get(String pref) { return idSettings.get(pref); } @Override public void put(String pref, String value) { String oldValue = idSettings.get(pref); if (!oldValue.equals(value)) { idSettings.put(pref, value); notifyObservers(new ChangedAttribute(pref, oldValue, value)); } } } // // private int tcpPort,tlsPort; //Connection handler stuff // private ConnectionHandler handler; // own connection handler for these ports needed.. // // private CryptoManager cryptoManager; // all the cryptostuff.. // // private IUser filelistSelf; //own CID/PID -> stuff like email and Nick could be packed here.. (Personal Information Pref page basically) self or rather filelist self that is // // private OwnFileList filelist; // FILELIST used for searching here.. //External IP settable per identity..or whole connection settings.. also bind address.. }