private void RefreshToken()
        {
            try
            {
                if (_token == null)
                {
                    using (var web = CreateJsonRestClient(_proxy, HOST_AUTH))
                    {
                        web.AddHeader("X-Simperium-API-Key", API_KEY);
                        web.SetEscapeAllNonASCIICharacters(true);

                        _logger.Debug(SimpleNotePlugin.Name, "Requesting token from Simplenote server");
                        _token = SimpleNoteAPI.Authenticate(web, _config.Username, _config.Password);
                        _logger.Debug(SimpleNotePlugin.Name, "Simplenote server returned token for user " + _token.userid);
                    }
                }
            }
            catch (RestException)
            {
                throw;
            }
            catch (Exception e)
            {
                throw new Exception("Could not authenticate with SimpleNote server : " + e.Message, e);
            }
        }
Beispiel #2
0
        private void RefreshToken()
        {
            try
            {
                if (_token == null)
                {
                    using (var web = CreateJsonRestClient(_proxy, _config.Server))
                    {
                        _logger.Debug(StandardNotePlugin.Name, "Requesting token from StandardNoteServer");

                        _token = StandardNoteAPI.Authenticate(web, _config.Email, _config.Password, _logger);

                        _logger.Debug(StandardNotePlugin.Name, "StandardNoteServer returned token for user " + _token.user.uuid);
                    }
                }
            }
            catch (StandardNoteAPIException)
            {
                throw;
            }
            catch (RestException)
            {
                throw;
            }
            catch (Exception e)
            {
                throw new StandardNoteAPIException("Could not authenticate with StandardNoteServer : " + e.Message, e);
            }
        }
        public override void StartSync(IRemoteStorageSyncPersistance data, List <INote> localnotes, List <INote> localdeletednotes)
        {
            _syncScan = FileSystemUtil
                        .EnumerateFilesDeep(_config.Folder, _config.SearchDepth)
                        .Where(p => (Path.GetExtension(p) ?? "").ToLower() == "." + _config.Extension.ToLower())
                        .ToList();

            _logger.Debug(FilesystemPlugin.Name, string.Format("Found {0} note files in directory scan", _syncScan.Count));
        }
Beispiel #4
0
        private static APIResultAuthorize Authenticate003(ISimpleJsonRest web, APIAuthParams apiparams, string mail, string uip, IAlephLogger logger)
        {
            try
            {
                logger.Debug(StandardNotePlugin.Name, $"AutParams[version:{apiparams.version}, pw_cost:{apiparams.pw_cost}, pw_nonce:{apiparams.pw_nonce}]");

                if (apiparams.pw_cost < 100000)
                {
                    throw new StandardNoteAPIException($"Account pw_cost is too small ({apiparams.pw_cost})");
                }

                var    salt  = StandardNoteCrypt.SHA256(string.Join(":", mail, "SF", "003", apiparams.pw_cost.ToString(), apiparams.pw_nonce));
                byte[] bytes = PBKDF2.GenerateDerivedKey(768 / 8, Encoding.UTF8.GetBytes(uip), Encoding.UTF8.GetBytes(salt), apiparams.pw_cost, PBKDF2.HMACType.SHA512);

                var pw = bytes.Skip(0 * (bytes.Length / 3)).Take(bytes.Length / 3).ToArray();
                var mk = bytes.Skip(1 * (bytes.Length / 3)).Take(bytes.Length / 3).ToArray();
                var ak = bytes.Skip(2 * (bytes.Length / 3)).Take(bytes.Length / 3).ToArray();

                var reqpw = EncodingConverter.ByteToHexBitFiddleUppercase(pw).ToLower();
                APIResultAuthorize tok;
                try
                {
                    tok = web.PostTwoWay <APIResultAuthorize>(new APIRequestUser {
                        email = mail, password = reqpw
                    }, "auth/sign_in");
                }
                catch (RestStatuscodeException e1)
                {
                    if (e1.StatusCode / 100 == 4 && !string.IsNullOrWhiteSpace(e1.HTTPContent))
                    {
                        var req = web.ParseJsonOrNull <APIBadRequest>(e1.HTTPContent);
                        if (req != null)
                        {
                            throw new StandardNoteAPIException($"Server returned status {e1.StatusCode}.\nMessage: '{req.error.message}'", e1);
                        }
                    }

                    throw;
                }

                tok.masterkey     = mk;
                tok.masterauthkey = ak;
                tok.version       = "003";
                return(tok);
            }
            catch (RestException)
            {
                throw;
            }
            catch (StandardNoteAPIException)
            {
                throw;
            }
            catch (Exception e)
            {
                throw new StandardNoteAPIException("Authentification with StandardNoteAPI failed.", e);
            }
        }
        public override void StartSync(IRemoteStorageSyncPersistance data, List <INote> localnotes, List <INote> localdeletednotes)
        {
            _data = (NextcloudData)data;

            using (var web = CreateAuthenticatedClient())
            {
                remoteNotes = NextcloudAPI.ListNotes(web);

                _logger.Debug(NextcloudPlugin.Name, string.Format("NextcloudAPI.ListNotes returned {0} elements", remoteNotes.Count));
            }
        }
        public override void StartSync(IRemoteStorageSyncPersistance data, List <INote> localnotes, List <INote> localdeletednotes)
        {
            _data = (EvernoteData)data;

            RefreshToken();

            TTransport noteStoreTransport = new THttpClient(new Uri(@"https://sandbox.evernote.com/shard/s1/notestore"));            //TODO use url from OAuth
            TProtocol  noteStoreProtocol  = new TBinaryProtocol(noteStoreTransport);

            nsClient = new NoteStore.Client(noteStoreProtocol);

            var state = nsClient.getSyncState(_token);

            if (_data.SyncStateUpdateCount != state.UpdateCount)
            {
                _logger.Debug(EvernotePlugin.Name, string.Format("Remote has changed SyncState: {0} -> '{1}'", _data.SyncStateUpdateCount, state.UpdateCount));

                NoteFilter filter = new NoteFilter();
                filter.Order = (int)NoteSortOrder.UPDATED;

                NotesMetadataResultSpec spec = new NotesMetadataResultSpec();
                spec.IncludeUpdateSequenceNum = true;

                bucket = nsClient.findNotesMetadata(_token, filter, 0, 9999, spec);

                _data.SyncStateUpdateCount = state.UpdateCount;
            }
            else
            {
                _logger.Debug(EvernotePlugin.Name, "Remote has not changed - no need for download - SyncState := " + state.UpdateCount);

                bucket = null;
            }

            remoteDirty = false;
        }
        public static void DeleteDirectoryWithRetry(IAlephLogger logger, string path)
        {
            for (int i = 0; i < 5; i++)
            {
                try
                {
                    Directory.Delete(path);
                    return;
                }
                catch (IOException e)
                {
                    logger.Debug("DeleteDirectoryWithRetry", "Retry Directory delete", "Retry directory delete, exception thrown:\r\n" + e);
                    Thread.Sleep(5);
                }
            }

            Directory.Delete(path);             // Do it again and throw Exception if it fails
        }
Beispiel #8
0
        public static void DeleteFolderIfEmpty(string logsrc, IAlephLogger log, string baseFolder, string folder)
        {
            var p1 = Path.GetFullPath(baseFolder).TrimEnd(Path.DirectorySeparatorChar).ToLower();
            var p2 = Path.GetFullPath(folder).TrimEnd(Path.DirectorySeparatorChar).ToLower();

            if (p1 == p2)
            {
                return;
            }
            if (p1.Count(c => c == Path.DirectorySeparatorChar) >= p2.Count(c => c == Path.DirectorySeparatorChar))
            {
                return;
            }

            if (Directory.EnumerateFileSystemEntries(folder).Any())
            {
                return;
            }

            log.Debug(logsrc, $"Cleanup empty folder '{p2}' (base = '{p1}')");
            Directory.Delete(folder);
        }
Beispiel #9
0
        private static APIResultAuthorize Authenticate001(ISimpleJsonRest web, APIAuthParams apiparams, string mail, string password, IAlephLogger logger)
        {
            try
            {
                logger.Debug(StandardNotePlugin.Name, $"AuthParams[version:1, pw_func:{apiparams.pw_func}, pw_alg:{apiparams.pw_alg}, pw_cost:{apiparams.pw_cost}, pw_key_size:{apiparams.pw_key_size}]");

                if (apiparams.pw_func != PasswordFunc.pbkdf2)
                {
                    throw new Exception("Unsupported pw_func: " + apiparams.pw_func);
                }

                byte[] bytes;

                if (apiparams.pw_alg == PasswordAlg.sha512)
                {
                    bytes = PBKDF2.GenerateDerivedKey(apiparams.pw_key_size / 8, Encoding.UTF8.GetBytes(password), Encoding.UTF8.GetBytes(apiparams.pw_salt), apiparams.pw_cost, PBKDF2.HMACType.SHA512);
                }
                else if (apiparams.pw_alg == PasswordAlg.sha512)
                {
                    bytes = PBKDF2.GenerateDerivedKey(apiparams.pw_key_size / 8, Encoding.UTF8.GetBytes(password), Encoding.UTF8.GetBytes(apiparams.pw_salt), apiparams.pw_cost, PBKDF2.HMACType.SHA512);
                }
                else
                {
                    throw new Exception("Unknown pw_alg: " + apiparams.pw_alg);
                }

                var pw = bytes.Take(bytes.Length / 2).ToArray();
                var mk = bytes.Skip(bytes.Length / 2).ToArray();

                var reqpw = EncodingConverter.ByteToHexBitFiddleUppercase(pw).ToLower();

                APIResultAuthorize tok;
                try
                {
                    tok = web.PostDownload <APIResultAuthorize>("auth/sign_in", "email=" + mail, "password="******"Server returned status {e1.StatusCode}.\nMessage: '{req.error.message}'", e1);
                        }
                    }

                    throw;
                }

                tok.masterkey = mk;
                tok.version   = "001";
                return(tok);
            }
            catch (StandardNoteAPIException)
            {
                throw;
            }
            catch (Exception e)
            {
                throw new StandardNoteAPIException("Authentification with StandardNoteAPI failed.", e);
            }
        }
Beispiel #10
0
        private static StandardFileNote CreateNote(ISimpleJsonRest web, StandardNoteConnection conn, APIResultItem encNote, APIResultAuthorize authToken, StandardNoteConfig cfg, StandardNoteData dat)
        {
            if (encNote.deleted)
            {
                var nd = new StandardFileNote(encNote.uuid, cfg, conn.HConfig)
                {
                    CreationDate   = encNote.created_at,
                    Text           = "",
                    InternalTitle  = "",
                    AuthHash       = encNote.auth_hash,
                    ContentVersion = StandardNoteCrypt.GetSchemaVersion(encNote.content),
                };
                nd.ModificationDate = encNote.updated_at;
                return(nd);
            }

            ContentNote content;

            try
            {
                var contentJson = StandardNoteCrypt.DecryptContent(encNote.content, encNote.enc_item_key, encNote.auth_hash, authToken.masterkey, authToken.masterauthkey);

                Logger.Debug(
                    StandardNotePlugin.Name,
                    $"DecryptContent of note {encNote.uuid:B}",
                    $"[content]:\r\n{encNote.content}\r\n" +
                    $"[enc_item_key]:\r\n{encNote.enc_item_key}\r\n" +
                    $"[auth_hash]:\r\n{encNote.auth_hash}\r\n" +
                    $"\r\n\r\n" +
                    $"[contentJson]:\r\n{contentJson}\r\n");

                content = web.ParseJsonWithoutConverter <ContentNote>(contentJson);
            }
            catch (RestException)
            {
                throw;
            }
            catch (Exception e)
            {
                throw new StandardNoteAPIException("Cannot decrypt note with local masterkey", e);
            }

            var n = new StandardFileNote(encNote.uuid, cfg, conn.HConfig)
            {
                Text           = content.text,
                InternalTitle  = content.title,
                AuthHash       = encNote.auth_hash,
                ContentVersion = StandardNoteCrypt.GetSchemaVersion(encNote.content),
                IsPinned       = GetAppDataBool(content.appData, "org.standardnotes.sn", "pinned", false),
            };

            var refTags = new List <StandardFileTag>();

            foreach (var cref in content.references)
            {
                if (cref.content_type == "Note")
                {
                    // ignore
                }
                else if (dat.Tags.Any(t => t.UUID == cref.uuid))
                {
                    refTags.Add(new StandardFileTag(cref.uuid, dat.Tags.First(t => t.UUID == cref.uuid).Title));
                }
                else if (cref.content_type == "Tag")
                {
                    Logger.Warn(StandardNotePlugin.Name, $"Reference to missing tag {cref.uuid} in note {encNote.uuid}");
                }
                else
                {
                    Logger.Error(StandardNotePlugin.Name, $"Downloaded note contains an unknown reference :{cref.uuid} ({cref.content_type}) in note {encNote.uuid}");
                }
            }

            n.SetTags(refTags);
            n.SetReferences(content.references);
            n.CreationDate     = encNote.created_at;
            n.ModificationDate = encNote.updated_at;

            return(n);
        }