예제 #1
0
        /// <summary>
        /// Instantiates <see cref="VaultData"/> instance.
        /// </summary>
        /// <param name="clientKey"><see cref="IKeeperStorage"/> encryption key.</param>
        /// <param name="storage">Vault storage.</param>
        public VaultData(byte[] clientKey, IKeeperStorage storage)
        {
            ClientKey = clientKey;
            Storage   = storage;

            rootFolder = new FolderNode
            {
                FolderUid  = "",
                Name       = "My Vault",
                FolderType = FolderType.UserFolder
            };
        }
예제 #2
0
 public bool TryGetFolder(string folderUid, out FolderNode node)
 {
     return(keeperFolders.TryGetValue(folderUid, out node));
 }
예제 #3
0
        internal void BuildFolders()
        {
            var folderMap = new Dictionary <string, IFolder>();

            foreach (var folder in Storage.Folders.GetAll())
            {
                folderMap[folder.FolderUid] = folder;
            }
            var uids = new HashSet <string>();

            // check shared folder exists.
            foreach (var folder in folderMap.Values)
            {
                if (folder.FolderType == "user_folder")
                {
                    continue;
                }
                if (string.IsNullOrEmpty(folder.SharedFolderUid))
                {
                    continue;
                }

                if (!keeperSharedFolders.ContainsKey(folder.SharedFolderUid))
                {
                    uids.Add(folder.FolderUid);
                }
            }

            if (uids.Count > 0)
            {
                Storage.FolderRecords.DeleteLinksForObjects(uids);
                Storage.Folders.DeleteUids(uids);
                foreach (var folderUid in uids)
                {
                    folderMap.Remove(folderUid);
                }
            }

            keeperFolders.Clear();
            rootFolder.Records.Clear();
            rootFolder.Subfolders.Clear();
            foreach (var folder in folderMap.Values)
            {
                var node = new FolderNode
                {
                    FolderUid = folder.FolderUid,
                    ParentUid = folder.ParentUid
                };
                try
                {
                    byte[] data = null;
                    if (folder.FolderType == "user_folder")
                    {
                        node.FolderType = FolderType.UserFolder;
                        var key = CryptoUtils.DecryptAesV1(folder.FolderKey.Base64UrlDecode(), ClientKey);
                        data = CryptoUtils.DecryptAesV1(folder.Data.Base64UrlDecode(), key);
                    }
                    else
                    {
                        node.SharedFolderUid = folder.SharedFolderUid;
                        node.FolderType      = folder.FolderType == "shared_folder_folder"
                            ? FolderType.SharedFolderFolder
                            : FolderType.SharedFolder;
                        if (keeperSharedFolders.TryGetValue(folder.SharedFolderUid, out var sf))
                        {
                            if (node.FolderType == FolderType.SharedFolderFolder)
                            {
                                if (string.IsNullOrEmpty(node.ParentUid))
                                {
                                    node.ParentUid = node.SharedFolderUid;
                                }

                                var key = CryptoUtils.DecryptAesV1(folder.FolderKey.Base64UrlDecode(),
                                                                   sf.SharedFolderKey);
                                data = CryptoUtils.DecryptAesV1(folder.Data.Base64UrlDecode(), key);
                            }
                            else
                            {
                                node.Name = sf.Name;
                            }
                        }
                        else
                        {
                            Trace.TraceError(
                                $"Missing Shared Folder UID {folder.SharedFolderUid} for Folder UID {folder.FolderUid}");
                        }
                    }

                    if (data != null)
                    {
                        var serializer = new DataContractJsonSerializer(typeof(FolderData));
                        using (var stream = new MemoryStream(data))
                        {
                            var folderData = serializer.ReadObject(stream) as FolderData;
                            node.Name = folderData?.name;
                        }
                    }
                }
                catch (Exception e)
                {
                    Trace.TraceError(e.Message);
                }

                if (string.IsNullOrEmpty(node.Name))
                {
                    node.Name = node.FolderUid;
                }

                keeperFolders.TryAdd(node.FolderUid, node);
            }

            foreach (var folderUid in keeperFolders.Keys)
            {
                if (keeperFolders.TryGetValue(folderUid, out FolderNode node))
                {
                    FolderNode parent;

                    if (string.IsNullOrEmpty(node.ParentUid))
                    {
                        parent = rootFolder;
                    }
                    else
                    {
                        if (!keeperFolders.TryGetValue(node.ParentUid, out parent))
                        {
                            parent = rootFolder;
                        }
                    }

                    parent.Subfolders.Add(folderUid);
                }
            }

            foreach (var link in Storage.FolderRecords.GetAllLinks())
            {
                FolderNode node;
                if (string.IsNullOrEmpty(link.FolderUid))
                {
                    node = rootFolder;
                }
                else
                {
                    if (!keeperFolders.TryGetValue(link.FolderUid, out node))
                    {
                        node = rootFolder;
                    }
                }

                node.Records.Add(link.RecordUid);
            }
        }
        public static async Task <PasswordRecord> AddRecordToFolder(this VaultOnline vault, PasswordRecord record, string folderUid = null)
        {
            FolderNode node = null;

            if (!string.IsNullOrEmpty(folderUid))
            {
                vault.TryGetFolder(folderUid, out node);
            }

            record.Uid       = CryptoUtils.GenerateUid();
            record.RecordKey = CryptoUtils.GenerateEncryptionKey();
            var recordAdd = new RecordAddCommand
            {
                RecordUid  = record.Uid,
                RecordKey  = CryptoUtils.EncryptAesV1(record.RecordKey, vault.Auth.AuthContext.DataKey).Base64UrlEncode(),
                RecordType = "password"
            };

            if (node == null)
            {
                recordAdd.FolderType = "user_folder";
            }
            else
            {
                switch (node.FolderType)
                {
                case FolderType.UserFolder:
                    recordAdd.FolderType = "user_folder";
                    recordAdd.FolderUid  = node.FolderUid;
                    break;

                case FolderType.SharedFolder:
                case FolderType.SharedFolderFolder:
                    recordAdd.FolderUid  = node.FolderUid;
                    recordAdd.FolderType = node.FolderType == FolderType.SharedFolder
                            ? "shared_folder"
                            : "shared_folder_folder";
                    if (vault.TryGetSharedFolder(node.SharedFolderUid, out var sf))
                    {
                        recordAdd.FolderKey = CryptoUtils.EncryptAesV1(record.RecordKey, sf.SharedFolderKey)
                                              .Base64UrlEncode();
                    }

                    if (string.IsNullOrEmpty(recordAdd.FolderKey))
                    {
                        throw new Exception($"Cannot resolve shared folder for folder UID: {folderUid}");
                    }

                    break;
                }
            }

            var dataSerializer = new DataContractJsonSerializer(typeof(RecordData), JsonUtils.JsonSettings);
            var data           = record.ExtractRecordData();

            using (var ms = new MemoryStream())
            {
                dataSerializer.WriteObject(ms, data);
                recordAdd.Data = CryptoUtils.EncryptAesV1(ms.ToArray(), record.RecordKey).Base64UrlEncode();
            }

            await vault.Auth.ExecuteAuthCommand(recordAdd);

            await vault.ScheduleSyncDown(TimeSpan.FromSeconds(0));

            return(vault.TryGetRecord(record.Uid, out var r) ? r : record);
        }