Jun 202021
 

So, today on the radio I heard that from this Friday, our state government was “expanding” the use of their Check-in Queensland program. Now, since my last post on the topic, I have since procured a new tablet. The tablet was purchased for completely unrelated reasons, namely:

  1. to provide navigation assistance, current speed monitoring and positional logging whilst on the bicycle (basically, what my Garmin Rino-650 does)
  2. to act as a media player (basically what my little AGPTek R2 is doing — a device I’ve now outgrown)
  3. to provide a front-end for a SDR receiver I’m working on
  4. run Slack for monitoring operations at work

Since it’s a modern Android device, it happens to be able to run the COVID-19 check-in programs. So I have COVIDSafe and Check-in Queensland installed. For those to work though, I have to run my existing phone’s WiFi hotspot. A little cumbersome, but it works, and I get the best of both worlds: modern Android + my phone’s excellent cell tower reception capability.

The snag though comes when these programs need to access the Internet at times when using my phone is illegal. Queensland laws around mobile phone use changed a while back, long before COVID-19. The upshot was that, while people who hold “open” driver’s licenses may “use” a mobile phone (provided that they do not need to handle it to do so), anybody else may not “use” a phone for “any purpose”. So…

  • using it for talking to people? Banned. Even using “hands-free”? Yep, still banned.
  • using it for GPS navigation? Banned.
  • using it for playing music? Banned.

It’s a $1000 fine if you’re caught. I’m glad I don’t use a wheelchair: such mobility aids are classed as a “vehicle” under the Queensland traffic act, and you can be fined for “drink driving” if you operate one whilst drunk. So traffic laws that apply to “motor vehicles” also apply to non-“motor vehicles”.

I don’t have a driver’s license of any kind, and have no interest in getting one, my primary mode of private transport is by bicycle. I can’t see how I’d be granted permission to do something that someone on a learner’s permit or P1 provisional license is forbidden from doing. The fact that I’m not operating a “motor vehicle” does not save me, the drink-driving in a wheelchair example above tells me that I too, would be fined for riding my bicycle whilst drunk. Likely, the mobile phones apply to me too. Given this, I made the decision to not “use” a mobile phone on the bicycle “for any purpose”. “For any purpose” being anything that requires the device to be powered on.

If I’m going to be spending a few hours at the destination, and in a situation that may permit me to use the phone, I might carry it in the top-box turned off (not certain if this is permitted, but kinda hard to police), but if it’s a quick trip to the shops, I leave the mobile phone at home.

What’s this got to do with the Check-in Queensland application or my new shiny-shiny you ask? Glad you did.

The new tablet is a WiFi-only device… specifically because of the above restrictions on using a “mobile phone”. The day those restrictions get expanded to include the tablet, you can bet the tablet will be ditched when travelling as well. Thus, it receives its Internet connection via a WiFi access point. At home, that’s one of two Cisco APs that provide my home Internet service. No issue there.

If I’m travelling on foot, or as a passenger on someone else’s vehicle, I use the WiFi hot-spot function on my phone to provide this Internet service… but this obviously won’t work if I just ducked up the road on my bike to go get some grocery shopping done, as I leave the phone at home for legal reasons.

Now, the Check-in Queensland application does not work without an Internet connection, and bringing my own in this situation is legally problematic.

I can also think of situations where an Internet connection is likely to be problematic.

  • If your phone doesn’t have a reliable cell tower link, it won’t reliably connect to the Internet, Check-in Queensland will fail.
  • If your phone is on a pre-paid service and you run out of credit, your carrier will deny you an Internet service, Check-in Queensland will fail.
  • If your carrier has a nation-wide whoopsie (Telstra had one a couple of years back, Optus and Vodafone have had them too), you can find yourself with a very pretty but very useless brick in your hand. Check-in Queensland will fail.

What can be done about this?

  1. The venues could provide a WiFi service so people can log in to that, and be provided with limited Internet access to allow the check-in program to work whilst at the venue. I do not see this happening for most places.
  2. The Check-in Queensland application could simply record the QR code it saw, date/time, co-visitors, and simply store it on the device to be uploaded later when the device has a reliable Internet link.
  3. For those who have older phones (and can legally carry them), the requirement of an “application” seems completely unnecessary:
    1. Most devices made post-2010 can run a web browser capable of running an in-browser QR code scanner, and storage of the customer’s details can be achieved either through using window.localStorage or through RFC-6265 HTTP cookies. In the latter case, you’d store the details server-side, and generate an “opaque” token which would be stored on the device as a cookie. A dedicated program is not required to do the function that Check-in Queensland is performing.
    2. For older devices, pretty much anything that can access the 3G network can send and receive SMS messages. (Indeed, most 2G devices can… the only exception I know to this would be the Motorola MicroTAC 5200 which could receive but not send SMSes. The lack of a 2G network will stop you though.) Telephone carriers are required to capture and verify contact details when provisioning pre-paid and post-paid cellular services, so already have a record of “who” has been assigned which telephone number. So why not get people to text the 6-digit code that Check-In Queensland uses, to a dedicated telephone number? If there’s an outbreak, they simply contact the carrier (or the spooks in Canberra) to get the contact details.
  4. The Check-in Queensland application has a “business profile” which can be used for manual entry of a visitor’s details… hypothetically, why not turn this around? Scan a QR code that the visitor carries and provides. Such QR codes could be generated by the Check-in Queensland website, printed out on paper, then cut out to make a business-card sized code which visitors can simply carry in their wallets and present as needed. No mobile phone required! For the record, the Electoral Commission of Queensland has been doing this for our state and council elections for years.

It seems the Queensland Government is doing this fancy “app” thing “because we can”. Whilst I respect the need to effectively contact-trace, the truth is there’s no technical reason why “this” must be the implementation. We just seem to be playing a game of “follow the shepherd”. They keep trying to advertise how “smart” we are, why not prove it?

Apr 232021
 

So, about 10 years ago, I started out as a contractor with a local industrial automation company, helping them integrate energy meters into various energy management systems.

Back then, they had an in-house self-managed corporate email system built on Microsoft Small Business Server. It worked, mostly, but had the annoyance of being a pariah regarding Internet standards… begrudgingly speaking SMTP to the outside world and mangling RFC822 messaging left-right and centre any chance it got. Ohh, and if you didn’t use its sister product, Microsoft Outlook, you weren’t invited!

Thankfully, as a contractor, I was largely insulated from that horror of a mail system… I had my own, running postfix + dovecot. That worked. Flawlessly for my needs. Emails were stored in the Maildir format, so back-ups were easy, if I couldn’t find something over IMAP, a ssh into the server was all I needed to unleash grep on the mailstore. Prior to this, I’ve used various combinations of Sendmail, Qmail, qpsmtpd for MTA and uw-imapd, Binc IMAP and finally dovecot. I used SpamAssassin for mail filtering, configured the server with a variety of RBLs, and generally enjoyed a largely spam-free and easy life.

A year or two into this arrangement, my workplace’s server had a major meltdown… they apparently had hit some internal limit on the Microsoft server, and on receipt of a few messages, it just crashed. Restore from back-up, all good, then some more incoming emails, down she went. In a hurry for an alternative, they grabbed an old box, loaded it up with an Ubuntu server fork and configured Zarafa groupware which sat atop the postfix MTA.

It was chosen because it was feature-wise, similar, to the Microsoft option. Unfortunately, it was also architecturally similar, with the mailstore being stored in MySQL using a bizzare schema that tried to replicate how Microsoft Exchange stored emails… meaning any header that Zarafa didn’t understand, got stripped… and any character that didn’t fit in the mailstore’s LATIN1 table character set got replaced with ?. Yes Mr. ????????? we’ll be onto that support request right away! One thing that I will say in Zarafa’s defence though, is that they at least supported IMAP (even if their implementation was primitive, it mostly “worked”), and calendaring was accessible using CalDAV.

That was the server I inherited as mail server administrator. We kept it going like that for a couple of years, but over time, the growing pains became evident… we had to move… again. By this stage, we were using Thunderbird as our standard email client, the Lightning extension for calendaring. On the fateful weekend of the 13-14th February, 2016, after a few weeks of research and testing, we moved again; to a combination of postfix, dovecot and SoGO providing calendaring/webmail. Like the server I had at home, email was stored in Maildir mail stores, which meant back-ups were as simple as rsync, selective restoring of a mail folder was easy, we could do public folders. People could use any IMAP compatible mail client: Thunderbird, Outlook, mutt, Apple Mail… whatever floated their boat.

I was quite proactive about the spam/malware situation… there was an extensive blacklist I maintained on that server to keep repeat offenders out. If you used a server at OVH or DigitalOcean for example, your email was not welcome, connections to port 25/tcp were rejected. Anything that did get through brought to my attention, I would pass the email through Spamcop for analysis and reporting, and any repeat offenders got added to the blacklist. I’d have liked to improve on the malware scanning… there are virus scanners that will integrate into Postfix and I was willing to set something up, but obviously needed management to purchase something suitable to do that.

Calendaring worked too… about the only thing that was missing was free-busy information, which definitely has its value, but it was workable. Worst case in my opinion is maybe replace SoGO with something else, but for now, it worked.

Fast forward to March 29th this year. New company has bought up my humble abode… and the big wigs have selected… Microsoft! No consultation. No discussion. The first note I got regarding this was a company-wide email stating we’d be migrating over the Easter long week-end.

I emailed back, pointing out a few concerns. I was willing to give Microsoft a second chance. For my end as a end user, I really only care about one thing: that the server communicates with the software on my computer with agreed “standard” protocols. For email that is IMAP and SMTP. For calendaring that is CalDAV. I really don’t care how it’s implemented, so long as it implements it properly. They do their end of the bargain by speaking an agreed protocol correctly… I’ll do my end by selecting a standards-compliant email/calendar client. All good.

I was assured that yes, it would do this. Specifically, I was shown this page as evidence. Okay, I thought, lets see how it goes. Small Business Server was from 2003… surely Microsoft has learned something in 18 years. They’ve been a lot more open about things, adopting support for OpenDocument in Office, working with Novell on .NET, ditching Visual Source Safe and embracing git so much so they acquired Github… surely things have improved.

Tuesday, 6th April, we entered a new world. A world were public folders were gone. A world with no calendaring. I’m guessing the powers at be have decided I do not need to see public folders, after all, RFC2342 has been around since the 90s… and even has people from Microsoft working on it! It’s possible they’re still migrating them from the old server, but 3 weeks seems a stretch.

Fine, I can live without public folders for now. Gone are the days where I interacted with customers on a regular basis and thus needed to file correspondence. The only mail folder I had much to do with of late was a public folder called Junk Mail which I used to monitor for spam to report and train the spam filter with.

Calendaring, I’ll admit I don’t use much… but to date, I have no CalDAV URI to configure my client with. I did some digging this morning. Initial investigations suggest that Microsoft still lives in the past. Best they can offer is a “look-but-not-touch” export. Useless.

But wait, there’s a web client! Yeah great… let’s cram it all in a web browser. I have to deal with Slack and its ugly bloat because voice chat doesn’t work in anything else. Then there’s the thorny of web-based email and why I think that is a bad idea. No, just because a web client works for you, or a particular brand desktop client works for you, does not mean it will work for everybody.

The frustration from this end right now is that I’m trapped with nowhere to go. I’m locked in to supporting myself and Sam (I made a commitment to my dying grandmother that he’d be cared for) for another 10 years at least (who knows how long he’ll live for, he’s 7 now and Emma lived to nearly 18), so suicide isn’t an option right now, nor is simply quitting and living on the savings I have.

Most workplaces seem to be infected with this groupware-malware, so switching isn’t a viable option either. Office365 apparently has a REST API, so maybe that’s the next point of call: see if I can write a proxy to bolt-on such an interface.

Apr 112021
 

So, for the past 12 months we’ve basically had a whirlwind of different “solutions” to the problem of contact tracing. The common theme amongst them seems to be they’re all technical-based, and they all assume people carry a smartphone, registered with one of the two major app stores, and made in the last few years.

Quite simply, if you’re carrying an old 3G brick from 2010, you don’t exist to these “apps”. Our own federal government tried its hand in this space by taking OpenTrace (developed by the Singapore Government and released as GPLv3 open-source) and rebadging that (and re-licensing it!) as COVIDSafe.

This had very mild success to say the least, with contact tracers telling us that this fancy “app” wasn’t telling them anything new. So much focus has been put on signing into and out of venues.

To be honest, I’m fine with this until such time as we get this gift from China under control. The concept is not what irks me, it’s its implementation.

At first, it was done on paper. Good old fashioned pen and paper. Simple, nearly foolproof, didn’t crash, didn’t need credit, didn’t need recharging, didn’t need network coverage… except for two problems:

  1. people who can’t successfully operate a pen (Hmm, what went wrong, Education Queensland?)
  2. people who can’t take the process seriously (and an app solves this how?)

So they demanded that all venues use an electronic system. Fine, so we had a myriad of different electronic web-based systems, a little messy, but it worked, and for the most part, the venue’s system didn’t care what your phone was.

A couple, even could take check-in by SMS. Still rocking a Nokia 3210 from 1998? Assuming you’ve found a 2G cell tower in range, you can still check in. Anything that can do at least 3G will be fine.

An advantage of this solution is that they have your correct mobile phone number then and it’s a simple matter for Queensland Health to talk to Telstra/Optus/Vodaphone/whoever to get your name and address from that… as a bonus, the cell sites may even have logs of your device’s IMEI roaming, so there’s more for the contact tracing kitty.

I only struck one venue out of dozens, whose system would not talk to my phone. Basically some JavaScript library didn’t load, and so it fell in a heap.

Until yesterday.

The Queensland Government has decided to foist its latest effort on everybody, the “Check-in Queensland” app. It is available on Google Play Store and Apple App Store, and their QR codes are useless without it. I can’t speak about the Apple version of the software, but for the Android one, it requires Android 5.0 or above.

Got an old reliable clunker that you keep using because it pulls the weakest signals and has a stand-by time that can be measured in days? Too bad. For me, my Android 4.1 device is not welcome. There are people out there for whom, even that, is a modern device.

Why not buy a newer phone? Well, when I bought this particular phone, back in 2015… I was looking for 3 key features:

  1. Make and receive (voice) telephone calls
  2. Send and receive short text messages
  3. Provide a Internet link for my laptop via USB/WiFi

Anything else is a bonus. It has a passable camera. It can (and does) play music. There’s a functional web browser (Firefox). There’s a selection of software I can download (via F-Droid). It Does What I Need It To Do. The battery still lasts 2-3 days between charges on stand-by. I’ve seen it outperform nearly every contemporary device on the market in areas with weak mobile coverage, and I can connect an external antenna to boost that if needed.

About the only thing I could wish for is open-source firmware and a replaceable battery. (Well, it sort-of is replaceable. Just a lot of frigging around to get at it. I managed to replace a GPS battery, so this should be doable.)

So, given this new check-in requirement, what is someone like me to do? Whilst the Queensland Government is urging people to install their application, they recognise that there are those of us who cannot because we lack anything that will run it. So they ask that venues have a device on hand that can be used to check visitors in if this situation arises.

My little “hack” simply exploits this:

# This file is part of pylabels, a Python library to create PDFs for printing
# labels.
# Copyright (C) 2012, 2013, 2014 Blair Bonnett
#
# pylabels is free software: you can redistribute it and/or modify it under the
# terms of the GNU General Public License as published by the Free Software
# Foundation, either version 3 of the License, or (at your option) any later
# version.
#
# pylabels is distributed in the hope that it will be useful, but WITHOUT ANY
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
# A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License along with
# pylabels.  If not, see <http://www.gnu.org/licenses/>.

import argparse
import labels
import time
from reportlab.lib.units import mm
from reportlab.graphics import shapes
from reportlab.lib import colors
from reportlab.graphics.barcode import qr

rows = 4
cols = 2
# Specifications for Avery C32028 2×4 85×54mm
specs = labels.Specification(210, 297, cols, rows, 85, 54, corner_radius=0,
        left_margin=17, right_margin=17, top_margin=31, bottom_margin=32)

def draw_label(label, width, height, checkin_id):
    label.add(shapes.String(
        42.5*mm, 50*mm,
        'COVID-19 Check-in Card',
        fontName="Helvetica", fontSize=12, textAnchor='middle'
    ))
    label.add(shapes.String(
        42.5*mm, 46*mm,
        'The Queensland Government has chosen to make the',
        fontName="Helvetica", fontSize=8, textAnchor='middle'
    ))
    label.add(shapes.String(
        42.5*mm, 43*mm,
        'CheckIn QLD application incompatible with my device.',
        fontName="Helvetica", fontSize=8, textAnchor='middle'
    ))
    label.add(shapes.String(
        42.5*mm, 40*mm,
        'Please enter my contact details into your system',
        fontName="Helvetica", fontSize=8, textAnchor='middle'
    ))
    label.add(shapes.String(
        42.5*mm, 37*mm,
        'at your convenience.',
        fontName="Helvetica", fontSize=8, textAnchor='middle'
    ))

    label.add(shapes.String(
        5*mm, 32*mm,
        'Name: Joe Citizen',
        fontName="Helvetica", fontSize=12
    ))
    label.add(shapes.String(
        5*mm, 28*mm,
        'Phone: 0432 109 876',
        fontName="Helvetica", fontSize=12
    ))
    label.add(shapes.String(
        5*mm, 24*mm,
        'Email address:',
        fontName="Helvetica", fontSize=12
    ))
    label.add(shapes.String(
        84*mm, 20*mm,
        'myaddress+c%o@example.com' % checkin_id,
        fontName="Courier", fontSize=12, textAnchor='end'
    ))
    label.add(shapes.String(
        5*mm, 16*mm,
        'Home address:',
        fontName="Helvetica", fontSize=12
    ))
    label.add(shapes.String(
        15*mm, 12*mm,
        '12 SomeDusty Rd',
        fontName="Helvetica", fontSize=12
    ))
    label.add(shapes.String(
        15*mm, 8*mm,
        'BORING SUBURB, QLD, 4321',
        fontName="Helvetica", fontSize=12
    ))

    label.add(shapes.String(
        2, 2, 'Date: ',
        fontName="Helvetica", fontSize=10
    ))
    label.add(shapes.Rect(
        10*mm, 2, 12*mm, 4*mm,
        fillColor=colors.white, strokeColor=colors.gray
    ))
    label.add(shapes.String(
        22.5*mm, 2, '-', fontName="Helvetica", fontSize=10
    ))
    label.add(shapes.Rect(
        24*mm, 2, 6*mm, 4*mm,
        fillColor=colors.white, strokeColor=colors.gray
    ))
    label.add(shapes.String(
        30.5*mm, 2, '-', fontName="Helvetica", fontSize=10
    ))
    label.add(shapes.Rect(
        32*mm, 2, 6*mm, 4*mm,
        fillColor=colors.white, strokeColor=colors.gray
    ))
    label.add(shapes.String(
        40*mm, 2, 'Time: ',
        fontName="Helvetica", fontSize=10
    ))
    label.add(shapes.Rect(
        50*mm, 2, 6*mm, 4*mm,
        fillColor=colors.white, strokeColor=colors.gray
    ))
    label.add(shapes.String(
        56.5*mm, 2, ':', fontName="Helvetica", fontSize=10
    ))
    label.add(shapes.Rect(
        58*mm, 2, 6*mm, 4*mm,
        fillColor=colors.white, strokeColor=colors.gray
    ))

    label.add(shapes.String(
        10*mm, 5*mm, 'Year',
        fontName="Helvetica", fontSize=6, fillColor=colors.gray
    ))
    label.add(shapes.String(
        24*mm, 5*mm, 'Month',
        fontName="Helvetica", fontSize=6, fillColor=colors.gray
    ))
    label.add(shapes.String(
        32*mm, 5*mm, 'Day',
        fontName="Helvetica", fontSize=6, fillColor=colors.gray
    ))
    label.add(shapes.String(
        50*mm, 5*mm, 'Hour',
        fontName="Helvetica", fontSize=6, fillColor=colors.gray
    ))
    label.add(shapes.String(
        58*mm, 5*mm, 'Minute',
        fontName="Helvetica", fontSize=6, fillColor=colors.gray
    ))

    label.add(qr.QrCodeWidget(
            '%o' % checkin_id,
            barHeight=12*mm, barWidth=12*mm, barBorder=1,
            x=73*mm, y=0
    ))

# Grab the arguments
OCTAL_T = lambda x : int(x, 8)
parser = argparse.ArgumentParser()
parser.add_argument(
        '--base', type=OCTAL_T,
        default=(int(time.time() / 86400.0) << 8)
)
parser.add_argument('--offset', type=OCTAL_T, default=0)
parser.add_argument('pages', type=int, default=1)
args = parser.parse_args()

# Figure out cards per sheet (max of 256 cards per day)
cards = min(rows * cols * args.pages, 256)

# Figure out check-in IDs
start_id = args.base + args.offset
end_id = start_id + cards
print ('Generating cards from %o to %o' % (start_id, end_id))

# Create the sheet.
sheet = labels.Sheet(specs, draw_label, border=True)

sheet.add_labels(range(start_id, end_id))

# Save the file and we are done.
sheet.save('checkin-cards.pdf')
print("{0:d} cards(s) output on {1:d} page(s).".format(sheet.label_count, sheet.page_count))

That script (which may look familiar), generates up to 256 check-in cards. The check-in cards are business card sized and look like this:

That card has:

  1. the person’s full name
  2. a contact telephone number
  3. an email address with a unique sub-address component for verification purposes (compatible with services that use + for sub-addressing like Gmail)
  4. home address
  5. date and time of check-in (using ISO-8601 date format)
  6. a QR code containing a “check-in number” (which also appears in the email sub-address)

Each card has a unique check-in number (seen above in the email address and as the content of the QR code) which is derived from the number of days since 1st January 1970 and a 8-bit sequence number; so we can generate up to 256 cards a day. The number is just meant to be unique to the person generating them, two people using this script can, and likely will, generate cards with the same check-in ID.

I actually added the QR code after I printed off a batch (thought of the idea too late). Maybe the next batch will have the QR code. This can be used with a phone app of your choosing (e.g. maybe use BarcodeScanner to copy the check-in number to the clip-board then paste it into a spreadsheet, or make your own tool) to add other data. In my case, I’ll use a paper system:

The script that generates those is here:

# This file is part of pylabels, a Python library to create PDFs for printing
# labels.
# Copyright (C) 2012, 2013, 2014 Blair Bonnett
#
# pylabels is free software: you can redistribute it and/or modify it under the
# terms of the GNU General Public License as published by the Free Software
# Foundation, either version 3 of the License, or (at your option) any later
# version.
#
# pylabels is distributed in the hope that it will be useful, but WITHOUT ANY
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
# A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License along with
# pylabels.  If not, see <http://www.gnu.org/licenses/>.

import argparse
import labels
import time
from reportlab.lib.units import mm
from reportlab.graphics import shapes
from reportlab.lib import colors

rows = 4
cols = 2
# Specifications for Avery C32028 2×4 85×54mm
specs = labels.Specification(210, 297, cols, rows, 85, 54, corner_radius=0,
        left_margin=17, right_margin=17, top_margin=31, bottom_margin=32)

def draw_label(label, width, height, checkin_id):
    label.add(shapes.String(
        42.5*mm, 50*mm,
        'COVID-19 Check-in Log',
        fontName="Helvetica", fontSize=12, textAnchor='middle'
    ))

    label.add(shapes.Rect(
        1*mm, 3*mm, 20*mm, 45*mm,
        fillColor=colors.lightgrey,
        strokeColor=None
    ))
    label.add(shapes.Rect(
        41*mm, 3*mm, 28*mm, 45*mm,
        fillColor=colors.lightgrey,
        strokeColor=None
    ))

    for row in range(3, 49, 5):
        label.add(shapes.Line(1*mm, row*mm, 84*mm, row*mm, strokeWidth=0.5))
    for col in (1, 21, 41, 69, 84):
        label.add(shapes.Line(col*mm, 48*mm, col*mm, 3*mm, strokeWidth=0.5))

    label.add(shapes.String(
        2*mm, 44*mm,
        'In',
        fontName="Helvetica", fontSize=8
    ))

    label.add(shapes.String(
        22*mm, 44*mm,
        'Check-In #',
        fontName="Helvetica", fontSize=8
    ))

    label.add(shapes.String(
        42*mm, 44*mm,
        'Place',
        fontName="Helvetica", fontSize=8
    ))

    label.add(shapes.String(
        83*mm, 44*mm,
        'Out',
        fontName="Helvetica", fontSize=8, textAnchor='end'
    ))

# Grab the arguments
parser = argparse.ArgumentParser()
parser.add_argument('pages', type=int, default=1)
args = parser.parse_args()

cards = rows * cols * args.pages

# Create the sheet.
sheet = labels.Sheet(specs, draw_label, border=True)

sheet.add_labels(range(cards))

# Save the file and we are done.
sheet.save('checkin-log-cards.pdf')
print("{0:d} cards(s) output on {1:d} page(s).".format(sheet.label_count, sheet.page_count))

When I see one of these Check-in Queensland QR codes, I simply pull out the log card, a blank check-in card, and a pen. I write the check-in number from the blank card (visible in the email address) in my log with the date/time, place, and on the blank card, write the same date/time and hand that to the person collecting the details.

They can write that into their device at their leisure, and it saves time not having to spell it all out. As for me, I just have to remember to write the exit time. If Queensland Health come a ringing, I have a record of where I’ve been on hand… or if I receive an email, I can use the check-in number to validate that this is legitimate, or even tell if a venue has on-sold my personal details to an advertiser.

I guess it’d be nice if the Queensland Government could at least add a form to their fancy pages that their flashy QR codes send people to, so that those who do not have the application can still at least check-in without it, but that’d be too much to ask.

In the meantime, this at least meets them half-way, and hopefully does so which ensures minimal contact and increases efficiency.

Dec 162020
 

Well, this month has been a funny one. When we moved to the NBN back in March, we went from having a 500GB a month quota, to a 100GB a month, with a link speed of 50Mbps.

That seemed, at the time, like a reasonable compromise, since much of the time, my typical usage has been around 60~70GB a month. There’s no Netflicks subscriptions here, but my father does hit YouTube rather hard, and I lately have been downloading music (legally) from time to time.

This year has also seen me working from home, and doing a lot of Slack and Zoom calls. Zoom in particular, is pricey quota-wise, since everyone insists on running webcams. Despite this, the extra Internet use has been manageable. Couple of times we got around 90GB, maybe sailing close to the 100GB, but never over. This is what it looked like last month:

November’s Internet quota usage

This month, that changed:

Internet usage this month

Now, the start of the month data got missed because of a glitch between collectd and the Internode quota monitoring script I have. Two of the spikes can be attributed to:

  • the arrival of a Windows 10-based laptop doing its out-of-box updates (~4GB)
  • my desktop doing its 3-monthly OS updates (~5GB)

That isn’t enough to account for why things have nearly doubled though. A few prospects were in my mind:

  • a web-based script going haywire in a browser (this has happened, and cost me dearly, before)
  • genuine local user Internet activity increases
  • website traffic increases
  • server or workstation compromise

Looking over the netflow data

Now, last time I had this happen, I did two things:

  • I set up collectd/influxdb/Grafana to be able to monitor my Internet usage and quota
  • I set up nfcapd on the border router to monitor my usage

This is pretty easy to set up in OpenBSD, and well worth doing.

I keep about 30 days’ worth of netflow data on the border router. So naturally, I haul that back to my workstation and run nfdump over it to see what jumps out.

Looking through the list of “flows”, one target identified was a development machine hosted at Vultr… checking the IP address, revealed it was one of the WideSky test instances my workplace uses, about 5GB of HTTP requests and about 4GB of VPN traffic — admittedly the couple of WideSky hubs I have here have the logging settings cranked high.

That though doesn’t explain it. The bulk of the traffic was scattered amongst a number of hosts. I didn’t see it until I tried aggregating it by /16 subnet:

RC=0 stuartl@rikishi /tmp $ nfdump -R /tmp/nfcapd -A srcip,dstip -o long6 -O bytes 'net 114.119.0.0/16'  
Date first seen          Duration Proto                             Src IP Addr:Port                                 Dst IP Addr:Port     Flags Tos  Packets    Bytes Flows
2020-11-27 23:11:30.000 1630599.000 0                             150.101.176.226:0     ->                         114.119.146.185:0     ........   0    4.7 M    6.8 G  2535
2020-11-22 13:02:41.000 2099541.000 0                             150.101.176.226:0     ->                         114.119.133.234:0     ........   0    4.3 M    6.1 G  2376
2020-11-18 14:38:42.000 2439079.000 0                             150.101.176.226:0     ->                         114.119.140.107:0     ........   0    3.8 M    5.4 G  2418
2020-11-20 10:43:58.000 2280070.000 0                             150.101.176.226:0     ->                          114.119.141.52:0     ........   0    3.7 M    5.3 G  2421
2020-11-21 22:34:35.000 2151244.000 0                             150.101.176.226:0     ->                         114.119.159.109:0     ........   0    3.4 M    4.9 G  2446
2020-11-24 00:11:52.000 1972657.000 0                             150.101.176.226:0     ->                          114.119.136.13:0     ........   0    3.4 M    4.8 G  2399
2020-11-25 04:24:32.000 1870854.000 0                             150.101.176.226:0     ->                         114.119.136.215:0     ........   0    3.3 M    4.8 G  2473
2020-11-24 15:49:55.000 1916848.000 0                             150.101.176.226:0     ->                           114.119.151.0:0     ........   0    3.0 M    4.4 G  2435
2020-11-27 20:15:43.000 1641316.000 0                             150.101.176.226:0     ->                         114.119.129.181:0     ........   0    2.6 M    3.7 G  2426
2020-11-27 21:38:37.000 1636635.000 0                             150.101.176.226:0     ->                          114.119.159.16:0     ........   0    2.5 M    3.6 G  2419
2020-11-27 23:11:30.000 1630599.000 0                             114.119.146.185:0     ->                         150.101.176.226:0     ........   0    4.1 M  175.9 M  2535
…
2020-11-19 22:02:04.000     0.000 0                             150.101.176.226:0     ->                         114.119.138.111:0     ........   0        3      132     1
2020-11-25 03:37:11.000     0.000 0                             150.101.176.226:0     ->                          114.119.152.27:0     ........   0        3      132     1
2020-12-06 19:59:49.000     0.000 0                             150.101.176.226:0     ->                         114.119.151.153:0     ........   0        3      132     1
2020-11-22 08:23:11.000     0.000 0                             150.101.176.226:0     ->                          114.119.130.23:0     ........   0        3      132     1
2020-11-25 15:43:47.000     0.000 0                             150.101.176.226:0     ->                         114.119.128.219:0     ........   0        3      132     1
2020-11-24 09:05:13.000     0.000 0                             150.101.176.226:0     ->                          114.119.140.85:0     ........   0        3      132     1
Summary: total flows: 56059, total bytes: 51.7 G, total packets: 65.0 M, avg bps: 150213, avg pps: 23, avg bpp: 794
Time window: 2020-11-13 11:01:52 - 2020-12-16 20:19:41
Total flows processed: 39077053, Blocks skipped: 0, Bytes read: 2698309352
Sys: 3.744s flows/second: 10436251.9 Wall: 15.108s flows/second: 2586482.6 

51.7GB in a month!!! Drilling further, I noted it was mostly targeted at TCP ports 80 and 443, and UDP port 53. Web traffic, in other words. Reverse look-up on a randomly selected IP showed the reverse pointer petalbot-xxx-xxx-xxx-xxx.aspiegel.com, and indeed, in server logs for various sites I host, I saw PetalBot in the user agent.

Plucking some petals off PetalBot

So, I needed to put the brakes on this somehow. I’m fine with them indexing my site, just they should have some consideration and restraint about how quickly they do so.

Thus, I amended pf.conf:

# Rate-limited "friends"
ratelimit_dst4="{ 114.119.0.0/16 }"
#ratelimit_dst6="{ }"

# Traffic shaping queues
queue root on $external  bandwidth 25M max 25M
queue slow parent root   bandwidth 256K max 512K
queue bulk parent root   bandwidth 25M default

# …

# Rate-limit certain targets
pass out on egress proto { tcp, udp, icmp } from any to $ratelimit_dst4 modulate state (pflow) set queue slow
#pass out on egress proto { tcp, udp, icmp6 } from any to $ratelimit_dst6 modulate state (pflow) set queue slow

So, the first line defines the root queue on my external interface, and sets the upload bandwidth for 25Mbps (next month, I will be dropping my speed to 25Mbps in favour of an “unlimited” quota).

Then, I define a queue which is restricted to 256kbps (peak 512kbps), and define all traffic going to a specific list of networks, to use that queue. PetalBot should now see a mere 512kbps at most from this end, which should severely crimp how quickly it can guzzle my quota, whilst still permitting it to index my site.

Yesterday, PetalBot chewed through 8GB… let’s see what it does tomorrow.

Dec 012020
 

The last few years have been a testing time for world politics. Recent events have seen much sabre-rattling, but really, none of this has suddenly “appeared”… it’s been slowly bubbling away for some time now.

Economic tunnel-vision

For a long time now, much of our world has revolved around the unit of currency. Call it the US dollar, the Australian dollar, the British Pound, Chinese Yuan, whatever… for the past 50 years or so, we have been “seduced” by two concepts which developed in the latter part of last century:

  • economies of scale
  • just-in-time production

The concepts are on the surface, fairly simple.

Just-in-time production forgoes having a large stock and inventory of components to feed your supply-lines in favour of ordering just enough of what you need to fulfil the orders you have active at the present moment. So long as nothing disrupts your supply lines, all is rosy. You might keep a small inventory just as a buffer, but in general, that might only last a day or so.

Economies of Scale was the other concept that really took hold last century, and was the reason why smaller workshops got shut down in favour of making lots of a widget in one central place, and shipping it out to everywhere from that one point.

Again, works great, until something happens in that place where you are doing the manufacturing, or something happens that hampers your ability to shift parts or product around.

The latter in particular took a dark turn when instead of making things close to where the demand was, “we” instead outsourced it, shifting the production to places where the labour was cheapest. As a consequence, many countries are forced to import as they no longer have the expertise or capabilities to manufacture products locally.

Both these concepts were ideas conceived with people wearing rose-coloured glasses, they emphasise cost-cutting over contingency plans on the grounds that disruption to manufacturing and supplies are unlikely events.

The rise of “the world’s factory”

Over time, companies pushed this concept of centralised manufacturing to extremes, whereby they were largely making things in one place. Apple for instance, were leaning heavily on Foxconn in China for the manufacture of their hardware.

None of this is without precedent, when I was growing up, Nike used to cop a lot of flack for the exploitation of workers in various third-world localities.

That said, history has often had something to say about putting all of one’s eggs in a single basket. There’s mostly nothing wrong with having products made in China, the problem is having things made exclusively in China.

At first, products made in China were seen as dodgy knock-offs of things made elsewhere. The same was said of things made in Japan in the 1950s and 1960s… but then Japan improved their systems and processes, and with it, the products they made improved too. In the case of China, initially things were done “cheaply”, which gave rise to a perception that things made in China were all “dodgy”.

Over time, processes again improved, and now there are some great examples of products and services, which are designed and built by people based in China. Stuff that works, and is reliable. There are some very smart people over there who are great at their craft.

That said, manufacturing all revolves around the dollar, and so when it came to cutting costs, something had to give.

Trouble in Xinjiang

With this global demand for manufacturing, China had a problem trying to find people to do the mundane jobs. Quality had to be maintained, and so some organisations over there tried to solve the cost problem a different way: cheaper labour.

Now, it’s well known that China’s government is not a government that particularly values individualism. This is evident in the manner in which the Tienanmen Square protests were so violently silenced.

The Uighur Muslim community is one such group that has been in their sights for a long time. This is a group that has been clamped-down on for more than 6 years. Over time, a narrative was developed that tried to cast this group as being “trouble makers” in need of “re-education”.

Over time, members of this community found themselves co-opted into being the cogs in this “global” factory. At first, such actions were hidden from view, including from the direct customers of these factories.

COVID-19 makes its entrance

So, over time, global manufacturing has shifted to China, in some cases involving forced labour in the effort to drive the cost down and make the end product seem more competitive.

Much of these problems have been hidden from the outside world, but for now, whilst we’re starting to learn of these issues, we still do the majority of our manufacturing in one country.

Then, about this time last year, a bizarre respiratory condition started showing up in Wuhan. Nobody knew much about this condition, other than the fact that it was discovered it was highly contagious.

Even today, we’re still unsure exactly how it came about, but the smart money is that it jumped from some reservoir host such as a bat, via some intermediate host, to humans. Bats in particular are major carriers of all kinds of corona-viruses, and as such, are a highly probably suspect in this.

I do not believe it is synthetic in origin.

COVID-19 threw a major spanner in the works for everybody. Community event calendars looked like an utter train-wreck with cancellations and deferrals all over the place. For me, some of the casualties I was looking forward to include the 2020 Yarraman to Wulkuraka bike ride and numerous endurance horse-riding events (where I assist in operations).

It also threw a major spanner in the works for just-in-time manufacturing (since freight was running inefficiently due to a lack of flights) and rolling shut-downs across China as COVID-19 did its worst.

Some businesses have already closed for good.

Knee-jerk reactions

Numerous countries, notably ours, called for an investigation into the origins and initial handling of the COVID-19 pandemic.

I for one, think such an investigation should go ahead. We owe it to the people who have lost their lives, and those who have lost their livelihoods, to this condition, that we try and find out what went wrong. It’s not about blaming people.

We’re not interested in who made the mistakes, it’s more a question of what the mistakes were. This event will repeat itself again, and again, until such time as we get to understand what “we” (globally) did wrong.

China’s government does not seem to have seen it this way. It’s as if they see it as a witch-hunt. As a result, we as a nation that seems to have been singled-out, with heavy tariffs placed on goods that we as a nation export to China.

Notably absent in this trade-war is iron ore, partially because the other major producer of iron ore, Brazil, has been left a complete basket-case by this pandemic, and Australia was a major supplier of iron ore long before COVID-19 reared its ugly head.

A plan “B”

Right now, things are escalating in this diplomatic row. Whilst the politicians are trying to resolve this with as little fuss as possible, I think China’s position is becoming very clear. They’ve told the world “F You” in no uncertain terms.

We are most definitely dealing with a rebellious and violent teenager, more than capable of smashing holes in a few walls and inflicting grievous bodily harm.

I think it would be wonderful if things could be reset back to the way they were, but at the same time, I think that really, we may need to realise that “peak China” days may be behind us now.

I know there are organisations that have built their entire business model around exports to China, and that literally overnight, conditions have changed which now make that greatly risk business viability.

They are geared around the huge appetite that this country’s people have previously demonstrated for our goods and services. I think now, more than ever, we should be looking around. Where else can I outsource to? Where else can I sell to? How can we make do with less demand?

If China does come around, then sure, maybe a certain portion of your market can be serviced there. I think it folly though to be reliant on one single region for your supply or demand though.

Two or three alternatives may not totally balance things, but having at least a partial income is better than none at all!

The Australian coat-of-arms features the emu and the kangaroo. These animals are quite different from one another, but they share a few common attributes. Yes, some might say they’re two of the less brainy members of the animal kingdom, but also, they are not known for going “backwards”.

Whilst we momentarily look over our shoulder at our past, I think it important that we keep moving “forwards”.

Learning from our mistakes

I think in all of this, it’s fair to say none of us are perfect. Yes, our SAS troops have been implicated in some truly horrendous war crimes. Not all of them, thankfully, but enough to cast a cloud over the military in general. Some of the Army’s chopper pilots are not exactly famous for fast reporting of fires either.

We’re investigating this, and yes, some of the top brass are ducking for cover, as it’s likely some know more than they’ve been letting on. An analysis of what went wrong will be done, and we, collectively, will learn from those mistakes.

In the case of COVID-19, for the first few months of 2020, we were told “No, we don’t need help, we’re fine, we’ve got this!”. Taiwan saw this, and immediately sprang to action, as did many other nations close to China. They’ve seen similar things happen before (SARS, MERS), and so maybe their scepticism shielded them somewhat.

I think one of the biggest lessons of all is to realise that asking for help is not a sign of weakness, it’s a sign of maturity. We’re on this planet, together. We are in this mess, together. We need to work this all out, together.

What am I doing?

So, based on the above… where do I sit? Not on the fence.

I myself have started seriously considering my suppliers.

In particular, I have practically destroyed my credentials for AliExpress, having bought the last few things I’m likely to want from there. I’ve ordered printed circuit boards from a supplier in Hong Kong.

During last year, I had ordered a few PCBs from their sister factory in mainland China as I was concerned about the civil unrest there (and on that, I do think the people there have a valid point to raise) causing delays, but had originally intended to move things back once things settled down. However, with China being so adamant that Hong Kong is “theirs”, I’m forced to treat Hong Kong the same as mainland China.

As such, I’ll probably be looking to the US, Europe or India to evaluate options there. I might still use the old Hong Kong supplier, but they won’t be the sole supplier.

Where possible, I’ll probably be paying more attention to country-of-origin for products I buy from now on, and preferring local options where possible. This won’t always be the case, and some things will have to be imported from China, but I aim to diversify my sources.

I may start making things myself. Yes, time-consuming, expensive, but ultimately, this means I become the master of my own destiny, it’s likely a worthwhile journey to undertake.

Above all, I am not out to discriminate against the people of China. I may not always agree with some of their customs, but that does not give one the right to indulge in racism. My only real complaint with China at this time, is the conduct of its government.

Maybe with time, diplomatic relations might turn this around, and we may see a more co-operative Chinese government, only time will tell on that.

In the meantime, I plan to not reward their government for what I consider, bad behaviour.

Sep 052020
 

So, this is not really news… for the past 12 months or so, the scammers have been busy. They’ve been calling us long before we moved to the NBN, and of course we’ve just hung up the moment they started their spiel. The dead giveaway is the seconds of silence at the start of the call. Dead silence.

Of course, it’s not just the NBN, we’ve had “Amazon Prime”, “Visa”, “Telstra” and others call. Far and above all others has been NBN-related scams.

The latest on the NBN front is they claim your connection has been “compromised” by “other users”, in a British accent.

This is the call I received this morning. You can hear other callers in the back-ground. This is not a professional call-centre, this is a back-yard operation!

The home number recently moved from the PSTN to a VoIP service, so this actually gives me a lot of scope for dealing with this. For now, it’s a manual process: when they call, put them on hold. If I put someone on hold on this number, you better be a Deborah Harry fan!

Long term, I’ll probably look at seeing if I can sample the first 2 seconds of call audio, and if silent, direct the call to a voicemail service or IVR menu. In the meantime, it’s a manual process.

Thankfully we get caller ID now, something Telstra used to charge for.

MoH considerations

There’s three big considerations with music on hold:

  1. Licensing: You need to do the research into how music is licensed in your country. If you want to be safe, go look for something that is “public domain” or one of the “Creative Commons” family of licenses. In Australia, you probably want to have a look at this page if you want to use a piece of commercial music (like “Hangin’ On The Telephone”).
  2. Appropriateness: is the caller likely to get offended by your choice of hold music? (Then again, maybe that’s your goal?)
  3. Suitability for your chosen audio CODEC: Some audio CODECs, particularly the lower-bitrate ones, do an unsurprisingly terrible job, with music.

Regarding point (3) always test your music choice! Try different CODEC settings, and ensure it sounds “good” with ALL of them. Asterisk actually supports transcoding, but will choose the format that takes the least effort. RIFF Wave files (.wav) can be used too, but they must be mono files.

I slapped a CD-quality 44.1kHz stereo version in there, and wondered why it got ignored: that’s why — it wasn’t mono and Asterisk won’t down-mix.

Signed 16-bit linear is a pretty safe bet: effort of going to that to PCMA/PCMU (G.711a/G.711u) isn’t a big deal, but to anything else, you’re at the mercy of the CODEC implementation. Using G.722, things sounded fine, but I found even with Speex settings cranked right up (quality=10 complexity=10 enhancement=true), my selection of audio sounded terrible in Ultra-wideband Speex mode. I wound up with the following in my MoH directory:

vk4msl-gap# ls -l /usr/local/share/moh/
total 8280
-rw-r--r--  1 root  wheel   527836 Aug 29 17:02 moh.sln
-rw-r--r--  1 root  wheel  1055670 Aug 29 17:02 moh.sln16
-rw-r--r--  1 root  wheel  2111342 Aug 29 17:01 moh.sln32
-rw-r--r--  1 root  wheel   104793 Sep  5 12:17 moh.spx
-rw-r--r--  1 root  wheel   177879 Sep  5 12:34 moh.spx16
-rw-r--r--  1 root  wheel   184617 Sep  5 12:16 moh.spx32
  • .sln* is for 16-bit signed linear, the 16 and 32 suffixes refer to the sample rate, so 16kHz (wideband) and 32kHz (ultra-wideband). These should otherwise be “raw” files (no headers). Use sox <input> -r <rate> -b 16 -e signed-integer -c 1 <output>.sln to convert.
  • .spx* is Speex: Here again, I’ve got 8kHz, 16kHz and 32kHz versions. These were encoded using the following command: speexenc --quality 10 --comp 10 moh.wav moh.spx

There are various other CODEC selections, but right now, I’ve just focussed on signed linear and Speex since the latter is what needs careful attention paid. I tested between my laptop running Twinkle and the ATA on my network, and when I placed the call on hold from my laptop it sounded fine there, so I figure it’ll be “good enough”.


“Visa Security Department”

So, had “Visa” call me this morning… this too, is another scam. Anonymous caller. Bear in mind I do not actually have a credit card. Never have had one, never will.

“Visa security department”

They didn’t stick around, seems their system just drops the call if it hears a noise which isn’t a DTMF tone.

Interestingly, both this call, and the previous one were G.711u (µ-law PCM). Australia normally uses A-law PCM. America uses µ-law encoding. What’s the difference? Both are logarithmic encoding schemes. µ-law encoding has a wider dynamic range, however A-law has less distortion for quieter signals.


“Amazon”

“Amazon”

Almost the same structure as before. Audio CODEC was G.729 this time.

Aug 052020
 

Some people make fun of my plain-text emails, but really, I think it’s time we re-consider our desire for colours, hyperlinks and inline images in email messages, especially for those who use web-based email clients as their primary email interface.

The problem basically boils down to this: HTML gives too much opportunity for mischief by a malicious party. In most cases, HTML isn’t even necessary to convey the information required. Tables are about the only real “feature” that is hard to replicate in plain text, for everything else there’s reasonable de-facto standards already in existence.

Misleading hyperlinks

HTML has a feature where a link to a remote page can take on any descriptive text the author desires, including images and other valid URIs. For example, the following piece of HTML code is perfectly valid:

<a href="http://www.google.com.malicious.website.example.com/">
   http://www.google.com
</a>

There are many cases where this feature is “useful”, however in an email, it can be used to disguise phishing attempts. In the above example, the link is claiming to be to Google’s search website, however would otherwise re-direct that user to some other, likely malicious, website.

Granted, not every user can read a URI to determine if it is safe. There are adults who “grew up with the Internet”, that have never typed a URI in an address bar ever, instead relying on tools like search engines to locate websites of interest.

However, it would seem disingenuous to say that because a proportion of the community cannot read a URI, we should hide any and all links from everybody. For that small portion, showing the links won’t make a difference, but it will at least make it easier to avoid such traps.

Media exploits

Media decoders are written by humans, and humans are imperfect, thus it is fair to say there are media decoders that contain bugs, some of which could be disastrous for computer security.

Microsoft had such a problem in their GDI+ JPEG decoder back in 2004. More recently, there was a kernel-level security vulnerability in their TrueType font parser.

Modern HTML allows embedding of all this, and more. Most email clients will also allow you to “preview” an email without opening it. If an email embeds inline media which exploits vulnerabilities such as the one above, just previewing it will be sufficient to gain access.

Details are scarce, but it would appear it was a vulnerability along these lines that allowed unauthorised access into the Australian National University back in 2018.

Scripting

Modern web standards allow all kinds of means for embedding scripts, that is, small pieces of interpreted code which runs client-side in the HTML renderer. ECMAScript (JavaScript) can be embedded:

  • in <script> tags (the traditional way)
  • inside a hyperlink using a javascript: URI
  • HTC and XBL features in Internet Explorer and Mozilla Firefox, respectively.

Probably lots more ways I haven’t thought about.

Web-based email clients

Now, a stand-alone email client such as Microsoft Outlook, Eudora or Mozilla Thunderbird can simply not implement the scripting features, however the problem is highly acute where web-based email clients are used.

Here, you’re viewing an email in a HTML engine that has complete media and scripting capabilities. There’s dozens of ways to embed both forms of content into a blob of HTML, and you are entirely at the mercy of your web-based email client’s ability to sanitise the HTML before it dumps it inside the DOM tree that represents your email client.

As far as the web browser is concerned, the “email” is just another web page, and will not hesitate to execute embedded scripts or render inline media, whether the user wishes it to or not.

It’s not known what ANU uses for their email infrastructure, but many universities are big fans of web-based email since it means they don’t have to explain to end users how to configure their email clients, and provides portability for their users.

Putting users at risk

Despite the above, it would appear there are lots of organisations that are completely oblivious to this problem, and insist on forcing people to render their emails as HTML, putting their customers/users at risk of security breach.

The purpose of multiple formats in the same email is to provide alternate formats of the same content. Not to provide totally different emails because you can’t be stuffed!

For example, my workplace’s hosting provider, recently sent us an email, which when viewed as plain text, read as follows:

Hello Client,
 
Unfortunately your email client is outdated and does not support HTML emails, our system uses HTML emails as standard. You will NOT be able to read this email.
 
HOW DO I READ THIS EMAIL?
 
To read this email please login to your domain manager https://hostingprovider.example.com/login/ and click on Notifications to see a list of all sent emails.
 
Thank You
 
Customer Support

The suggestion that an email client configured to read emails as plain text, counts as it being “outdated” is naïve in the extreme, and I’d expect a hosting provider to know better. I’m thankful I personally don’t purchase services from them!

Then there’s financial service providers. One share registry’s handling of the situation is downright abusive:

Link Market Services sent numerous emails that looked exactly like this.

Yeah, rather than just omitting the text/plain component and letting the email client at this end try to render the HTML as plain text (which works reasonably well in many cases), in this case, they just sent an empty text/plain body:

From: …redacted… <comms@linkmarketservices.com.au>
To: …redacted…
Reply-To: donotreply@linkmarketservices.com.au
Date: Wed, 29 Jul 2020 04:42:30 +0000
Subject: …redacted… Funds Attribution Managed Investment Trust Member Annual
 Statement
Content-Type: multipart/alternative;
 boundary=--boundary_55327_8fbc43bd-48f3-4aa1-9ab7-9046df02b853
ZMID: 9f485235-9848-49cf-9a66-62c215ea86ba-1
Message-ID: <0100017398e10334-d45a0a83-ff4d-4b83-8d19-146b100017f6-000000@us-east-1.amazonses.com>
X-SES-Outgoing: 2020.07.29-54.240.9.110
Feedback-ID: 1.us-east-1.oB/l4dCmGdzC38jjMLirCbscajeK9vK6xBjWQPPJrkA=:AmazonSES


----boundary_55327_8fbc43bd-48f3-4aa1-9ab7-9046df02b853
Content-Transfer-Encoding: quoted-printable
MIME-Version: 1.0
Content-Type: text/plain; charset="utf-8"


----boundary_55327_8fbc43bd-48f3-4aa1-9ab7-9046df02b853
Content-Transfer-Encoding: base64
MIME-Version: 1.0
Content-Type: text/html; charset="utf-8"

PCFET0NUWVBFIGh0bWw+Cgo8aHRtbCBsYW5nPSJlbiI+CjxoZWFkPgo8bWV0YSBjaGFyc2V0PSJ1
dGYtOCI+CjxtZXRhIGNvbnRlbnQ9IndpZHRoPWRldmljZS13aWR0aCwgaW5pdGlhbC1zY2FsZT0x
IiBuYW1lPSJ2aWV3cG9ydCI+CjxtZXRhIGNvbnRlbnQ9IklFPWVkZ2UiIGh0dHAtZXF1aXY9Ilgt

Ohh yeah, I’m so fluent in BASE64! I’ve since told them to send it via snail mail. Ensuring they don’t burn down forests posting blank sheets of A4 paper will be their problem.

The alternative: wiki-style mark-up

So, our biggest problem is that HTML does “too much”, so much that it becomes a liability from a security perspective. HTML wasn’t the first attempt at rich text in email… some older email clients used enriched text.

Before enriched text and HTML, we made do with various formatting marks, for instance, *bold text might be surrounded by asterisks*, and /italics indicated with forwardslashes/. _Underlining_ could be done too.

No there was no colour or font size options, but then again this was from a time when teletype terminals were not uncommon. The terminals of that time only understood one fixed-size font, and most did not do colour.

More recently, Wikis have built on this to allow for some basic mark-up features, whilst still allowing the plain text to be human readable. Modern takes of this include reStructured Text and Markdown, the latter being the native format for Wikis on Github.

Both these formats allow for embedding images inline and for tables (Markdown itself doesn’t do tables, but extensions of it do).

In email clients such images should be replaced with place-holders until the user clicks a button to reveal the images (which they should only click if they trust the sender).

Likewise, hyperlinks should be rendered in full, e.g. in a web-based client, the link [a cool website](http://example.com/) might be rendered as <a href="http://example.com">[a cool website](<code>http://www.example.com</code>)</a> — thus allowing for malicious links to be more easily detected. (It also makes them printable.) Only plain text should be permitted as a “label” for a hyperlink.

Use of such a mark-up format would have a number of benefits:

  • the format is minimal, meaning a much reduced attack surface for security vulnerabilities
  • whilst minimal, it would cover the vast majority of peoples’ use cases for HTML email
  • the mark-up is light-weight, reducing bandwidth for those on low-speed links or using lower-power devices

The downside might be for businesses, which rely on more advanced features in HTML to basically make an email look like their letter head. The business community might wish to consider the differences between a printed letter sent via the post, and an email sent electronically. They are different beasts, and trying to treat one as a substitute for the other will end in tears.

In any case, a simple letter head could be embedded as an inline image quite safely if such a feature was indeed required.

It is in our interests to curtail the features used in email communications if we intend to ensure communications remain safe and reliable.

Jul 152020
 

At the last federal election, we started seeing this meme floating about the Internet…

“Quexit” meme, (source: ABC)

Of course, we in Queensland can do memes too…

“Vexit” anyone?

That said, one hopes Victoria can get over their COVID-19 issues and come join the rest of us. This isn’t the (Dis)United States of America, this is Australia, we’re one country, and it’s our problem collectively to sort out, so let’s just put our differences aside and get on with it!

May 222020
 

For the past 2 years now, there’s been quite a bit in the press about the next evolution of mobile telephony standards.

The 5G standard is supposed to bring with it higher speeds and greater user density handling. As with a lot of systems, “5G” itself, describes a family of standards… some concern the use of millimetre-wave communications for tower-to-handset communications, some cover the communications channels for more modest frequencies in the high UHF bands.

One thing that I really can’t get my head around is the so-called claims of health effects.

Now, these are as old as radio communications itself. And for sure, danger to radio transmissions does increase with frequency, proximity and transmit power. There is a reason why radio transmitter sites such as those that broadcast medium wave radio or television are fenced off: electrocution is a real risk at high power.

0G: glorified two-way radios

Mobile phones originally were little more than up-market cordless phones. They often were a luggable device if they were portable at all. Many were not, they were installed into a vehicle (hence “mobile”). No such thing as cell hand-over, and often incoming calls had to be manually switched.

Often the sets were half-duplex, and despite using a hand-set, would have a very distinctive “radio” feel to them, requiring the user use a call-sign when initiating a call, and pressing a push-to-talk button to switch between listening and talking modes.

These did not see much deployment outside the US or maybe Europe.

1G: cellular communications

Back in the late 80s, when AMPS mobile phones (1G) were little more than executive toys, there might not have been much press about, but I’m sure there’d be anecdotal evidence of people being concerned about “radiation”.

If any standard was going to cause problems, it’d have been 1G, since the sets generally used much higher transmit power to compensate for the lack of coverage. They were little more than glorified FM transceivers with a little digital control channel on the side which implemented the selective calling and cell hand-off.

This was the first standard we saw here in Australia, and was the first to be actually practical. Analogue services didn’t last that long, and because of the expense of running AMPS services, they were mostly an expensive luxury. So that did limit its up-take.

2G: voice goes digital

The next big change was 2G, which replaced the analogue FM voice channel and used digital modulation techniques. GSM (which used Gaussian Minimum Shift Keying) and CDMA (which used phase shift keying) encoded everything in a single digital transmission.

This meant audio could be compressed (with some loss in fidelity), and have forward error correction added to make the signal more robust to noise. The cells could handle more users than the 1G services could. Transmit power could be reduced, improving battery life and the sets became cheaper to make and services became more economical.

Then came all the claims that 2G was going to cause us to develop brain cancer.

Now, many of those 2G services started popping up in the mid 90s… has there been a mass pandemic of cancer cases? Nope! About the only thing GSM was bad for, was its ability to leak into any audio frequency circuit.

2G went through a few sub-revisions, but it basically was AMPS done digitally, so fundamentally worked much the same. A sore point was how data was handled. 2G and its predecessors all tried to emulate what the wired network was doing: establishing a dedicated circuit between callers.

The Internet was really starting to get popular, and people wanted a way to access it on the move. GPRS did allow for some of that, but it really didn’t work that well due to the way 2G saw the world, so things moved on.

3G: packet switching

The big change here was the move from “circuits” to sending data around in packets. This is more like how the Internet operates, and so it meant the services could better support an Internet connection.

Voice still went the old-fashioned way, dedicated circuits, since the QoS (quality of service) could be better maintained that way.

The cells could support more users than 2G could, and the packet mode meant mobile Internet finally became a “thing” for most people.

I don’t recall there being the same concern about health as there was for 2G… it was probably still simmering below the surface. Services were deployed further afield and of course, the uptake continued.

4G: bye bye circuit switching

4G or LTE is the current standard that most of us are using. The biggest change is it ditches the circuit switching used in 1G, 2G and 3G. Voice is done using VoLTE… basically the voice call is sent the same way calls are routed over the Internet.

The cell towers are no longer trying to keep a “circuit” connected to your phone as you move around, instead it’s just directing packets. It’s your handset’s problem to sort out whether it heard a given packet already, or re-arrange incoming packets if they arrive out-of-order.

To make this work, obviously the latency inherent in 3G had to be addressed. As a sweetener, the speeds were bumped up, and the voice CODEC could be updated, so we gained wide-band voice calls. (Pity Bluetooth hasn’t kept up!)

5G: new frequencies, higher speed, smaller cells

So far, the cellular standards have largely co-existed in the same frequency bands. 4G actually varies quite a bit in frequency, but basically there are bands from the low UHF around 410MHz right up to microwave at 2600MHz.

Higher frequencies

5G has been contentious because some implementations of it reach even higher. Frequency Range 1 used in the 5G NR standard is basically much the same as 4G, but frequency range 2 soars as high as 40GHz.

Now, in terms of the electromagnetic spectrum, compared to other forms of radiation that we rely on for survival (and have done ever since life first began on this planet), this might as well be DC!

Infrared radiation, which is the very bottom of the “light” spectrum, starts at 300GHz. At these frequencies, we typically forget about frequencies, and instead consider wavelengths (1mm in this case). Visible light is even higher, 430THz (yes, that’s T for tera!).

Now, where do we start to worry about radiation? The nasty stuff begins with ultraviolet radiation, specifically UVC which is at a dizzying 1.1PHz (yes, that’s peta-hertz). It’s worth noting that UVB, which is a little lower in frequency can cause problems when exposure is excessive… however none is dangerous too, you actually need UVB exposure on your body to produce vitamin D for survival!

Dielectric heating

So that’s where the danger is in terms of frequency. I did mention that danger also increases with power… this is why microwave ovens, which typically operate at a fairly modest 2.4GHz frequency, pose a risk.

No, they won’t make you develop cancer, but the danger there is when there’s a lot of power, it can cause dielectric heating. That is, it causes molecules to move around, and in doing so, collide transferring energy which is then given off as heat. It happens at all frequencies in the EM spectrum, but it starts to become more practical at microwave frequencies.

To do something like cook dinner, a microwave oven bombards your food with hundreds of watts of RF energy at it. The microwave has a thick RF shield around it for a reason! If that shield is doing what it should, you might be exposed to no more than a watt of energy escaping the shield. Not enough to cause any significant heating.

I hear that if you put a 4W power amp on a 2.4GHz WiFi access point and put your hand in front of the antenna, you can “feel” framing packets. (Never tried this myself.) That’s pretty high power for most microwave links, and would be many orders of magnitude more than what any cell phone would be capable of.

Verdict: not a health risk

In my view, there’s practically no risk in terms of health effects from 5G. I expect my reasoning above will be thoroughly rubbished by those who are protesting against the roll-out.

However, that does not mean I am in favour of 5G.

The case against 5G

So I seem to be sticking up for 5G above, but let me make one thing abundantly clear, for us here in Australia, I do not think 5G is the “right” thing for us to use. It’s perfectly safe in terms of health effects, but simply the wrong tool for the job.

Small cells

Did I mention before the cells were smaller? Compared to its predecessors, 5G cells are tiny! The whole point of 5G was to serve a large number of users in a small area. Think of 10s of thousands of people crammed into a single stadium (okay, once COVID-19 is put to bed). That’s the use case for 5G.

5G’s range when deployed on the lower bands, is about on par with 4G. Maybe a little better in certain ideal conditions with higher speeds. This is likely the variant we’re most likely to see outside of major city CBDs. How reliable it is at that higher speed remains to be seen, as there’s a crazy amount of DSP going on to make stuff work at those data rates.

5G when deployed with mmWave bands, barely makes 500 metres. This will make deployment in the suburbs prohibitively expensive. Outdoor Wi-Fi or WiMAX might not be as fast, but would be more cost-effective!

Processor load

Did I mention about the crazy amount of DSP going on? To process data streams that exceed 1Gbps, you’re doing a lot of processing to extract the data out of the radio signal. 5G leans heavily on MIMO for its higher speeds, basically dividing the high-rate stream into parts which are directed to separate antennas. This reduces the bandwidth needed to achieve a high data rate, but it does make processing the signal at the far end more complex.

Consequently, the current crop of 5G handsets run hot. How hot? Well, subject them to 29.5°C, and they shut down! Now, think about the weather we get in this country? How many days have we experienced lately where 29°C has been a daily minimum, not a maximum?

5G isn’t the future for Australia

We need a wireless standard that goes the distance, and can take the heat! 5G is not looking so great in this marathon race. Personally, I’d like to see more investment into the 4G services and getting those rolled out to more locations. There’s plenty of locations that are less than a day’s drive from most capital cities, where mobile coverage is next to useless.

Plenty of modern 4GX handsets also suffer technical elitism… they see 3G services, but then refuse to talk to them, instead dropping to -1G: brick emulation. There’s a reason I stick by my rather ancient ZTE T83 and why I had high hopes for the Kite.

I think for the most part, many of the wireless standards we see have been driven by Europe and Asia, both areas with high population densities and relatively cool annual temperatures.

It saddens me when I hear Telstra tell everybody that they “aspire” to be a technology company, when back in the early 90s, Telecom Australia very much was a technology company, and a well respected trail-blazing one at that! It’s time they pulled their finger out and returned to those days.

May 122020
 

So, the other day I pondered about whether BlueTrace could be ported to an older device, or somehow re-implemented so it would be compatible with older phones.

The Australian Government has released their version of TraceTogether, COVIDSafe, which is available for newer devices on the Google and Apple application repositories. It suffers a number of technical issues, one glaring one being that even on devices it theoretically supports, it doesn’t work properly unless you have it running in the foreground and your phone unlocked!

Well, there’s a fail right there! Lots of people, actually need to be able to lock their phones. (e.g. a condition of their employment, preventing pocket dials, saving battery life, etc…)

My phone, will never run COVIDSafe, as provided. Even compiling it for Android 4.1 won’t be enough, it uses Bluetooth Low Energy, which is a Bluetooth 4.0 feature. However, the government did one thing right, they have published the source code. A quick fish-eye over the diff against TraceTogether, suggests the changes are largely superficial.

Interestingly, although the original code is GPLv3, our government has decided to supply their own license. I’m not sure how legal that is. Others have questioned this too.

So, maybe I can run it after all? All I need is a device that can do BLE. That then “phones home” somehow, to retrieve tokens or upload data. Newer phones (almost anything Android-based) usually can do WiFi hotspot, which would work fine with a ESP32.

Older phones don’t have WiFi at all, but many can still provide an Internet connection over a Bluetooth link, likely via the LAN Access Profile. I think this would mean my “token” would need to negotiate HTTPS itself. Not fun on a MCU, but I suspect someone has possibly done it already on ESP32.

Nordic platforms are another option if we go the pure Bluetooth route. I have two nRF52840-DK boards kicking around here, bought for OpenThread development, but not yet in use. A nicety is these do have a holder for a CR2032 cell, so can operate battery-powered.

Either way, I think it important that the chosen platform be:

  1. easily available through usual channels
  2. cheap
  3. hackable, so the devices can be re-purposed after this COVID-19 nonsense blows over

A first step might be to see if COVIDSafe can be cleaved in two… with the BLE part running on a ESP32 or nRF52840, and the HTTPS part running on my Android phone. Also useful, would be some sort of staging server so I can test my code without exposing things. Not sure if there is such a beast publicly available that we can all make use of.

Guess that’ll be the next bit to look at.