18 June 2019

How to dump macOS security-rights database

macOS handles some security items in a custom database, which may or may not be SQLite. The official way to interact with such database, outside of Objective-C, is the /usr/bin/security utility, with the parameter authorizationdb and specifying the required operation on the class of rights, e.g. security authorizationdb read system.login.console

Unfortunately, there is no way (that I could find) to simply list all classes. I was trying to uninstall something that might have had references in that db, but I wasn't sure about the class it might be registered under, so I wanted to dump them all.

Luckily I found what looks looks like a comprehensive list of rights. After a quick scraping job with Python, I had a list that I could use like this:

cat osxrights.txt | xargs -I % sh -c 'sudo security authorizationdb read %' | grep -B 10 myAnnoyingItemToRemove

... and the bundle wasn't anywhere, so I could just chuck it.

(Note: had the item been found, I would have had to dump the whole security class to a .plist file with security authorizationdb read the.class > my.plist , edited the file to remove it, then write it back to the db with security authorizationdb write the.class < my.plist )

14 March 2019

How to remove all bars in fullscreen mode in Firefox on MacOS/OSX ("kiosk mode")

Procedure

If you want to remove all toolbars from Firefox in fullscreen mode on Mac, this is the procedure:

  1. Type about:config: in the location bar to open advanced settings. (If it is the first time you do it, you might have to click "confirm" or something like that in the scary screen that comes up first.)
  2. search for full-screen-api.allow-trusted-requests-only and double-click the line that is found, so the value changes to false
  3. Bring up the Bookmark Toolbar if you don't have it (menu View -> Toolbars -> Bookmark Toolbar)
  4. Right-click on empty space in the Bookmark Toolbar, and select New Bookmark...
  5. In the Name field, type something like "Enter Fullscreen" (it doesn't really matter, just don't leave it blank)
  6. In the Location field, enter the following line:
    javascript:document.getElementsByTagName('html')[0].mozRequestFullScreen();void(0)
  7. Click Add to save the bookmark.
Now, when you click on that bookmark, Firefox will go "real fullscreen", hiding all toolbars. To get them back, you will have to press ESC.

Now, there is a bit of a snag. That preference in about:config: is set to true by default for a reason: it is a bit unsafe to allow any website to use fullscreen-enabling javascript. For this reason I would suggest to only do this for limited periods, then switch it back once you're done.

Long-winded explanation

FF has a preference, browser.fullscreen.autohide, that in theory should govern the behaviour of toolbars when going fullscreen. It is set to true by default, meaning toolbars should disappear. However, for some reason this property has (almost) always failed to work on MacOS/OSX builds of Firefox.

There used to be a few extensions that corrected that behaviour, but they've all gone away when Firefox switched to WebExtension APIs, which basically sandboxed extensions more rigidly and blocked them from changing the browser interface as deeply as they could before. This was the price for the dramatic performance improvement seen in Firefox 57+.

This workaround hence relies on the new Fullscreen WebAPI, which is supposed to be a new, standard way to enable fullscreen via Javascript on any browser (well, any browser that implements it - just a few at the moment). However, because of security concerns, this API is locked down by default; so, in order to use it, we first have to relax checks as described above. Once that is done, we can launch a bit of JS from a bookmark that triggers "real" fullscreen.

Credit to this AskDifferent post where I first found the trick.

11 February 2019

How to customise Jetty embedded in Spark Java framework

EDIT: I uploaded a full working example, ready to be customized, on github. If you just want a working solution, go there. Otherwise, keep reading for the explanation.

When it comes to Java microframeworks for API development, I've been using Spark for some time in a couple of different projects. For most casual needs, it works out of the box; however, there are circumstances where the "easy" options for configuring the embedded Jetty instance, are simply not enough. In that case, you have to take control and basically replace the instance with one that you completely control.

Due to how Jetty works, there are multiple moving parts: the server takes care of things like thread pools, the socket is responsible for SSL and other low-level protocol stuff, and the handler is where you do high-level middleware (changing headers etc). This means that you might need several factories to take care of all these. The good news is that Spark is granular enough that you can (more or less) limit yourself to what you need. The main pattern is: there will be a factory for each element, with a create() method returning an interface; you implement the interface and swap out the default factory with your own. However, these factories at the moment (Spark 2.8) are somewhat nested, so depending on where you need to work, you might have to replace a bunch of classes before you hit the point you're interested in.

The main entry point is EmbeddedServers.add(identifier, serverFactory). This is what you'll call from the main() method you use for all the post() and get() configuration directives. It is important that EmbeddedServers should appear right at the top, before any other configuration directive, otherwise Spark will use its default factory. It should look more or less like this:

EmbeddedServers.add(
     EmbeddedServers.Identifiers.JETTY, 
     new MyWonderfulServerFactory());

For the identifier, we re-use the default one because otherwise Spark will take over again. Nothing to do there.

The server factory is where real work begins. Your class (or lambda) needs to implement the spark.embeddedserver.EmbeddedServerFactory interface, which has one method:

public EmbeddedServer create(
            Routes routeMatcher, 
            StaticFilesConfiguration staticFilesConfiguration, 
            ExceptionMapper exceptionMapper, 
            boolean hasMultipleHandler)

As a starter, you can copy the content of spark.embeddedserver.jetty.EmbeddedJettyFactory as-is. You don't need constructors (unless you want them). Strictly speaking you don't need withThreadPool() and withHttpOnly() methods either, but I suggest you keep them anyway; just change the return type to match MyWonderfulServerFactory.

Create() does three things:

  1. Initializing the route matcher, which you probably don't want to touch;
  2. Initializing the Jetty handler for that matcher, which you may want to configure for things like header manipulation and other middleware;
  3. Creating the embedded server, which is likely what you are after.

I will assume we want to tweak n.3. The main place where to pay attention is this line at the end of create():

return (new EmbeddedJettyServer(this.serverFactory, handler)
        ).withThreadPool(this.threadPool);

This will return the default configuration, and we don't want that. So we change it to something like:

return (new MyWonderfulEmbeddedServer(handler)
        ).withThreadPool(this.threadPool);

Now we need a MyWonderfulEmbeddedServer class, which should implement spark.embeddedserver.EmbeddedServer. Again, as a starting point, you can copy spark.embeddedserver.jetty.EmbeddedJettyServer, and change the return types to match. I also suggest you get rid of the factory parameter in constructor and the related field, which adds a bit of unnecessary complexity. That factory is actually used only in one place:

if (this.threadPool == null) {
    this.server = this.serverFactory.create(
       maxThreads, minThreads, threadIdleTimeoutMillis);
} else {
    this.server = this.serverFactory.create(this.threadPool);
}

Which you can replace with the following (straight from spark.embeddedserver.jetty.JettyServer):

if (this.threadPool == null) {
    if (maxThreads > 0) {
       int min = minThreads > 0 ? minThreads : 8;
       int idleTimeout = threadIdleTimeoutMillis > 0 ? threadIdleTimeoutMillis : '\uea60';
       server = new Server(new QueuedThreadPool(maxThreads, min, idleTimeout));
    } else {
       server = new Server();
    }
} else {
    this.server = threadPool != null ? new Server(threadPool) : new Server();
}

It's a bunch of stuff related to the amount of threads and timeouts. If that's what you were trying to configure, btw, this is where you can do it. To be honest, I believe Spark developers intended that the "proper" way, to do that particular customisation, would be to keep the factory parameter as it is, implement your own alternative to the badly-named JettyServer class -- it should be something like JettyThreadConfigFactory, really -- which implements the similarly badly-named JettyServerFactory, and pass it to the constructor in MyWonderfulServerFactory.create().

In my case, though, I was after an SSL customisation, and for that I had to swap out yet another factory, spark.embeddedserver.jetty.SocketConnectorFactory, mentioned in the second half of this block:

ServerConnector connector;
if (sslStores == null) {
    connector = SocketConnectorFactory.createSocketConnector(
         this.server, host, port);
} else {
    connector = SocketConnectorFactory.createSecureSocketConnector(
         this.server, host, port, sslStores);
}

In this case there is no interface, you can just extend the existing class with what you need. I wanted to enforce a particular set of SSL ciphers and protocols, so I overrode createSecureSocketConnector() adding the following bits:

sslContextFactory.setExcludeProtocols("SSLv3", "SSLv2", "TLSv1.2");
// first we clear existing exclusions
sslContextFactory.setExcludeCipherSuites(new String[]{});
// then we re-add what we need
sslContextFactory.setIncludeCipherSuites(bigArrayOfCipherNames);

And that's it. Now you know how to instantiate your own Jetty instance for Spark. It's a bit convoluted, and hopefully a "spark 3" will give us a better architecture to work with, one day. In the meantime, this is how you can do it.

26 November 2018

How to get Google Home / Google Assistant to call your iOS iPhone

If you have an iPhone, Google Assistant and Google Home won't be able to call or ring your phone out of the box, since it's an Android-only feature. If you are not in the US, you cannot even use the workaround of calling your number. So what can you do, if you tend to misplace your phone around the house ? (ahem)
  1. Get an account on IFTTT
  2. Install the IFTTT app on your phone
  3. create a new applet, click on "this" and select Google Assistant
  4. select "say a simple phrase"  and enter the details you prefer (e.g. "make a noise on my phone" or "ping my phone". Note the most common "ring my phone" or "where is my phone" are reserved by Google and won't work).
  5. click on "then" and select VoIP Calls
  6. enter a message the phone will tell you if you pick up (e.g. "Glad you found me!")
  7. Save the applet.
Now, when you say that phrase to Google Home / Goole Assistant, it will ring your phone, so you can dig it out of the sofa or the Lego box (ahem).

15 August 2018

how to load initial data and test data in Django 2+

There are two ways to automatically load data in Django:

  • for data you need while running tests, place xml/json/yaml files in yourapp/fixtures.
  • for data you need while setting up the database from scratch, or at specific points in time, you must create a Migration

This is a bit annoying, because chances are these locations will get out of sync sooner or later, and it duplicates effort if you do reproducible builds, docker, and stuff like that.

The solution is to create a migration that actually loads fixtures. So:

  1. Create your fixtures: manage.py dumpdata --output yourapp/fixtures/yourmodel.json yourapp.YourModel
  2. Create an empty Migration: manage.py makemigrations --empty yourapp
  3. Edit the resulting migration (the last file created under yourapp/migrations, making it look like this:
    from django.db import migrations
    
    def load_fixtures(apps, schema_editor):
        # This is what will be executed by the migration
        from django.core.management import call_command
        # this is the equivalent of running manage.py loaddata yourmodel.json
        for fixture_name in ['yourmodel']: # add any additional model here
            call_command("loaddata", fixture_name)
        # add other calls if you have multiple models
    
    def rollback(apps, schema_editor):
        # This will be executed if you rollback the migration, so you want to clean up
        for model_name in ["YourModel"]:  # add any additional model here
            model = apps.get_model("yourapp", model_name)
            model.objects.all().delete()
    
    class Migration(migrations.Migration):
        dependencies = [
          # ... don't touch anything here ...
        ]
    
        operations = [
            migrations.RunPython(load_fixtures, rollback),
        ]
    # -*- coding: utf-8 -*-
    
  4. Profit

Note that this does not remove the option to have data that is available only in certain situation: just don't list the fixtures you don't want in the migration, and vice-versa.