Пример #1
0
        /// <summary>
        /// Sends a broadcast to all potential plugins prompting them to request access to our app.
        /// </summary>
        public static void TriggerRequests(Context ctx)
        {
            PluginDatabase pluginDatabase = new PluginDatabase(ctx);

            foreach (string pkg in GetAllPlugins(ctx))
            {
                TriggerRequest(ctx, pkg, pluginDatabase);
            }
        }
Пример #2
0
        public static void TriggerRequest(Context ctx, string pkgName, PluginDatabase pluginDatabase)
        {
            try
            {
                Intent triggerIntent = new Intent(Strings.ActionTriggerRequestAccess);
                triggerIntent.SetPackage(pkgName);
                triggerIntent.PutExtra(Strings.ExtraSender, ctx.PackageName);

                triggerIntent.PutExtra(Strings.ExtraRequestToken, pluginDatabase.GetRequestToken(pkgName));
                ctx.SendBroadcast(triggerIntent);
            }
            catch (Exception e)
            {
            }
        }
        public static void TriggerRequest(Context ctx, string pkgName, PluginDatabase pluginDatabase)
        {
            try
            {
                Intent triggerIntent = new Intent(Strings.ActionTriggerRequestAccess);
                triggerIntent.SetPackage(pkgName);
                triggerIntent.PutExtra(Strings.ExtraSender, ctx.PackageName);

                triggerIntent.PutExtra(Strings.ExtraRequestToken, pluginDatabase.GetRequestToken(pkgName));
                ctx.SendBroadcast(triggerIntent);
            }
            catch (Exception e)
            {
            }
        }
Пример #4
0
 public static void TriggerRequest(Context ctx, string pkgName, PluginDatabase pluginDatabase)
 {
     try
     {
         Intent triggerIntent = new Intent(Strings.ActionTriggerRequestAccess);
         triggerIntent.SetPackage(pkgName);
         triggerIntent.PutExtra(Strings.ExtraSender, ctx.PackageName);
         string requestToken = pluginDatabase.GetRequestToken(pkgName);
         triggerIntent.PutExtra(Strings.ExtraRequestToken, requestToken);
         Android.Util.Log.Debug(_tag, "Request token: " + requestToken);
         ctx.SendBroadcast(triggerIntent);
     }
     catch (Exception e)
     {
     }
 }
Пример #5
0
 public static void TriggerRequest(Context ctx, string pkgName, PluginDatabase pluginDatabase)
 {
     try
     {
         Intent triggerIntent = new Intent(Strings.ActionTriggerRequestAccess);
         triggerIntent.SetPackage(pkgName);
         triggerIntent.PutExtra(Strings.ExtraSender, ctx.PackageName);
         string requestToken = pluginDatabase.GetRequestToken(pkgName);
         triggerIntent.PutExtra(Strings.ExtraRequestToken, requestToken);
         Android.Util.Log.Debug(_tag, "Request token: " + requestToken);
         ctx.SendBroadcast(triggerIntent);
     }
     catch (Exception e)
     {
     }
 }
Пример #6
0
        protected override void OnResume()
        {
            base.OnResume();
            PluginDatabase pluginDb = new PluginDatabase(this);

            _items = (from pluginPackage in pluginDb.GetAllPluginPackages()
                      let version = PackageManager.GetPackageInfo(pluginPackage, 0).VersionName
                      let enabledStatus = pluginDb.IsEnabled(pluginPackage) ? GetString(Resource.String.plugin_enabled) : GetString(Resource.String.plugin_disabled)
                      select new PluginItem(pluginPackage, enabledStatus, this)).ToList();
            /*
                {
                    new PluginItem("PluginA", Resource.Drawable.Icon, "keepass2android.plugina", "connected"),
                    new PluginItem("KeepassNFC", Resource.Drawable.Icon, "com.bla.blubb.plugina", "disconnected")
                };
             * */
            _pluginArrayAdapter = new PluginArrayAdapter(this, Resource.Layout.ListViewPluginRow, _items);
            ListAdapter = _pluginArrayAdapter;
        }
        protected override void OnResume()
        {
            base.OnResume();
            PluginDatabase pluginDb = new PluginDatabase(this);

            _items = (from pluginPackage in pluginDb.GetAllPluginPackages()
                      let version = PackageManager.GetPackageInfo(pluginPackage, 0).VersionName
                                    let enabledStatus = pluginDb.IsEnabled(pluginPackage) ? GetString(Resource.String.plugin_enabled) : GetString(Resource.String.plugin_disabled)
                                                        select new PluginItem(pluginPackage, enabledStatus, this)).ToList();

            /*
             *      {
             *              new PluginItem("PluginA", Resource.Drawable.Icon, "keepass2android.plugina", "connected"),
             *              new PluginItem("KeepassNFC", Resource.Drawable.Icon, "com.bla.blubb.plugina", "disconnected")
             *      };
             * */
            _pluginArrayAdapter = new PluginArrayAdapter(this, Resource.Layout.ListViewPluginRow, _items);
            ListAdapter         = _pluginArrayAdapter;
        }
        private void UpdateView()
        {
            var scopesContainer = FindViewById <LinearLayout>(Resource.Id.scopes_list);
            //scopesContainer.RemoveAllViews();

            var pluginDb = new PluginDatabase(this);

            _checkbox.Checked = pluginDb.IsEnabled(_pluginPackageName);
            foreach (string scope in pluginDb.GetPluginScopes(_pluginPackageName))
            {
                string scopeId = scope.Substring("keepass2android.".Length);

                TextWithHelp help = new TextWithHelp(this,
                                                     GetString(Resources.GetIdentifier(scopeId + "_title", "string", PackageName)),
                                                     GetString(Resources.GetIdentifier(scopeId + "_explanation", "string", PackageName)));
                LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.FillParent,
                                                                                       ViewGroup.LayoutParams.WrapContent);
                help.LayoutParameters = layoutParams;
                scopesContainer.AddView(help);
            }
        }
Пример #9
0
        public void CloseAfterTaskComplete()
        {
            //before closing, wait a little to get plugin updates
            int numPlugins = new PluginDatabase(this).GetPluginsWithAcceptedScope(Strings.ScopeCurrentEntry).Count();
            var timeToWait = TimeSpan.FromMilliseconds(500 * numPlugins);

            SetProgressBarIndeterminateVisibility(true);
            _timer = new Timer(obj =>
            {
                RunOnUiThread(() =>
                {
                    //task is completed -> return NullTask
                    Intent resIntent = new Intent();
                    new NullTask().ToIntent(resIntent);
                    SetResult(KeePass.ExitCloseAfterTaskComplete, resIntent);
                    //close activity:
                    Finish();
                }
                              );
            },
                               null, timeToWait, TimeSpan.FromMilliseconds(-1));
        }
Пример #10
0
        public override void OnReceive(Context context, Intent intent)
        {
            PluginDatabase pluginDb = new PluginDatabase(context);
            if (intent.Action == Strings.ActionRequestAccess)
            {
                var senderPackage = intent.GetStringExtra(Strings.ExtraSender);
                var requestToken = intent.GetStringExtra(Strings.ExtraRequestToken);

                var requestedScopes = intent.GetStringArrayListExtra(Strings.ExtraScopes);

                if (!AreScopesValid(requestedScopes))
                {
                    return;
                }

                if (pluginDb.GetRequestToken(senderPackage) != requestToken)
                {
                    Log.Warn(_tag, "Invalid requestToken!");
                    return;
                }
                string currentAccessToken = pluginDb.GetAccessToken(senderPackage);
                if ((currentAccessToken != null)
                    && (AccessManager.IsSubset(requestedScopes,
                                           pluginDb.GetPluginScopes(senderPackage))))
                {
                    //permission already there.
                    var i = new Intent(Strings.ActionReceiveAccess);
                    i.PutExtra(Strings.ExtraSender, context.PackageName);
                    i.PutExtra(Strings.ExtraAccessToken, currentAccessToken);
                    //TODO: Plugin should verify requestToken to make sure it doesn't receive accessTokens from malicious apps
                    i.PutExtra(Strings.ExtraRequestToken, requestToken);
                    i.SetPackage(senderPackage);
                    context.SendBroadcast(i);

                    Log.Debug(_tag, "Plugin " + senderPackage + " enabled.");
                }
                else
                {
                    //store that scope was requested but not yet approved (=> accessToken = null)
                    pluginDb.StorePlugin(senderPackage, null, requestedScopes);

                    Log.Debug(_tag, "Plugin " + senderPackage + " not enabled.");

                    //see if the plugin has an access token
                    string accessToken = intent.GetStringExtra(Strings.ExtraAccessToken);
                    if (accessToken != null)
                    {
                        //notify plugin that access token is no longer valid or sufficient
                        Intent i = new Intent(Strings.ActionRevokeAccess);
                        i.PutExtra(Strings.ExtraSender, context.PackageName);
                        i.PutExtra(Strings.ExtraAccessToken, accessToken);
                        i.SetPackage(senderPackage);
                        context.SendBroadcast(i);
                        Log.Warn(_tag, "Access token of plugin " + senderPackage + " not (or no more) valid.");
                    }

                }
                if (OnReceivedRequest != null)
                    OnReceivedRequest(this, new PluginHostEventArgs() { Package = senderPackage });

            }
        }
Пример #11
0
 /// <summary>
 /// Sends a broadcast to all potential plugins prompting them to request access to our app.
 /// </summary>
 public static void TriggerRequests(Context ctx)
 {
     PluginDatabase pluginDatabase = new PluginDatabase(ctx);
     foreach (string pkg in GetAllPlugins(ctx))
         TriggerRequest(ctx, pkg, pluginDatabase);
 }
Пример #12
0
 public void CloseAfterTaskComplete()
 {
     //before closing, wait a little to get plugin updates
     int numPlugins = new PluginDatabase(this).GetPluginsWithAcceptedScope(Strings.ScopeCurrentEntry).Count();
     var timeToWait = TimeSpan.FromMilliseconds(500*numPlugins);
     SetProgressBarIndeterminateVisibility(true);
     _timer = new Timer(obj =>
         {
             RunOnUiThread(() =>
                 {
                     //task is completed -> return NullTask
                     Intent resIntent = new Intent();
                     new NullTask().ToIntent(resIntent);
                     SetResult(KeePass.ExitCloseAfterTaskComplete, resIntent);
                     //close activity:
                     Finish();
                 }
                 );
         },
         null, timeToWait, TimeSpan.FromMilliseconds(-1));
 }
Пример #13
0
        public override void OnReceive(Context context, Intent intent)
        {
            PluginDatabase pluginDb = new PluginDatabase(context);

            if (intent.Action == Strings.ActionRequestAccess)
            {
                string senderPackage = intent.GetStringExtra(Strings.ExtraSender);
                string requestToken  = intent.GetStringExtra(Strings.ExtraRequestToken);

                IList <string> requestedScopes = intent.GetStringArrayListExtra(Strings.ExtraScopes);

                if (!AreScopesValid(requestedScopes))
                {
                    Log.Debug(_tag, "requested scopes not valid");
                    return;
                }

                if (pluginDb.GetRequestToken(senderPackage) != requestToken)
                {
                    Log.Warn(_tag, "Invalid requestToken!");
                    return;
                }
                string currentAccessToken = pluginDb.GetAccessToken(senderPackage);
                if ((currentAccessToken != null) &&
                    (AccessManager.IsSubset(requestedScopes,
                                            pluginDb.GetPluginScopes(senderPackage))))
                {
                    //permission already there.
                    var i = new Intent(Strings.ActionReceiveAccess);
                    i.PutExtra(Strings.ExtraSender, context.PackageName);
                    i.PutExtra(Strings.ExtraAccessToken, currentAccessToken);
                    //TODO: Plugin should verify requestToken to make sure it doesn't receive accessTokens from malicious apps
                    i.PutExtra(Strings.ExtraRequestToken, requestToken);
                    i.SetPackage(senderPackage);
                    context.SendBroadcast(i);

                    Log.Debug(_tag, "Plugin " + senderPackage + " enabled.");
                }
                else
                {
                    //store that scope was requested but not yet approved (=> accessToken = null)
                    pluginDb.StorePlugin(senderPackage, null, requestedScopes);

                    Log.Debug(_tag, "Plugin " + senderPackage + " not enabled.");

                    //see if the plugin has an access token
                    string accessToken = intent.GetStringExtra(Strings.ExtraAccessToken);
                    if (accessToken != null)
                    {
                        //notify plugin that access token is no longer valid or sufficient
                        Intent i = new Intent(Strings.ActionRevokeAccess);
                        i.PutExtra(Strings.ExtraSender, context.PackageName);
                        i.PutExtra(Strings.ExtraAccessToken, accessToken);
                        i.SetPackage(senderPackage);
                        context.SendBroadcast(i);
                        Log.Warn(_tag, "Access token of plugin " + senderPackage + " not (or no more) valid.");
                    }
                }
                if (OnReceivedRequest != null)
                {
                    OnReceivedRequest(this, new PluginHostEventArgs()
                    {
                        Package = senderPackage
                    });
                }
            }
        }
Пример #14
0
        protected override void OnCreate(Bundle bundle)
        {
            base.OnCreate(bundle);

            // Set our view from the "main" layout resource
            SetContentView(Resource.Layout.Main);

            // Get our button from the layout resource,
            // and attach an event to it
            Button button = FindViewById<Button>(Resource.Id.MyButton);

            button.Click += delegate { PluginHost.TriggerRequests(this);  };

            FindViewById<Button>(Resource.Id.managePluginsButton).Click += delegate(object sender, EventArgs args)
                {
                    StartActivity(new Intent(this, typeof(PluginListActivity)));
                };
            FindViewById<Button>(Resource.Id.entryviewButton).Click += delegate
            {
                    StartActivity(new Intent(this, typeof(EntryActivity)));
            };

            FindViewById<Button>(Resource.Id.testDbButton).Click += delegate
                {
                    string message = "ok. ";
                    try
                    {
                        Stopwatch sw = new Stopwatch();
                        sw.Start();
                        PluginDatabase db = new PluginDatabase(this);
                        db.Clear();

                        if (db.GetAllPluginPackages().Count() != 0)
                            throw new Exception("db not empty!");

                        const string testPackageA = "test.package.a";
                        const string testPackageB = "test.package.b";
                        db.ClearPlugin(testPackageA);
                        db.ClearPlugin(testPackageB);
                        EnsurePackageDataIsEmpty(db, testPackageA);
                        EnsurePackageDataIsEmpty(db, testPackageB);

                        string[] requestedScopes = {
                            Strings.ScopeDatabaseActions
                        };
                        db.StorePlugin(testPackageA, null, requestedScopes);
                        EnsurePackageDataIsEmpty(db, testPackageB);
                        EnsurePackageDataIsEmpty(new PluginDatabase(this), testPackageB);
                        db.StorePlugin(testPackageB, null, requestedScopes);
                        EnsurePackageHasUnacceptedScope(db, testPackageA, Strings.ScopeDatabaseActions);
                        EnsurePackageHasUnacceptedScope(db, testPackageB, Strings.ScopeDatabaseActions);
                        EnsurePackageHasUnacceptedScope(new PluginDatabase(this), testPackageA, Strings.ScopeDatabaseActions);

                        if (db.GetAllPluginPackages().Count() != 2)
                            throw new Exception("wrong count of plugins");
                        if (db.GetPluginsWithAcceptedScope(Strings.ScopeDatabaseActions).Any())
                        {
                            throw new Exception("wrong count of accepted plugins");
                        }
                        if (new PluginDatabase(this).GetPluginsWithAcceptedScope(Strings.ScopeDatabaseActions).Any())
                        {
                            throw new Exception("wrong count of accepted plugins");
                        }

                        db.SetEnabled(testPackageA, true);
                        if (db.GetPluginsWithAcceptedScope(Strings.ScopeDatabaseActions).Single() != testPackageA)
                        {
                            throw new Exception("wrong plugin");
                        }
                        if (new PluginDatabase(this).GetPluginsWithAcceptedScope(Strings.ScopeDatabaseActions).Single() != testPackageA)
                        {
                            throw new Exception("wrong plugin");
                        }
                        if (db.GetPluginsWithAcceptedScope("somescope").Any())
                        {
                            throw new Exception("wrong count of accepted plugins");
                        }
                        var accessTokenA = db.GetAccessToken(testPackageA);
                        if (String.IsNullOrEmpty(accessTokenA))
                            throw new Exception("expected access token!");
                        if (!db.IsEnabled(testPackageA))
                            throw new Exception("plugin not enabled!");
                        if (db.IsEnabled(testPackageB))
                            throw new Exception("plugin enabled!");
                        if (!db.IsValidAccessToken(testPackageA, accessTokenA, Strings.ScopeDatabaseActions))
                            throw new Exception("invalid token!");
                        db.SetEnabled(testPackageA, false);
                        if (db.IsValidAccessToken(testPackageA, accessTokenA, Strings.ScopeDatabaseActions))
                            throw new Exception("valid token?!");
                        if (db.GetPluginsWithAcceptedScope(Strings.ScopeDatabaseActions).Any())
                            throw new Exception("unexpected!");

                        new PluginDatabase(this).SetEnabled(testPackageB, true);
                        if (!db.IsEnabled(testPackageB))
                            throw new Exception("plugin not enabled!");

                        db.SetEnabled(testPackageA, true);
                        accessTokenA = db.GetAccessToken(testPackageA);

                        message += sw.ElapsedMilliseconds + "ms";

                        Stopwatch swQuery = new Stopwatch();
                        swQuery.Start();
                        int n = 3;
                        for (int i = 0; i < n; i++)
                        {
                            if (db.GetPluginsWithAcceptedScope(Strings.ScopeDatabaseActions).Count() != 2)
                            {
                                throw new Exception("wrong plugin");
                            }
                            if (!db.IsValidAccessToken(testPackageA, accessTokenA, Strings.ScopeDatabaseActions))
                                throw new Exception("invalid token");
                        }
                        message += "/ " + swQuery.ElapsedMilliseconds/(double)n/2.0 + "ms for query";

                    }
                    catch (Exception exception)
                    {
                        message = exception.ToString();
                    }
                    Toast.MakeText(this, message, ToastLength.Long).Show();

                };
        }
Пример #15
0
 private void EnsurePackageHasUnacceptedScope(PluginDatabase db, string plugin, string scope)
 {
     if (String.IsNullOrEmpty(db.GetRequestToken(plugin)))
         throw new Exception("invalid request token");
     if (db.GetAccessToken(plugin) != null)
         throw new Exception("invalid access token!");
     if (db.GetPluginScopes(plugin).Count != 1)
         throw new Exception("Unexpected scopes!");
     if (db.GetPluginScopes(plugin).First() != scope)
         throw new Exception("Unexpected scope in db!");
 }
Пример #16
0
 private static void EnsurePackageDataIsEmpty(PluginDatabase db, string testPackageA)
 {
     if (String.IsNullOrEmpty(db.GetRequestToken(testPackageA)))
         throw new Exception("invalid request token");
     if (db.GetAccessToken(testPackageA) != null)
         throw new Exception("invalid access token!");
     if (db.GetPluginScopes(testPackageA).Count > 0)
         throw new Exception("Unexpected scopes!");
 }
Пример #17
0
        private void UpdateView()
        {
            var scopesContainer = FindViewById<LinearLayout>(Resource.Id.scopes_list);
            //scopesContainer.RemoveAllViews();

            var pluginDb = new PluginDatabase(this);
            _checkbox.Checked = pluginDb.IsEnabled(_pluginPackageName);
            foreach (string scope in pluginDb.GetPluginScopes(_pluginPackageName))
            {
                string scopeId = scope.Substring("keepass2android.".Length);

                TextWithHelp help = new TextWithHelp(this,
                                                     GetString(Resources.GetIdentifier(scopeId + "_title", "string", PackageName)),
                                                     GetString(Resources.GetIdentifier(scopeId + "_explanation", "string", PackageName)));
                LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.FillParent,
                                                                                       ViewGroup.LayoutParams.WrapContent);
                help.LayoutParameters = layoutParams;
                scopesContainer.AddView(help);
            }
        }