Discord and Security UI Patterns

20 June 2020

I've been using web browser cookie-based login for Discord. Recently my main laptop crashed. Now using an old standby laptop, I visit Discord and am prompted for password. No problem, I have it in my password safe that is backed up regularly. Password ok, now prompted for 2FA. Hmmm, 2FA fails...

Right, seems I have been using cookie-based login for so long that, during that time, I bought a new phone and sold the old phone. For 2FA, I use Duo Mobile, and it is phone-specific:

Since Duo Mobile is tied to a specific device's hardware security module (HSM), you will need to reinstall and reactivate Duo Mobile on a new phone.

No biggie, this is only Discord. I'll make a new account. Ok done. Login again. Discord repeatedly says, for my new account, "We've detected something out of the ordinary going on. To continue using Discord, we will need you to verify your account." And the single option presented is to verify by phone. That's an easy decision: No Discord, you are not getting my mobile phone number.

A few things to think about, in no particular order, from both user and system engineering perspectives:

  • I am willing to use cookie-based login for Discord. Probably need not have enabled 2FA. If a user enables cookie login, perhaps prompt to turn off 2FA, or do it automatically?

  • With a password safe, my Discord password is randomly generated gibberish. Is that, combined with good integration of safe and browser, better than using cookie-based login? Am I applying resume-padding thinking here?

  • As a user, RTF2FAM. As a system engineer, expect no user to.

  • The corporate IT world practises periodic security credentials review. Overkill for an individual to do it like they do, but this situation has motivated me to relook at my password safe, Duo Mobile accounts and a few other things.

  • Think hard about asking for people's mobile phone numbers. If you do it, don't 'explain' it with weasel words like Discord has done. Yeah yeah, I'm not paying $$ to use Discord, therefore they want me to pay with my personal data. I get that. I say no.


Updating OpenSSL for Pharo

6 June 2020

Pharo is transitioning from OpenSSL 1.0.x to OpenSSL 1.1.1. There are C API changes between the two OpenSSL versions that break many tests, basic things like XXX_create() becoming XXX_new(), XXX_init() becoming XXX_reset() etc. As such, I've created the branches openssl_1_0 and openssl_1_1 to match the versions used by Pharo.

To load, for OpenSSL 1.0.x:

Metacello new
  baseline: 'OpenSSL';
  repository: 'github://PierceNg/OpenSSL-Pharo:openssl_1_0/src-st';

To load, for OpenSSL 1.1.x:

Metacello new
  baseline: 'OpenSSL';
  repository: 'github://PierceNg/OpenSSL-Pharo:openssl_1_1/src-st';

Updating GlorpSQLite for Pharo 8

2 May 2020

I've started to update Glorp and GlorpSQLite for Pharo 8. This post lists the stuff to be handled.

Changes in Pharo

First, changes in Pharo from version to version. Glorp's TimedProxyReaper uses a weak-valued dictionary to hold TimedProxy instances. In Pharo 6, WeakValueDictionary>>at:put: essentially does the following:

WeakValueAssociation key: key value: anObject

In Pharo 7, that became:

WeakValueAssociation key: key value: anObject asSetElement

This required TimedProxy to implement #asSetElement.

In Pharo 8, #asSetElement is deprecated in favour of #asCollectionElement.

WeakValueAssociation key: key value: anObject asCollectionElement

So TimedProxy now also needs #asCollectionElement.

New SQLite Binding

The Pharo community has consolidated around Pharo-SQLite3 as the definitive SQLite binding going forward. GlorpSQLite uses the now-legacy UDBC-SQLite binding currently. This change should be straightforward.

Glorp Changes

Todd Blanchard has been working on Ruby on Rails-style ActiveRecord for Glorp, and testing the changes with PostgreSQL.


With independently evolving drivers for SQLite, PostgreSQL and MySQL, and the ActiveRecord work changing Glorp itself, the time has come to set up CI for Glorp.

Embedding Pharo in Pascal HOWTO - Linux

23 January 2020

Pharo headless VM

First, build the Pharo headless VM, following the instructions in its README. When done, the VM files are in build/vm.

Pharo application image

Next, prepare the Pharo application image. Basically, start from a fresh Pharo 8.0 image and load the EmbeddedSupport code from Pablo's repository. The following snippet works, assuming you have cloned Pablo's repository locally; adjust the gitlocal path in the snippet, of course.

Metacello new
    baseline: 'EmbeddedSupport';
    repository: 'gitlocal:///home/pierce/src/st/pharo-vm-embedded-example/smalltalk-src';

NoChangesLog install.
NoPharoFilesOpener install.
PharoCommandLineHandler forcePreferencesOmission: true.

SmalltalkImage current snapshot: true andQuit: true

Windows resource

Then, embed the Pharo application image into a Windows resource file.

Here's a simplified version of resources.rc. This assumes you have named the image to be embedded Pharo.image.

300 RCDATA "Pharo.image"

Building a Windows resource file on Linux requires windres. On Ubuntu, this program is part of the package binutils-mingw-w64-x86-64.

Place the application Pharo.image and resources.rc in the same directory. Then,

% /usr/bin/x86_64-w64-mingw32-windres -i resources.rc -o resources.res
% ls -l
total 113488
-rw-r--r-- 2 pierce pierce 58098672 Jan 23 14:10 Pharo.image
-rw-r--r-- 2 pierce pierce       25 Jan 23 14:01 resources.rc
-rw-r--r-- 2 pierce pierce 58098736 Jan 23 14:10 resources.res

The output resources.res is the compiled resources file.

Pascal host program

Finally we are ready to build the Pascal host program. Move resources.res to this repository's embedded-cli directory. Also create a link to libPharoVMCore.so or make a copy of it. The directory's content is now as follows:

% ls -l
total 58736
-rwxr-xr-x 2 pierce pierce  3344760 Jan 23 09:26 libPharoVMCore.so*
-rw-r--r-- 2 pierce pierce 58098736 Jan 23 14:10 resources.res
-rw-r--r-- 4 pierce pierce     1945 Jan 23 12:55 runPharoEmbedded.pas
-rw-r--r-- 4 pierce pierce     3824 Jan 23 12:54 ulibEmbeddedImage.pas
-rw-r--r-- 5 pierce pierce     1045 Jan 22 15:42 ulibPharoVM.pas

At the start of runPharoEmbedded.pas, the line {$R resources.res} is the Pascal compiler directive to incorporate resources.res into the executable that is being built:

program runPharoEmbedded;

{$mode objfpc}{$H+}
{$R resources.res} { <= compiler directive to incorporate resources.res }
{$linklib m}

Build the host program - the Pascal compiler is its own make system and knows to compile the necessary source files. (The Pascal compiler also knows how to invoke windres to compile resources.rc into resources.res when so configured. I've done that part by hand since this is a HOWTO.)

% fpc runPharoEmbedded.pas
Free Pascal Compiler version 3.0.4 [2018/10/29] for x86_64
Copyright (c) 1993-2017 by Florian Klaempfl and others
Target OS: Linux for x86-64
Compiling runPharoEmbedded.pas
Compiling ulibPharoVM.pas
Compiling ulibEmbeddedImage.pas
Compiling resource runPharoEmbedded.or
Linking runPharoEmbedded
/usr/bin/ld: warning: link.res contains output sections; did you forget -T?
232 lines compiled, 0.4 sec

% ls -l runPharoEmbedded
-rwxr-xr-x 1 pierce pierce 58884328 Jan 23 14:22 runPharoEmbedded*

Much of the size of the executable is due to the embedded Pharo.image.

We'll run runPharoEmbedded in the headless VM build directory because Pharo's baked-in library lookup currently requires this. (More on this in a later post.) So move the program over.

% mv runPharoEmbedded ~/src/st/opensmalltalk-vm-pharo/build/vm
% cd ~/src/st/opensmalltalk-vm-pharo/build/vm
% ls -T 30
libB2DPlugin.so*             libgit2.so.0.25.1             libSDL2-2.0.so.0*      libssl.so*
libBitBltPlugin.so*          libgit2.so.25                 libSDL2-2.0.so.0.7.0*  libssl.so.1.0.0*
libcrypto.so.1.0.0*          libIA32ABI.so*                libSDL2.so*            libSurfacePlugin.so*
libDSAPrims.so*              libJPEGReaderPlugin.so*       libSecurityPlugin.so*  libTestLibrary.so*
libffi.so*                   libJPEGReadWriter2Plugin.so*  libSocketPlugin.so*    libUnixOSProcessPlugin.so*
libffi.so.7*                 libLargeIntegers.so*          libSqueakFFIPrims.so*  libUUIDPlugin.so*
libffi.so.7.1.0*             libLocalePlugin.so*           libSqueakSSL.so*       pharo*
libFileAttributesPlugin.so*  libMiscPrimitivePlugin.so*    libssh2.so*            runPharoEmbedded*
libFilePlugin.so*            libPharoVMCore.so*            libssh2.so.1*
libgit2.so                   libPThreadedPlugin.so*        libssh2.so.1.0.1*

Set up LD_LIBRARY_PATH. The first path segment is for the Pharo VM. The second is for libcairo2.so needed by the embedded Pharo.image - on Ubuntu, it lives in /usr/lib/x86_64-linux-gnu, which isn't in Pharo 8's current hardcoded lookup path. Then run the executable:

% export LD_LIBRARY_PATH=`pwd`:/usr/lib/x86_64-linux-gnu
% uname -a
Linux Otrus 4.15.0-74-generic #84-Ubuntu SMP Thu Dec 19 08:06:28 UTC 2019 x86_64 x86_64 x86_64 GNU/Linux
% ./runPharoEmbedded


Ta da! "lala" is printed by Pharo.