Ejemplo n.º 1
0
 public KeePassRPCService(IPluginHost host, string[] standardIconsBase64, KeePassRPCExt plugin)
 {
     KeePassRPCPlugin = plugin;
     PluginVersion = KeePassRPCExt.PluginVersion;
     this.host = host;
     _standardIconsBase64 = standardIconsBase64;
 }
Ejemplo n.º 2
0
 /// <summary>
 /// Starts the web socket listener
 /// </summary>
 /// <param name="service">The KeePassRPCService the server should interact with.</param>
 public KeePassRPCServer(KeePassRPCService service, KeePassRPCExt keePassRPCPlugin, int webSocketPort, bool bindOnlyToLoopback)
 {
     if (keePassRPCPlugin.logger != null) keePassRPCPlugin.logger.WriteLine("Starting KPRPCServer");
     Service = service;
     KeePassRPCPlugin = keePassRPCPlugin;
     StartWebsockServer(webSocketPort, bindOnlyToLoopback);
     if (keePassRPCPlugin.logger != null) keePassRPCPlugin.logger.WriteLine("Started KPRPCServer");
 }
Ejemplo n.º 3
0
 public override void AttachToEntryDialog(KeePassRPCExt plugin, PwEntry entry, TabControl mainTabControl, PwEntryForm form, CustomListViewEx advancedListView, ProtectedStringDictionary strings)
 {
     KeeFoxEntryUserControl entryControl = new KeeFoxEntryUserControl(plugin, entry, advancedListView, form, strings);
     TabPage keefoxTabPage = new TabPage("KeeFox");
     entryControl.Dock = DockStyle.Fill;
     keefoxTabPage.Controls.Add(entryControl);
     if (mainTabControl.ImageList == null)
         mainTabControl.ImageList = new ImageList();
     int imageIndex = mainTabControl.ImageList.Images.Add(global::KeePassRPC.Properties.Resources.KeeFox16, Color.Transparent);
     keefoxTabPage.ImageIndex = imageIndex;
     mainTabControl.TabPages.Add(keefoxTabPage);
 }
Ejemplo n.º 4
0
 public override void AttachToGroupDialog(KeePassRPCExt plugin, PwGroup group, TabControl mainTabControl)
 {
     KeeFoxGroupUserControl groupControl = new KeeFoxGroupUserControl(plugin, group);
     TabPage keefoxTabPage = new TabPage("KeeFox");
     groupControl.Dock = DockStyle.Fill;
     keefoxTabPage.Controls.Add(groupControl);
     if (mainTabControl.ImageList == null)
         mainTabControl.ImageList = new ImageList();
     int imageIndex = mainTabControl.ImageList.Images.Add(global::KeePassRPC.Properties.Resources.KeeFox16, Color.Transparent);
     keefoxTabPage.ImageIndex = imageIndex;
     mainTabControl.TabPages.Add(keefoxTabPage);
 }
Ejemplo n.º 5
0
        public KeePassRPCClientConnection(IWebSocketConnection connection, bool isAuthorised, KeePassRPCExt kprpc)
        {
            WebSocketConnection = connection;
            Authorised = isAuthorised;

            //TODO2: Can we lazy load these since some sessions will require only one of these authentication mechanisms?
            _srp = new SRP();
            Kcp = new KeyChallengeResponse(ProtocolVersion);

            // Load from config, default to medium security if user has not yet requested anything different
            securityLevel = (int)kprpc._host.CustomConfig.GetLong("KeePassRPC.SecurityLevel", 2);
            securityLevelClientMinimum = (int)kprpc._host.CustomConfig.GetLong("KeePassRPC.SecurityLevelClientMinimum", 2);
            KPRPC = kprpc;
        }
Ejemplo n.º 6
0
        public OptionsForm(IPluginHost host, KeePassRPCExt plugin)
        {
            _host = host;
            _plugin = plugin;

            InitializeComponent();
            Icon = global::KeePassRPC.Properties.Resources.keefox;
            checkBox1.Text = "Automatically save KeePass database when KeeFox makes changes";
            if (host.CustomConfig.GetBool("KeePassRPC.KeeFox.autoCommit", true))
                checkBox1.Checked = true;
            else
                checkBox1.Checked = false;

            checkBox2.Text = "Immediately edit entries created by KeeFox";
            if (host.CustomConfig.GetBool("KeePassRPC.KeeFox.editNewEntries", false))
                checkBox2.Checked = true;
            else
                checkBox2.Checked = false;

            label13.Text = "You can generate new random passwords from KeeFox. These are stored in your system clipboard ready for you to paste into \"new user\" or \"change password\" fields. To protect against accidents these new passwords can be automatically stored in your current KeePass database under a special \"KeeFox Generated Password Backups\" group. You can generate new passwords when not logged in to a KeePass database but they will not receive this extra protection. The KeePass database can NOT be automatically saved after creating these backups so some problems can still result in a lost generated password.";

            checkBox3.Text = "Store a backup of each password generated by KeeFox";
            if (host.CustomConfig.GetBool("KeePassRPC.KeeFox.backupNewPasswords", true))
                checkBox3.Checked = true;
            else
                checkBox3.Checked = false;

            textBoxAuthExpiry.Text = (_host.CustomConfig.GetLong("KeePassRPC.AuthorisationExpiryTime", 8760 * 3600) / 3600).ToString();

            long secLevel = _host.CustomConfig.GetLong("KeePassRPC.SecurityLevel", 2);
            long secLevelClientMin = _host.CustomConfig.GetLong("KeePassRPC.SecurityLevelClientMinimum", 2);
            switch (secLevel)
            {
                case 1: comboBoxSecLevelKeePass.SelectedItem = "Low"; break;
                case 2: comboBoxSecLevelKeePass.SelectedItem = "Medium"; break;
                default: comboBoxSecLevelKeePass.SelectedItem = "High"; break;
            }
            switch (secLevelClientMin)
            {
                case 1: comboBoxSecLevelMinClient.SelectedItem = "Low"; break;
                case 2: comboBoxSecLevelMinClient.SelectedItem = "Medium"; break;
                default: comboBoxSecLevelMinClient.SelectedItem = "High"; break;
            }

            label6.Text = "Listen for connections on this TCP/IP port.";
            textBoxPort.Text = _host.CustomConfig.GetLong("KeePassRPC.webSocket.port", 12546).ToString();

            UpdateAuthorisedConnections();
        }
Ejemplo n.º 7
0
        public override void AttachToEntryDialog(KeePassRPCExt plugin, PwEntry entry, TabControl mainTabControl, PwEntryForm form, CustomListViewEx advancedListView, ProtectedStringDictionary strings)
        {
            KeeFoxEntryUserControl entryControl = new KeeFoxEntryUserControl(plugin, entry, advancedListView, form, strings);
            TabPage keefoxTabPage = new TabPage("KeeFox");

            entryControl.Dock = DockStyle.Fill;
            keefoxTabPage.Controls.Add(entryControl);
            if (mainTabControl.ImageList == null)
            {
                mainTabControl.ImageList = new ImageList();
            }
            int imageIndex = mainTabControl.ImageList.Images.Add(global::KeePassRPC.Properties.Resources.KeeFox16, Color.Transparent);

            keefoxTabPage.ImageIndex = imageIndex;
            mainTabControl.TabPages.Add(keefoxTabPage);
        }
Ejemplo n.º 8
0
        public override void AttachToGroupDialog(KeePassRPCExt plugin, PwGroup group, TabControl mainTabControl)
        {
            KeeFoxGroupUserControl groupControl = new KeeFoxGroupUserControl(plugin, group);
            TabPage keefoxTabPage = new TabPage("KeeFox");

            groupControl.Dock = DockStyle.Fill;
            keefoxTabPage.Controls.Add(groupControl);
            if (mainTabControl.ImageList == null)
            {
                mainTabControl.ImageList = new ImageList();
            }
            int imageIndex = mainTabControl.ImageList.Images.Add(global::KeePassRPC.Properties.Resources.KeeFox16, Color.Transparent);

            keefoxTabPage.ImageIndex = imageIndex;
            mainTabControl.TabPages.Add(keefoxTabPage);
        }
Ejemplo n.º 9
0
        public OptionsForm(IPluginHost host, KeePassRPCExt plugin)
        {
            _host = host;
            _plugin = plugin;

            InitializeComponent();
            Icon = global::KeePassRPC.Properties.Resources.keefox;
            this.checkBox1.Text = "Automatically save KeePass database when KeeFox makes changes";
            if (host.CustomConfig.GetBool("KeePassRPC.KeeFox.autoCommit", true))
                this.checkBox1.Checked = true;
            else
                this.checkBox1.Checked = false;

            this.checkBox2.Text = "Immediately edit entries created by KeeFox";
            if (host.CustomConfig.GetBool("KeePassRPC.KeeFox.editNewEntries", false))
                this.checkBox2.Checked = true;
            else
                this.checkBox2.Checked = false;

            this.textBoxAuthExpiry.Text = (_host.CustomConfig.GetLong("KeePassRPC.AuthorisationExpiryTime", 8760 * 3600) / 3600).ToString();

            long secLevel = _host.CustomConfig.GetLong("KeePassRPC.SecurityLevel", 2);
            long secLevelClientMin = _host.CustomConfig.GetLong("KeePassRPC.SecurityLevelClientMinimum", 2);
            switch (secLevel)
            {
                case 1: comboBoxSecLevelKeePass.SelectedItem = "Low"; break;
                case 2: comboBoxSecLevelKeePass.SelectedItem = "Medium"; break;
                default: comboBoxSecLevelKeePass.SelectedItem = "High"; break;
            }
            switch (secLevelClientMin)
            {
                case 1: comboBoxSecLevelMinClient.SelectedItem = "Low"; break;
                case 2: comboBoxSecLevelMinClient.SelectedItem = "Medium"; break;
                default: comboBoxSecLevelMinClient.SelectedItem = "High"; break;
            }

            this.label6.Text = "Listen for connections on this TCP/IP port.";
            this.textBoxPort.Text = _host.CustomConfig.GetLong("KeePassRPC.webSocket.port", 12546).ToString();

            UpdateAuthorisedConnections();
        }
Ejemplo n.º 10
0
        public override void AttachToEntryDialog(KeePassRPCExt plugin, PwEntry entry, TabControl mainTabControl, PwEntryForm form, CustomListViewEx advancedListView, ProtectedStringDictionary strings)
        {
            UserControl entryControl;

            try
            {
                string qualifiedName = typeof(KeePass.Util.AutoType).AssemblyQualifiedName
                                       .Replace("KeePass.Util.AutoType", "KeePass.Util.MultipleValues.MultipleValuesEx");
                System.Type  mvType   = System.Type.GetType(qualifiedName);
                PropertyInfo prop     = mvType.GetProperty("CueString", BindingFlags.Public | BindingFlags.Static);
                string       mvString = (string)prop.GetValue(null, null);
                string       json     = strings.ReadSafe("KPRPC JSON");
                if (!string.IsNullOrEmpty(json) && mvString == json)
                {
                    entryControl = new KeeMultiEntryUserControl();
                }
                else
                {
                    entryControl = new KeeEntryUserControl(plugin, entry, advancedListView, form, strings);
                }
            }
            catch
            {
                // Assume we're running in an older version of KeePass that can't edit multiple entries
                entryControl = new KeeEntryUserControl(plugin, entry, advancedListView, form, strings);
            }

            TabPage keeTabPage = new TabPage("Kee");

            entryControl.Dock = DockStyle.Fill;
            keeTabPage.Controls.Add(entryControl);
            if (mainTabControl.ImageList == null)
            {
                mainTabControl.ImageList = new ImageList();
            }
            int imageIndex = mainTabControl.ImageList.Images.Add(global::KeePassRPC.Properties.Resources.KPRPC64, Color.Transparent);

            keeTabPage.ImageIndex = imageIndex;
            mainTabControl.TabPages.Add(keeTabPage);
        }
Ejemplo n.º 11
0
 public virtual void AttachToGroupDialog(KeePassRPCExt plugin, PwGroup group, TabControl mainTabControl)
 {
     return;
 }
Ejemplo n.º 12
0
 public virtual void AttachToEntryDialog(KeePassRPCExt plugin, PwEntry entry, TabControl mainTabControl, PwEntryForm form, CustomListViewEx advancedListView, ProtectedStringDictionary strings)
 {
     return;
 }
Ejemplo n.º 13
0
 public virtual void AttachToGroupDialog(KeePassRPCExt plugin, PwGroup group, TabControl mainTabControl)
 {
     return;
 }
Ejemplo n.º 14
0
 public virtual void AttachToEntryDialog(KeePassRPCExt plugin, PwEntry entry, TabControl mainTabControl, PwEntryForm form, CustomListViewEx advancedListView, ProtectedStringDictionary strings)
 {
     return;
 }
Ejemplo n.º 15
0
 public static PKCS12 Generate(string subject, string issuer, KeePassRPCExt KeePassRPCPlugin)
 {
     return Generate(subject, issuer, (string)null, KeePassRPCPlugin);
 }
Ejemplo n.º 16
0
 public IconConverter(IPluginHost host, KeePassRPCExt plugin, string[] _standardIconsBase64)
 {
     this.host                 = host;
     this.KeePassRPCPlugin     = plugin;
     this._standardIconsBase64 = _standardIconsBase64;
 }
Ejemplo n.º 17
0
        /// <summary>
        /// Establishes the SSL certificate we will use for communication with
        /// RPC clients and starts a seperate thread to listen for connections
        /// </summary>
        /// <param name="port">port to listen on</param>
        /// <param name="service">The KeePassRPCService the server should interact with.</param>
        public KeePassRPCServer(int port, KeePassRPCService service, KeePassRPCExt keePassRPCPlugin, bool useSSL)
        {
            _useSSL = useSSL;
            if (keePassRPCPlugin.logger != null) keePassRPCPlugin.logger.WriteLine("Starting KPRPCServer");
            Service = service;
            KeePassRPCPlugin = keePassRPCPlugin;

            if (_useSSL)
            {
                if (Type.GetType("Mono.Runtime") == null)
                {
                    _store = new X509Store();
                    _store.Open(OpenFlags.ReadWrite);

                    // Find any certificates in this user's certificate store and re-use
                    // them rather than suffer the overhead of creating an entirly new
                    // certificate. Our certificates are considered "invalid" by the
                    // store (probably becuase they are self-signed)
                    X509Certificate2Collection matchingCertificates = _store.Certificates
                        .Find(X509FindType.FindBySubjectDistinguishedName,
                            "CN=KeePassRPC certificate for " + Environment.MachineName, false);

                    //foreach (X509Certificate2 temp in matchingCertificates)
                    //    _store.Remove(temp);

                    //matchingCertificates = _store.Certificates
                    //    .Find(X509FindType.FindBySubjectDistinguishedName,
                    //        "CN=KeePassRPC TLS aaa for " + Environment.MachineName, false);

                    if (keePassRPCPlugin.logger != null) keePassRPCPlugin.logger.WriteLine("Matching certificates from store: " + matchingCertificates.Count);
                    if (matchingCertificates.Count > 0)
                        _serverCertificate = matchingCertificates[0];
                    else
                    {
                        //_serverCertificate = (X509Certificate2)X509Certificate2.CreateFromCertFile(Path.Combine(Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), "KeePassRPC"), "cert.p12"));

                        if (keePassRPCPlugin.logger != null) keePassRPCPlugin.logger.WriteLine("Generating new certificate (MS).");
                        // We can use the MakeCert feature from Mono to generate a new
                        // certificate for use by this user on this machine. This means
                        // that every KeePassRPC user will establish TLS connections
                        // that are protected by a private key held on their own
                        // system, rather than a key that is disclosed in this open
                        // source code. NB: The local server is assumed to be secure!
                        byte[] cert = MakeCertKPRPC.Generate("KeePassRPC certificate for " + Environment.MachineName, "KeePassRPC Automated Self-Signed Key Generator", keePassRPCPlugin);
                        _serverCertificate = new X509Certificate2(cert, (string)null, X509KeyStorageFlags.PersistKeySet);
                        _store.Add(_serverCertificate);
                    }
                }
                else
                {
                    if (keePassRPCPlugin.logger != null) keePassRPCPlugin.logger.WriteLine("Looking for existing certificate (Mono)");

                    _serverCertificate = (X509Certificate2)X509Certificate2.CreateFromCertFile(Path.Combine(Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), "KeePassRPC"), "cert.p12"));

                    if (_serverCertificate == null)
                    {
                        if (keePassRPCPlugin.logger != null) keePassRPCPlugin.logger.WriteLine("Generating new certificate (Mono).");

                        MakeCertKPRPC.Generate("KeePassRPC certificate for " + Environment.MachineName, "KeePassRPC Automated Self-Signed Key Generator", keePassRPCPlugin);
                        _serverCertificate = (X509Certificate2)X509Certificate2.CreateFromCertFile(Path.Combine(Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), "KeePassRPC"), "cert.p12"));
                    }
                }

            }
               if (keePassRPCPlugin.logger != null) keePassRPCPlugin.logger.WriteLine("Server certificate has private key? " + _serverCertificate.HasPrivateKey);

            try
            {
                this._tcpListener =  new TcpListener(IPAddress.Loopback, port);
                this._listenThread = new Thread(new ThreadStart(ListenForClients));
                this._listenThread.Start();
                this._isListening = true; // just in case the main thread checks
                    // for successful startup before the thread has got going.
            }
            catch (Exception e)
            {
                if (keePassRPCPlugin.logger != null) keePassRPCPlugin.logger.WriteLine("Failed to start TCP listener: " + e.ToString());
            }
            if (keePassRPCPlugin.logger != null) keePassRPCPlugin.logger.WriteLine("Started KPRPCServer");
        }
Ejemplo n.º 18
0
        /// <summary>
        /// Establishes the SSL certificate we will use for communication with
        /// RPC clients and starts a seperate thread to listen for connections
        /// </summary>
        /// <param name="port">port to listen on</param>
        /// <param name="service">The KeePassRPCService the server should interact with.</param>
        public KeePassRPCServer(int port, KeePassRPCService service, KeePassRPCExt keePassRPCPlugin, bool useSSL)
        {
            _useSSL = useSSL;
            if (keePassRPCPlugin.logger != null)
            {
                keePassRPCPlugin.logger.WriteLine("Starting KPRPCServer");
            }
            Service          = service;
            KeePassRPCPlugin = keePassRPCPlugin;

            if (_useSSL)
            {
//                if (true)
                if (Type.GetType("Mono.Runtime") == null)
                {
                    _store = new System.Security.Cryptography.X509Certificates.X509Store();
                    _store.Open(OpenFlags.ReadWrite);

                    // Find any certificates in this user's certificate store and re-use
                    // them rather than suffer the overhead of creating an entirly new
                    // certificate. Our certificates are considered "invalid" by the
                    // store (probably becuase they are self-signed)
                    X509Certificate2Collection matchingCertificates = _store.Certificates
                                                                      .Find(X509FindType.FindBySubjectDistinguishedName,
                                                                            "CN=KeePassRPC certificate for " + Environment.MachineName, false);

                    //foreach (X509Certificate2 temp in matchingCertificates)
                    //    _store.Remove(temp);

                    //matchingCertificates = _store.Certificates
                    //    .Find(X509FindType.FindBySubjectDistinguishedName,
                    //        "CN=KeePassRPC TLS aaa for " + Environment.MachineName, false);

                    if (keePassRPCPlugin.logger != null)
                    {
                        keePassRPCPlugin.logger.WriteLine("Matching certificates from store: " + matchingCertificates.Count);
                    }
                    if (matchingCertificates.Count > 0)
                    {
                        _serverCertificate = matchingCertificates[0];
                    }
                    else
                    {
                        //_serverCertificate = (X509Certificate2)X509Certificate2.CreateFromCertFile(Path.Combine(Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), "KeePassRPC"), "cert.p12"));

                        if (keePassRPCPlugin.logger != null)
                        {
                            keePassRPCPlugin.logger.WriteLine("Generating new certificate (MS).");
                        }
                        // We can use the MakeCert feature from Mono to generate a new
                        // certificate for use by this user on this machine. This means
                        // that every KeePassRPC user will establish TLS connections
                        // that are protected by a private key held on their own
                        // system, rather than a key that is disclosed in this open
                        // source code. NB: The local server is assumed to be secure!
                        PKCS12 p12  = MakeCertKPRPC.Generate("KeePassRPC certificate for " + Environment.MachineName, "KeePassRPC Automated Self-Signed Key Generator", keePassRPCPlugin);
                        byte[] cert = p12.GetBytes();
                        _serverCertificate = new X509Certificate2(cert, (string)null, X509KeyStorageFlags.PersistKeySet);
                        _store.Add(_serverCertificate);
                    }
                }
                else
                {
                    /*
                     * Problem 1:
                     *   For Linux/Mono, we cannot use the X509Store. It appears that only a .cer file is saved. That certificate does not include
                     *   the private key that we need for SSL. So we will need to save the key ourselves.
                     *
                     * Problem 2:
                     *   When using PKCS12 SaveToFile to save the key ourselves, it appears that it is not possible to save a private key that is not
                     *   password protected.
                     *
                     */
                    string certdir  = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), "KeePassRPC");
                    string certfile = Path.Combine(certdir, "cert.p12");
                    _serverCertificate = null;

                    // Check if cert directory exists, if not, we need to create it
                    if (!System.IO.Directory.Exists(certdir))
                    {
                        if (keePassRPCPlugin.logger != null)
                        {
                            keePassRPCPlugin.logger.WriteLine("Cert directory does not exist, creating " + certdir);
                        }

                        System.IO.Directory.CreateDirectory(certdir);

                        if (keePassRPCPlugin.logger != null)
                        {
                            keePassRPCPlugin.logger.WriteLine("Cert directory created");
                        }
                    }
                    else
                    {
                        // Attempt to load cert
                        try {
                            if (keePassRPCPlugin.logger != null)
                            {
                                keePassRPCPlugin.logger.WriteLine("Looking for existing certificate (Mono)");
                            }
                            _serverCertificate = new X509Certificate2();
                            _serverCertificate.Import(certfile, pkcs12_password, X509KeyStorageFlags.PersistKeySet);
                            if (keePassRPCPlugin.logger != null)
                            {
                                keePassRPCPlugin.logger.WriteLine("Existing certificate loaded(Mono) : " + certfile);
                            }
                        }
                        catch (Exception ex) {
                            _serverCertificate = null;
                        }
                    }
                    // If we didn't load a cert, create one and save it
                    if (_serverCertificate == null)
                    {
                        if (keePassRPCPlugin.logger != null)
                        {
                            keePassRPCPlugin.logger.WriteLine("Generating new certificate (Mono).");
                        }

                        PKCS12 p12 = MakeCertKPRPC.Generate("KeePassRPC certificate for " + Environment.MachineName, "KeePassRPC Automated Self-Signed Key Generator", pkcs12_password, keePassRPCPlugin);
                        p12.SaveToFile(certfile);
                        byte[] cert = p12.GetBytes();
                        _serverCertificate = new X509Certificate2(cert, pkcs12_password, X509KeyStorageFlags.PersistKeySet);
                        if (keePassRPCPlugin.logger != null)
                        {
                            keePassRPCPlugin.logger.WriteLine("Generated new certificate (Mono) : " + certfile);
                        }
                    }
                }
            }

            if (keePassRPCPlugin.logger != null)
            {
                keePassRPCPlugin.logger.WriteLine("Server certificate has private key? " + _serverCertificate.HasPrivateKey);
            }

            try
            {
                this._tcpListener  = new TcpListener(IPAddress.Loopback, port);
                this._listenThread = new Thread(new ThreadStart(ListenForClients));
                this._listenThread.Start();
                this._isListening = true; // just in case the main thread checks
                // for successful startup before the thread has got going.
            }
            catch (Exception e)
            {
                if (keePassRPCPlugin.logger != null)
                {
                    keePassRPCPlugin.logger.WriteLine("Failed to start TCP listener: " + e.ToString());
                }
            }
            if (keePassRPCPlugin.logger != null)
            {
                keePassRPCPlugin.logger.WriteLine("Started KPRPCServer");
            }
        }
Ejemplo n.º 19
0
        /// <summary>
        /// Generates an X509 certificate using the Mono.Security assembly.
        /// Potentially could prise out the relevant classes from the Mono
        /// source code in order to reduce plgx size and complexity... one day
        /// </summary>
        /// <param name="subject">The subject.</param>
        /// <param name="issuer">The issuer.</param>
        /// <returns></returns>
        public static PKCS12 Generate(string subject, string issuer, string password, KeePassRPCExt KeePassRPCPlugin)
        {
            byte[] sn = Guid.NewGuid().ToByteArray();
            DateTime notBefore = DateTime.Now;
            DateTime notAfter = new DateTime(643445675990000000); // 12/31/2039 23:59:59Z
            subject = "CN=" + subject;
            issuer = "CN=" + issuer;
            RSA subjectKey = (RSA)RSA.Create();
            RSA issuerKey = (RSA)RSA.Create();
            subjectKey.KeySize = 2048;
            issuerKey.KeySize = 2048;

            string hashName = "SHA1";

            CspParameters subjectParams = new CspParameters();
            CspParameters issuerParams = new CspParameters();

            // serial number MUST be positive
            if ((sn[0] & 0x80) == 0x80)
                sn[0] -= 0x80;

            //issuer = subject;
            //RSA issuerKey = subjectKey;

            if (subject == null)
                throw new Exception("Missing Subject Name");

            X509CertificateBuilder cb = new X509CertificateBuilder(3);
            cb.SerialNumber = sn;
            cb.IssuerName = issuer;
            cb.NotBefore = notBefore;
            cb.NotAfter = notAfter;
            cb.SubjectName = subject;
            cb.SubjectPublicKey = subjectKey;
            cb.Hash = hashName;

            //X509 extensions
            KeyUsageExtension keyUsage = new KeyUsageExtension();
            keyUsage.KeyUsage = KeyUsages.keyEncipherment | KeyUsages.digitalSignature;
            cb.Extensions.Add(keyUsage);

            ExtendedKeyUsageExtension extendedKeyUsage = new ExtendedKeyUsageExtension();
            extendedKeyUsage.KeyPurpose.Add("1.3.6.1.5.5.7.3.1");
            cb.Extensions.Add(extendedKeyUsage);
            byte[] rawcert = cb.Sign(issuerKey);

            PKCS12 p12 = new PKCS12();
            p12.Password = password;

            ArrayList list = new ArrayList();
            // we use a fixed array to avoid endianess issues
            // (in case some tools requires the ID to be 1).
            list.Add(new byte[4] { 1, 0, 0, 0 });
            Hashtable attributes = new Hashtable(1);
            attributes.Add(PKCS9.localKeyId, list);

            p12.AddCertificate(new X509Certificate(rawcert), attributes);
            p12.AddPkcs8ShroudedKeyBag(subjectKey, attributes);

            /*
            if (Type.GetType("Mono.Runtime") != null)
            {
                string fileName = Path.Combine(Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), "KeePassRPC"), "cert.p12");
                if (KeePassRPCPlugin.logger != null) KeePassRPCPlugin.logger.WriteLine(fileName);
                try
                {
                    p12.SaveToFile(fileName);
                }
                catch (Exception)
                {
                    if (KeePassRPCPlugin.logger != null) KeePassRPCPlugin.logger.WriteLine("Could not write to " + fileName + " security between KPRPC and clients may not be established.");
                }
            }

            return p12.GetBytes();
            */
            return p12;
        }
Ejemplo n.º 20
0
        /// <summary>
        /// Starts the web socket listener and also
        /// establishes the SSL certificate we will use for legacy communication with
        /// RPC clients and starts a seperate thread to listen for legacy connections
        /// </summary>
        /// <param name="port">port to listen on</param>
        /// <param name="service">The KeePassRPCService the server should interact with.</param>
        public KeePassRPCServer(int port, KeePassRPCService service, KeePassRPCExt keePassRPCPlugin, bool useSSL, int webSocketPort)
        {
            _useSSL = useSSL;
            if (keePassRPCPlugin.logger != null) keePassRPCPlugin.logger.WriteLine("Starting KPRPCServer");
            Service = service;
            KeePassRPCPlugin = keePassRPCPlugin;
            activeClientThreads = new List<Thread>();

            // We set up the new web socket server first and then the legacy connection system.
            // KeeFox 1.3+ will connect to the webSocket server first provided that the upgrade has happened...
            /*
             * KF 1.3 checks for KPRPC.plgx, determines KPRPC is installed and tries to connect on websock
             * If success, move on to srp auth
             * If fail, try to connect to ssl port
             * if success, will find one of two situations:
             * 1) old version of KPRPC is running <1.3: Display standard KPRPC setup uprgade notice
             * 2) this version of KPRPC is running but firewalls or port misconfiguration is preventing websocket
             * from working: send a new category of auth failure (assuming client v is 1.3+) message to help user with the upgrade problems
             */
            StartWebsockServer(webSocketPort);

            if (_useSSL)
            {
            //                if (true)
                if (Type.GetType("Mono.Runtime") == null)
                {
                    _store = new System.Security.Cryptography.X509Certificates.X509Store();
                    _store.Open(OpenFlags.ReadWrite);

                    // Find any certificates in this user's certificate store and re-use
                    // them rather than suffer the overhead of creating an entirly new
                    // certificate. Our certificates are considered "invalid" by the
                    // store (probably becuase they are self-signed)
                    X509Certificate2Collection matchingCertificates = _store.Certificates
                        .Find(X509FindType.FindBySubjectDistinguishedName,
                            "CN=KeePassRPC certificate for " + Environment.MachineName, false);

                    //foreach (X509Certificate2 temp in matchingCertificates)
                    //    _store.Remove(temp);

                    //matchingCertificates = _store.Certificates
                    //    .Find(X509FindType.FindBySubjectDistinguishedName,
                    //        "CN=KeePassRPC TLS aaa for " + Environment.MachineName, false);

                    if (keePassRPCPlugin.logger != null) keePassRPCPlugin.logger.WriteLine("Matching certificates from store: " + matchingCertificates.Count);
                    if (matchingCertificates.Count > 0)
                        _serverCertificate = matchingCertificates[0];
                    else
                    {
                        //_serverCertificate = (X509Certificate2)X509Certificate2.CreateFromCertFile(Path.Combine(Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), "KeePassRPC"), "cert.p12"));

                        if (keePassRPCPlugin.logger != null) keePassRPCPlugin.logger.WriteLine("Generating new certificate (MS).");
                        // We can use the MakeCert feature from Mono to generate a new
                        // certificate for use by this user on this machine. This means
                        // that every KeePassRPC user will establish TLS connections
                        // that are protected by a private key held on their own
                        // system, rather than a key that is disclosed in this open
                        // source code. NB: The local server is assumed to be secure!
                        PKCS12 p12 = MakeCertKPRPC.Generate("KeePassRPC certificate for " + Environment.MachineName, "KeePassRPC Automated Self-Signed Key Generator", keePassRPCPlugin);
                        byte[] cert = p12.GetBytes();
                        _serverCertificate = new X509Certificate2(cert, (string)null, X509KeyStorageFlags.PersistKeySet);
                        _store.Add(_serverCertificate);
                    }
                }
                else
                {
                    /*
                     * Problem 1:
                     *   For Linux/Mono, we cannot use the X509Store. It appears that only a .cer file is saved. That certificate does not include
                     *   the private key that we need for SSL. So we will need to save the key ourselves.
                     *
                     * Problem 2:
                     *   When using PKCS12 SaveToFile to save the key ourselves, it appears that it is not possible to save a private key that is not
                     *   password protected.
                     *
                     */
                    string certdir = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), "KeePassRPC");
                    string certfile = Path.Combine(certdir, "cert.p12");
                    _serverCertificate = null;

                    // Check if cert directory exists, if not, we need to create it
                    if (!System.IO.Directory.Exists(certdir))
                    {
                        if (keePassRPCPlugin.logger != null) keePassRPCPlugin.logger.WriteLine("Cert directory does not exist, creating "+certdir);

                        System.IO.Directory.CreateDirectory(certdir);

                        if (keePassRPCPlugin.logger != null) keePassRPCPlugin.logger.WriteLine("Cert directory created");
                    }
                    else
                    {
                        // Attempt to load cert
                        try {
                            if (keePassRPCPlugin.logger != null) keePassRPCPlugin.logger.WriteLine("Looking for existing certificate (Mono)");
                            _serverCertificate = new X509Certificate2();
                            _serverCertificate.Import (certfile, pkcs12_password, X509KeyStorageFlags.PersistKeySet);
                            if (keePassRPCPlugin.logger != null) keePassRPCPlugin.logger.WriteLine("Existing certificate loaded(Mono) : "+certfile);
                        }
                        catch (Exception ex) {
                            _serverCertificate = null;
                        }
                    }
                    // If we didn't load a cert, create one and save it
                    if (_serverCertificate == null)
                    {
                        if (keePassRPCPlugin.logger != null) keePassRPCPlugin.logger.WriteLine("Generating new certificate (Mono).");

                        PKCS12 p12 = MakeCertKPRPC.Generate("KeePassRPC certificate for " + Environment.MachineName, "KeePassRPC Automated Self-Signed Key Generator", pkcs12_password, keePassRPCPlugin);
                        p12.SaveToFile(certfile);
                        byte[] cert = p12.GetBytes();
                        _serverCertificate = new X509Certificate2(cert, pkcs12_password, X509KeyStorageFlags.PersistKeySet);
                        if (keePassRPCPlugin.logger != null) keePassRPCPlugin.logger.WriteLine("Generated new certificate (Mono) : "+certfile);
                    }
                }
            }

               if (keePassRPCPlugin.logger != null) keePassRPCPlugin.logger.WriteLine("Server certificate has private key? " + _serverCertificate.HasPrivateKey);

            try
            {
                this._tcpListener =  new TcpListener(IPAddress.Loopback, port);
                this._listenThread = new Thread(new ThreadStart(ListenForClients));
                this._listenThread.Name = "KeePassRPCServer._listenThread";
                this._listenThread.Start();
                this._isListening = true; // just in case the main thread checks
                    // for successful startup before the thread has got going.
            }
            catch (Exception e)
            {
                if (keePassRPCPlugin.logger != null) keePassRPCPlugin.logger.WriteLine("Failed to start TCP listener: " + e.ToString());
            }
            if (keePassRPCPlugin.logger != null) keePassRPCPlugin.logger.WriteLine("Started KPRPCServer");
        }
Ejemplo n.º 21
0
        /// <summary>
        /// Establishes the SSL certificate we will use for communication with
        /// RPC clients and starts a seperate thread to listen for connections
        /// </summary>
        /// <param name="port">port to listen on</param>
        /// <param name="service">The KeePassRPCService the server should interact with.</param>
        public KeePassRPCServer(int port, KeePassRPCService service, KeePassRPCExt keePassRPCPlugin, bool useSSL)
        {
            _useSSL = useSSL;
            if (keePassRPCPlugin.logger != null)
            {
                keePassRPCPlugin.logger.WriteLine("Starting KPRPCServer");
            }
            Service          = service;
            KeePassRPCPlugin = keePassRPCPlugin;

            if (_useSSL)
            {
                if (Type.GetType("Mono.Runtime") == null)
                {
                    _store = new X509Store();
                    _store.Open(OpenFlags.ReadWrite);

                    // Find any certificates in this user's certificate store and re-use
                    // them rather than suffer the overhead of creating an entirly new
                    // certificate. Our certificates are considered "invalid" by the
                    // store (probably becuase they are self-signed)
                    X509Certificate2Collection matchingCertificates = _store.Certificates
                                                                      .Find(X509FindType.FindBySubjectDistinguishedName,
                                                                            "CN=KeePassRPC certificate for " + Environment.MachineName, false);

                    //foreach (X509Certificate2 temp in matchingCertificates)
                    //    _store.Remove(temp);

                    //matchingCertificates = _store.Certificates
                    //    .Find(X509FindType.FindBySubjectDistinguishedName,
                    //        "CN=KeePassRPC TLS aaa for " + Environment.MachineName, false);

                    if (keePassRPCPlugin.logger != null)
                    {
                        keePassRPCPlugin.logger.WriteLine("Matching certificates from store: " + matchingCertificates.Count);
                    }
                    if (matchingCertificates.Count > 0)
                    {
                        _serverCertificate = matchingCertificates[0];
                    }
                    else
                    {
                        //_serverCertificate = (X509Certificate2)X509Certificate2.CreateFromCertFile(Path.Combine(Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), "KeePassRPC"), "cert.p12"));

                        if (keePassRPCPlugin.logger != null)
                        {
                            keePassRPCPlugin.logger.WriteLine("Generating new certificate (MS).");
                        }
                        // We can use the MakeCert feature from Mono to generate a new
                        // certificate for use by this user on this machine. This means
                        // that every KeePassRPC user will establish TLS connections
                        // that are protected by a private key held on their own
                        // system, rather than a key that is disclosed in this open
                        // source code. NB: The local server is assumed to be secure!
                        byte[] cert = MakeCertKPRPC.Generate("KeePassRPC certificate for " + Environment.MachineName, "KeePassRPC Automated Self-Signed Key Generator", keePassRPCPlugin);
                        _serverCertificate = new X509Certificate2(cert, (string)null, X509KeyStorageFlags.PersistKeySet);
                        _store.Add(_serverCertificate);
                    }
                }
                else
                {
                    if (keePassRPCPlugin.logger != null)
                    {
                        keePassRPCPlugin.logger.WriteLine("Looking for existing certificate (Mono)");
                    }

                    _serverCertificate = (X509Certificate2)X509Certificate2.CreateFromCertFile(Path.Combine(Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), "KeePassRPC"), "cert.p12"));

                    if (_serverCertificate == null)
                    {
                        if (keePassRPCPlugin.logger != null)
                        {
                            keePassRPCPlugin.logger.WriteLine("Generating new certificate (Mono).");
                        }

                        MakeCertKPRPC.Generate("KeePassRPC certificate for " + Environment.MachineName, "KeePassRPC Automated Self-Signed Key Generator", keePassRPCPlugin);
                        _serverCertificate = (X509Certificate2)X509Certificate2.CreateFromCertFile(Path.Combine(Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), "KeePassRPC"), "cert.p12"));
                    }
                }
            }
            if (keePassRPCPlugin.logger != null)
            {
                keePassRPCPlugin.logger.WriteLine("Server certificate has private key? " + _serverCertificate.HasPrivateKey);
            }

            try
            {
                this._tcpListener  = new TcpListener(IPAddress.Loopback, port);
                this._listenThread = new Thread(new ThreadStart(ListenForClients));
                this._listenThread.Start();
                this._isListening = true; // just in case the main thread checks
                // for successful startup before the thread has got going.
            }
            catch (Exception e)
            {
                if (keePassRPCPlugin.logger != null)
                {
                    keePassRPCPlugin.logger.WriteLine("Failed to start TCP listener: " + e.ToString());
                }
            }
            if (keePassRPCPlugin.logger != null)
            {
                keePassRPCPlugin.logger.WriteLine("Started KPRPCServer");
            }
        }
Ejemplo n.º 22
0
        public KeePassRPCClientConnection(IWebSocketConnection connection, bool isAuthorised, KeePassRPCExt kprpc)
        {
            WebSocketConnection = connection;
            Authorised          = isAuthorised;

            //TODO2: Can we lazy load these since some sessions will require only one of these authentication mechanisms?
            _srp = new SRP();
            Kcp  = new KeyChallengeResponse(ProtocolVersion);

            // Load from config, default to medium security if user has not yet requested anything different
            securityLevel = (int)kprpc._host.CustomConfig.GetLong("KeePassRPC.SecurityLevel", 2);
            securityLevelClientMinimum = (int)kprpc._host.CustomConfig.GetLong("KeePassRPC.SecurityLevelClientMinimum", 2);
            KPRPC = kprpc;
        }