Category: All Posts

All posts.

  • Microsoft needs to be taken down a peg or two thousand

    Remember when you installed Windows 7 and you saw this shit?

    Image attribution: WindowsCentral

    When the EU stopped looking at Microsoft, they removed it. “Microsoft finally ditches the Browser Choice menu for Windows in Europe” was the headline on WindowsCentral.

    Stepping back, the Browser Choice popup was specifically part of the agreement Microsoft reached (and then broke) with the EU to actively give users the choice of what browser to use. Microsoft also, finally, allowed people to uninstall Internet Explorer around this time too (although because modern internet search is terrible, it’s impossible to find articles giving an exact date or inciting reason, so I can only go off of my own memories of “The EU did this”).

    Remember all that? So anyway, it’s 2023 and Microsoft won’t let you uninstall its browser and actively hounds you to use it. Microsoft has made it harder for other browsers to automatically set themselves as your default browser (the double edged sword – this does have legitimate value for security, but is very much beneficial to Microsoft more than anyone else). If you do try to use a different browser, you get a pop-up on the download page for the browser you’re trying to download, telling you to use Edge.

    Even going into the Settings app to change unrelated settings, Microsoft tries to convince you that your choices are wrong, that your system security is at risk because you’re not using their browser, that you’ve done something and Windows needs to fix it.

    From the point at which your default browser changes to not be Edge, this constant reminder that Microsoft disagrees with you is always present in the Settings app.

    You have no way to turn this off, other than to click it and let Windows set your default browser to Edge, pin Edge to the taskbar, put a shortcut to it on your desktop, and make Bing your default search engine.

    If you open the start menu and you type in the name of an application, not realising it isn’t installed, sometimes the start menu will suggest the website of that application instead. Helpful! Legitimately! However, if you hit enter, the website will be opened in Edge instead of your default browser, because the start menu uses Bing search.

    Image attribution: Neowin

    I got a new laptop last week, the Framework 13 (you can read my thoughts about it on Cohost), and I went through a whole thing of installing Windows 10 because 11 is just too user-hostile for my liking (I mean, come on, you can’t even move the taskbar any more). At some point I wanted to see my desktop wallpaper, I minimised all my windows and saw this piece of shit on the desktop. Even choosing to simply ignore Edge, it sits on the desktop and demands you use it. My existing Windows machines seem to have escaped this atrocity on the desktop (for now), but it seems like a new installation will receive the Mark of the Beast.

    Microsoft somewhat recently made waves with its launch of “Bing Chat”/”The New Bing”, which is Microsoft Bing Search but with ChatGPT, and you can’t even use it unless you’re using Microsoft Edge (or a browser which pretends to be Edge in order to specifically circumvent the requirement that you use Edge).

    Even if you acquiesce and use Microsoft Edge, the aggression and hostility does not stop. There’s a Bing button at the top-right corner of every Edge window, which was completely impossible to remove for a while (I believe there’s a way to remove it now, but because I stopped using Edge, I don’t want to check myself. It was not possible at all to remove it when I last used Edge).

    Let’s not mince words here; if Microsoft were being this aggressive and hostile to other browsers during the EU antitrust case, Steve Ballmer would have extremely been publicly executed. Yet in 2023, there aren’t even any open antitrust cases against Microsoft in relation to its monopolistic practices on Windows?

    Yes, I know Google made a whole thing where ChromeOS is a lightweight Linux distribution and everything’s supposed to run inside Chrome, there’s no disagreement that that’s also shit, but ChromeOS has nowhere near the market share and general-purpose use that Windows does. ChromeOS bad, Microsoft Edge somehow worse.

  • Bypassing a bone-headed battery block

    Note: This article discusses mechanisms for updating the BIOS and Embedded Controller of computers that haven’t been made in almost 20 years. Exercise an abundance of caution when attempting to follow, reproduce or build off of my findings. These computers only get more rare over time, and while a bad BIOS flash may be recoverable, I have no idea whether a bad EC flash can be recovered.

    Introduction: Enter the ThinkPad

    Some time ago, I picked up an IBM ThinkPad X40 for a pretty decent price. It’s a nice machine, came in relatively good condition (some cosmetic wear, but nothing actually broken), and doesn’t have the worst specs. It has an amber ThinkLight, which I find quite charming.

    This was a fairly good machine when it came out, featuring (in my case) WiFi, Bluetooth, IrDA, Gigabit Ethernet and 56k fax modem connectivity. It also has one (1) single CardBus slot, and an SD slot that supports SDIO.

    The battery it came with was, predictably for a machine of its age, dead. I didn’t really intend on this being a machine I’d carry about, and the battery casing was cracked enough that I was able to just open it up and remove all the cells and circuitry, leaving a nice blank. This, however, would be a problem when doing any firmware updates.

    It also came with its original 1.8″ IDE hard drive (blessedly, this used the standard 2.5″ interface rather than the other 1.8″ interface I’ve seen, which used ribbon connectors instead and are vastly easier to plug in the wrong way..), and the drive even still worked. For a bit of fun, I wanted to start off with as close to factory configuration as possible for this machine.

    This unit originally shipped with Windows XP, and some kind soul has made all seven (7!) recovery CDs available on archive.org. This is especially lucky because the only alternatives are to either attempt to order a set of recovery discs from Lenovo directly, or to appeal to the hoarders on the ThinkPad forum who think it’s completely okay to hoard recovery media and provide access only on request by individuals who have met their bizarre criteria. No thanks.

    Google dot com how do I upgrade BIOS

    Sometimes I’d observe that the X40 doesn’t boot without manually selecting an option (ie. setup). My initial suspicion was that the HDD was failing, and I wanted to replace it with an mSATA SSD anyway, so I switched out the HDD (temporarily) for an mSATA to IDE 2.5″ adapter to get the OS reinstalled, but I discovered the drive simply wasn’t being detected. I’d been informed by my friends over at the Vintage Tech Nerds telegram group that IBM was famous for locking their firmware down to only accept their own HDDs, so my first port of call was upgrading the BIOS to the latest version and then looking for a modified version (or modifying it myself) to permit other drives to be used.

    ThinkWiki’s matrix of BIOS and Embedded Controller versions for all ThinkPads noted that the final version was BIOS 2.08 and Embedded Controller firmware 1.62 – my device had BIOS 2.06 and EC 1.61, so an update was my first step. I downloaded the updates from the links on ThinkWiki (funnily, there’s a bold notice on ThinkWiki noting that all the download links are broken and have been since 2015, but none of the ones I needed were broken).

    The advice on ThinkWiki was to upgrade the Embedded Controller first, then upgrade the BIOS, so I ran the update program. It advised to keep the laptop undocked, connected to AC power, and have a fully-charged battery connected. I didn’t have a working battery at all, so I went ahead with the understanding that this was simply an advisory. The update program rebooted the computer, and a lovely text-mode IBM logo came up, followed by a menu with options to view a README or initiate the firmware upgrade. The problem began when I tried to initiate the firmware upgrade.

    It came up with confirmation messages stating that the laptop must be undocked (fine), connected to AC power (also fine), and have a fully charged battery connected (not fine). I continued, thinking this was just a second advisory, but woe betide, the upgrade program actually checks that you have a fully-charged battery connected, and refuses to continue without it.

    Initial google searches indicated I could pass the command-line argument -sp to the update program to have it ignore the battery requirements, but this must have been added in firmware update programs newer than the X40, because it had no effect, and later analysis of the program showed that there was no such functionality in the program.

    Searches also indicated I could use a program called WinPhlash (which I downloaded from the apparently legitimate website “wim’s bios”) to flash the EC and BIOS firmwares. I was able to take a full backup of the BIOS before doing anything, but was unable to use it to flash the Embedded Controller firmware, so it seems I -have- to use the official software for the EC part.

    Put your balaclava on, it’s time for crime

    At this point it was obvious I’d need to work out how the firmware update process worked, and then hack it in some way to remove the battery check. The downloaded update files from Lenovo were standard InstallShield programs, and the actual update programs were extracted and run from %temp% – the currently-logged in user’s temporary files directory. Both the BIOS and the Embedded Controller updates had the same file structure for the most part. I found it interesting that there was an IMG file, so I inspected that first using 7-Zip (because hey, did you know that 7-Zip can open pretty much anything? You can even open raw disks with it.)

    Opening the IMG file revealed that it was.. a floppy image. A regular 3.5″ high-density 1.44MB floppy diskette image.

    What was in the image was pretty interesting. The biggest file was $019B000.FL2, which was obviously the Embedded Controller firmware itself. At a later date I might inspect it and see what fun crimes can be done with it, but for now I just wanna grill for god’s sake. There were some interesting other things in the image, though: A minimal copy of IBM PC-DOS 5.00, with some additional software specific to flashing the Embedded Controller firmware.

    I verified what this was by running ibmdos.com through IDA Free 5.0 (the last version to support 16-bit binaries, blessedly preserved by the ScummVM folks) and confirming that it was, in fact, IBM DOS 5.00. To double-check, I opened up command.com as well, but found that it was actually the program responsible for the text-mode IBM logo and the menu that’s presented afterwards.

    I spent a while in IDA trying to work out if I could simply patch out the battery check in updtflsh.exe – the program called by the menu when initiating the EC flash procedure – but I couldn’t locate where this was actually happening, and I have very little experience with reverse-engineering 16-bit software. IDA Free 5.0’s interface is also..quite a bit harder to get to grips with than the more modern software I’m used to.

    It occurred to me, however, that I knew what the startup program was, and I knew what version of IBM DOS was being used. Could I simply replace the custom command.com with the equivalent from a retail copy of IBM PC-DOS 5.00? As it turns out, yes! I swapped the files in the floppy image, ran the EC firmware update program, it rebooted Windows and warm-booted into the floppy image, and I was immediately presented with the current date and time, and a prompt to change them should I wish.

    Finally, I was able to update the Embedded Controller’s firmware by running the command QKFLASH.EXE $019B000.FL2 – as documented in the “extremely last resort” section of ThinkWiki’s article on updating the BIOS, qkflash.exe is the program that actually performs the flashing.

    After this completed, the laptop completely shut down. I left it for a few seconds, then powered up, and it booted right back up. I then used WinPhlash to flash the BIOS itself, and when I rebooted into the BIOS setup, it confirmed I was now running BIOS 2.08 and EC 1.62. Success!

    Where now?

    I stopped here, because it was a small victory and I was tired, but I want to do more with this. It brought up some interesting questions, namely:

    • Can I fiddle with the Embedded Controller firmware, and perhaps enable some new functionality or fiddle with the keyboard mappings?
    • Can I modify the BIOS to disable the hard drive DRM? Existing modifications are only available for the X41 and newer.
    • How does the firmware update program manage to load a floppy disk image into memory and warm-reboot the computer directly into it?
    • Can I wholesale replace this with a different floppy image? What state is the computer actually in? What could you do with this?
    • Are there any other limitations IBM placed on this machine that I could perhaps lift?
  • Oh god, social media

    Hey guess what! Twitter sucks. It’s sucked for years, it’s getting worse, and they’ve just announced the addition of an actual child to their board.

    Pages: 1 2

  • Thoughts on the ODROID Go series

    For reasons of “push button, receive serotonin and electronic gubbins”, I have both the original ODROID Go and the newer Go Advance. I’ll try to give a rundown of the two, my thoughts on the final assembled kit, the modifications I’ve made, and the potential future for them.

    The ODROID Go

    This was an odd one when it first dropped. Intended as a product to celebrate the 10th anniversary of ODROID/HardKernel, this appears to be the one and only product released by them which..doesn’t run Linux.

    It’s a neat little kit which, when assembled, roughly resembles the GameBoy Colour. It has an LCD screen, mono speaker, D-pad, A and B buttons, four buttons below the LCD, MicroUSB port for charging, and a 10-pin header at the top for hardware hacking.

    As an added nicety, it also has that toggle switch for power that the original GameBoys had. For storage, it features a tiny MicroSD card slot on the back, near the side, which is cleverly integrated into the chassis.

    Where it really differs is the brains of the whole thing. Unlike seemingly every single other ODROID product, the Go is based on an ESP32-WROVER microcontroller from Espressif, featuring a 16MB EEPROM, 4MB of PSRAM, WiFi a/b/g/n 2.4GHz, and Bluetooth 4.2+LE. The MCU itself runs at between 80MHz and 240MHz, is dual-core, and has a third core for low-power operation.

    The MicroUSB port connects to a CP2102 USB-to-UART IC, providing serial access to the ESP32 itself, useful for updating the bootloader, or for programming and debugging.

    The ODROID Go Advance

    Seemingly spurred on by the success of the original Go, the Go Advance was released. Bearing a passing resemblance to the GameBoy Micro (due to the rectangular shape), the Go Advance features a full Rockchip ARM SoC, running at 1.3GHz, accompanied by 1GB of LPDDR3 RAM. Still featuring a MicroSD card slot as the primary storage, and a 16MB EEPROM internally, it now runs full-fat Linux, enabling a whole host of emulators (and, of course, other things).

    The MicroUSB port has been eschewed for a USB-C port (on the “Black Edition” revised version, the original release featured a barrel jack for charging). A USB2.0 port is present, and the UART is no longer exposed over USB, but instead is a dedicated internal port. The four buttons below the LCD are now six buttons, and the A & B buttons now have X & Y counterparts. There are now shoulder buttons (L1 and R1, the “Black Edition” added L2 and R2), and a left analogue stick.

    At launch, it didn’t include WiFi, but this is another omission addressed by the “Black Edition” variant, which includes 2.4GHz WiFi and Bluetooth 4.2+LE powered by the single-core variant of the module powering the whole original ODROID Go – the ESP32-WROVER-S2.

    My thoughts – the Go

    It’s definitely a weird one. It stands out as the only device from ODROID to not have a processor capable of running a full OS, and stands out as one of only a handful (ha!) of retrogaming-oriented handhelds to use a microcontroller instead of a proper ARM SoC. Though it’s definitely not alone in the category, it’s.. a very small category.

    Even the older retrogaming handhelds were based on some variant of Linux, running on a full ARM SoC. Heck, the 2009 GP2x Wiz (and its mid-2010 successor, the Caanoo) had a 533MHz processor. The Wiz had 64MB of RAM, and the Caanoo doubled that to 128MB. To use a microcontroller with massively tighter constraints than even these old handhelds, is definitely a weird choice.

    So, do I think the Go is dead in the water? A waste of money?

    Absolutely not. Despite its limited set of available emulators, it’s a fantastic device. It will never be the “perfect” device, despite how well-designed it is, but it doesn’t need to be. The use of the ESP32 as the brains of the operation, provides a great way to get into programming. You can run plenty of older games on it, but when you get bored? You can start making your own, way more easily than on a Linux-based system.

    You can write software for it in C (using the Arduino IDE) or Python (using MicroPython and something such as the Mu editor). It’s the perfect combination of fun and hackable!

    As an emulator, it runs very nicely using the RetroESP32 firmware, handling GB/GBC games smoothly. As a programmable device, it’s a lot of fun.

    ..and the Go Advance

    So the Go Advance came along, and answered everyone’s prayers by including a full-fat ARM SoC and a tasty chunk of RAM, running Linux, and supporting a wider range of emulators. It had a couple of weird omissions for a new release of a device like it (USB-C and WiFi) but these were, as mentioned above, addressed in the “Black Edition” variant.

    It’s fantastic from a hardware perspective, and with a faster SoC and more RAM it’d be close to perfect, but I have a couple of gripes with it that concern the physical design of the chassis.

    First, the rectangular design. The edges are curved to improve comfort, but it would have benefited greatly from borrowing more of the physical design from its namesake, the GameBoy Advance. The internal board could definitely be trimmed at the corners without issue, and the GBA’s curved design would’ve fit perfectly.

    Next, the buttons. They’re not super bad, and are perfectly usable, but (as a couple have noted) the shoulder buttons could definitely use springs beneath them. I get why this wasn’t included; it’s a fiddly kit to put together as-is, so putting springs in would serve to frustrate more, but it would’ve been a nice option. The buttons below the LCD, however, are.. squishy. Way too squishy. They don’t spring back quickly, and they’re way too rubbery.

    Possibly the biggest gripe I have is with the analogue stick. The one included in the kit is incredibly uncomfortable, has sharp edges, and is just a smidge too small to feel right in the hand. It can be replaced with an analogue stick from the PlayStation Vita, but it would’ve been nice to have a better stick as standard. I have some theories that the Nintendo Switch analogue sticks could work as a replacement as well, but these are way more difficult.

    The final, though more minor, gripe I have, is with the mechanical tolerances of the whole thing. The screen flexes when you apply any pressure to the areas surrounding it (not on it, but near it), such as if you press down on the plastic while pressing the right D-pad button. When assembling the unit, significant force must be used to “snap in” the clips that attach the front and back of the chassis, otherwise there will just be parts on the edges that bulge out uncomfortable.

    So what would I change? Honestly, I think the biggest benefits would be in swapping the mono speaker out for two smaller speakers flanking the LCD near the top, and use the blank space previously occupied by the speaker, to instead have a right analogue stick. I’d also swap out the analogue stick currently in use, for the analogue stick used by the Nintendo Switch and the 8BitDo SN30 Pro+. These are slightly larger, but feel way better in the hand, and they click in, providing L3 and R3. I’m not sure how I’d address the not-great function buttons below the LCD. Finally, I’d add light pipes inside the chassis, so that the LEDs visible through the ventilation grille on the back can be seen from the front or top of the unit instead.

    Final thoughts

    So what would I recommend? It depends. Do you want something that you can have a lot of fun playing games on, but want to learn on as well? Get the ODROID Go. The ESP32 is a brilliant platform for getting to grips with programming devices. Do you want to just play a whole bunch of fun games? Get the Go Advance. It runs Dreamcast and PS1 games great, and it’ll take the fancier MicroSD cards with higher speeds and capacities.

  • Taking a ride on the Universal Serial Bus

    Hello! I’d like to take a minute here to talk about some fun I’ve been having with the USB interface for the Paperang P1 and P2 portable thermal printers.

    I discovered recently that these devices had a USB interface (I’d previously thought the USB port was only for charging the internal battery) when I stumbled onto the (Chinese-only) download page for the Paperang software, which contains something omitted from the English variant of the page; Mac and Windows software, and mentions of using USB to print.

    Unfortunately the official Paperang software is very sparse in its featureset, and doesn’t appear to properly communicate with the P2 model (It’ll produce incorrect print results), so I was motivated to try and reverse-engineer the communications protocol used (a fantastic series of blog posts made by a good friend of mine on the subject of hacking a cheap chinese USB mouse provided added inspiration, and I sincerely recommend you read them).

    When first plugged into a Windows machine, it’s recognised as a USBPRINT device (USB class 0x07) with vendor 0x4348 (WinChipHead) and product 0x5584 (CH34x printer adapter cable). The host will, as part of device initialisation, send a URB_CONTROL request type 0xA1 (device-to-host class 0x1, interface 0x1), to which the printer responds with 0x0060 followed by MANUFACTURER:;COMMAND SET:ESC/POS;MODEL:MiaoMiaoJi;COMMENT:Impact Printer;ACTIVE COMMAND:ESC/POS;. However, the printer doesn’t actually contain a CH34x-type chip, and the USB data lines are directly connected to the main MCU (an STM32-type chip). Further, the URB_CONTROL response states that the printer uses the ESC/POS method of communication, however this doesn’t appear to actually be the case. It’s very unclear why they’d put this in, however both the P1 and P2 models report this. I did test whether they supported ESC/POS communications, however the messages were ignored by the printer.

    When the Paperang Windows application first detects the printer, it’ll begin sending messages to the printer via URB_BULK output. These messages are formed of a distinct structure:

    --------------------------------------------------------------
    | Frame Begin | CMD/OpCode | Data   | CRC        | Frame End |
    --------------------------------------------------------------
    | 0x02        | 0x00000000 | 0x0..0 | 0x00000000 | 0x03      |
    --------------------------------------------------------------
    Code language: plaintext (plaintext)

    The Data block is of variable length, and from my observations may be as small as 2 bytes, and may be as large as 1008 bytes. The CMD/OpCode block is always 4 bytes, and I have identified the following OpCodes:

    • 0x06000200 – Appears to be something of a “session” start indicator (Data block has only ever been observed to be 0x0000 for this OpCode)
    • 0x1a000200 – Feed command (doubles as a no-op) – Data block for this is simply the hex representation of an integer, corresponding to the number of milliseconds the printer should feed the paper for
    • 0x18010401 – CRC data transmission (Data block will be 4 bytes in length). This is an interesting one, in that the Data block consists of an initial value for the CRC32 algorithm, and the CRC block will be the initial value’s checksum calculated using the magic value 0x35769521 as the “initial” initial value. Once this OpCode has been used, the initial value will be XORed by the magic value and will then be used for future CRC calculations. The official Paperang software has an internal table of “initial values” which it picks from at random, however as it uses the C standard library’s random number function, the value it ultimately uses is almost always the same.
    • 0x0001FFFF – Print data transmission OpCode – this one is somewhat special in that the latter 2 bytes (denoted here as 0xFFFF) are dynamic, and correspond to an integer of the length of the Data block. The Data block will be a variable-length (up to 1008 bytes) block of data to be printed.

    The first message sent to the printer is the CRC data transmission message. An example is:

    ------------------------------------------------------------------
    | Frame Begin | CMD/OpCode | Data       | CRC        | Frame End |
    ------------------------------------------------------------------
    | 0x02        | 0x18010400 | 0x4d0dc477 | 0x699295ed | 0x03      |
    ------------------------------------------------------------------
    Code language: plaintext (plaintext)

    And the CRC result for all further messages where the Data block was 0x0000 was 0x906f4576

    From this point, the printer can be used normally. There may be other functionality available through the USB interface, but the first thing I looked at implementing was actually printing data. Upon printing some sample data using the official software, it very much looked like there was no special encoding – if I printed a single dash (-), the bytes sent to the printer appeared to match up with the physical dots printed on the paper.

    Although I could’ve then spent a while printing some test images on the paper and looking at the transmitted bytes in Wireshark, I figured I may as well just start bit-fiddling and see what happens. I’d already determined that the OpCode for printing data contained the length of the transmitted data in its latter two bytes, so I figured I’d start with the maximum length for a single packet – 1008 bytes – and set segments at 8-byte intervals to determine roughly what was going on:

    byte[] Data = new byte[1008];
    for(int i=0;i<Data.Length;i+=8)
    	Data[i]=0xFF;
    Code language: C# (cs)

    I sent this along to the printer, and was pleased to see it printed 6 vertical lines. Based on the fact that the lines were not skewed, it seemed like the line length in bytes was divisible by 8, and based on there being six vertical lines, it seemed like the line length was 48 bytes. To test this theory, I adjusted my code to the following:

    byte[] Data = new byte[1008];
    for(int i=0;i<Data.Length;i+=48)
    	Data[i]=0xFF;
    Code language: C# (cs)

    And was pleased to find that it now only printed one vertical line. Cool, we’ve now worked out the line length, and we’ve confirmed that 0xFF prints a line..now how do we get a single dot? I tweaked my code again, this time setting every 48th byte to an alternating pattern of 0x0F and 0xF0:

    byte[] Data = new byte[960];
    for(int i=0;i<Data.Length;i+=96) {
    	Data[i]=0x0F;
    	Data[i+48]=0xF0;
    }
    Code language: C# (cs)

    It printed something resembling a zig-zag! Awesome. It seems like every byte can be controlled 4 bits at a time, at least, for controlling what gets printed. Can we go deeper? Let’s try alternating byte patterns! We’ll make every 48th byte an alternating pattern of 0x33 and 0xCC. This should produce two narrow zig-zags:

    byte[] Data = new byte[960];
    for(int i=0;i<Data.Length;i+=96) {
    	Data[i]=0x33;
    	Data[i+48]=0xCC;
    }
    Code language: C# (cs)

    Print..and hey presto! Right on the money! Can we go even deeper? Let’s try an alternating pattern of 0x55 and 0xAA, which in binary is 0b01010101 and 0b10101010:

    byte[] Data = new byte[960];
    for(int i=0;i<Data.Length;i+=96) {
    	Data[i]=0x55;
    	Data[i+48]=0xAA;
    }
    Code language: C# (cs)

    Just like that, we’ve got what looks visually to be a dithered (50% dark) vertical line! Radical. From this we can deduce that every bit in the byte corresponds to an individual “dot” produced by the thermal print head. Thus, given that we know every 48-byte block is one line, we also know now that each line is 384 “dots” wide.

    Awesome, we know everything we need to in order to print an image!

    From here, the process of printing an image is pretty obvious – resize the image to 384 pixels wide, and convert it to a 1-bit bitmap. This presents a problem though; if the image is even slightly large, it’ll exceed the maximum packet size for a message sent to the printer (1008 bytes). Luckily for us, however, C# does present a fairly nice way of splitting at specific lengths, using LINQ:

    using System.Linq;
    using System.Collections.Generic;
    List<byte[]> segments =
    	Data
    		.Select( (onebyte, index) => new {Index=index,Value=onebyte} )
    		.GroupBy( onebyte => onebyte.Index / 1008)
    		.Select( onebyte => onebyte.Select( bytevalue => bytevalue.Value )
    			.ToArray()
    		).ToList();
    Code language: C# (cs)

    We can then iterate over the resulting segments variable! Thanks chief, very cool.

    Where’s all this leading to? Well, the long and short is that I’ve written a C# library for interfacing with P1 and P2 model Paperang printers over USB, as well as a basic Windows front-end for it. You can find it on my GitHub!

  • Bad at this ‘blogging’ thing

    Whoops.

    Put all that effort into writing a blog platform (which began as a static site generator, then became a quasi-dynamic web app), then neglected to actually write anything for the following three-and-something years. Whoops.

    I think part of the problem there is that, as cool as it sounds that your blog posts are stored as markdown files inside a Git repository, the fundamental issue is that it becomes inconvenient to draft up and write posts. Almost immediately, I found myself wanting for an XML-RPC interface for remote publishing, and a web interface for writing posts when I didn’t have access to my preferred MetaWeblog-compatible writing software (OpenLiveWriter). I could’ve added these features to BlogAlba, but this would’ve necessitated a user management system of some sort, as well as actually implementing a web administration interface of some kind, and XML-RPC features that allow for remote blogging. Doable, but I just didn’t have the energy to actually bother with it.

    So the blog sat dormant since that first “new blog” post, a testament to how much I simply couldn’t learn to love the now-traditional workflow for static site blogging (and pseudo-static relatives such as BlogAlba).

    Enter Chyrp Lite. A blogging platform that seemed simple enough that I could feel comfortable with deploying it, and which is actively maintained – latest release at time of writing was 18 days ago! From reading the features list, I felt quite enamoured with the software due to its support for the MetaWeblog API, ease of templating, and ability to have different ‘types’ of post, which differ from pages (akin to Tumblr, the default set bundled with Chyrp is Audio, Video, Disco, Text, Link, Photo, Quote and File), each of which can be toggled on or off.

    As much as I didn’t want to go away from Perl, I’ve gotten to a certain point in my life where, frankly, I don’t have the time or energy to be opinionated about technology and software. This website now runs inside Docker, a technology I’ve been very vocal in my hatred for. Docker, in turn, runs within Rancher OS, inside a Hyper-V machine. For all my love of FreeBSD, I’ve long lost the energy to put significant time into building infrastructure that needs regularly maintained; it goes against my personal philosophy, but the convenience of systems that can be repeatedly torn down and rebuilt rather than updated cannot feasibly be ignored.

  • On encryption and jails

    Note: This post was written when the Let’s Encrypt private beta first launched, and most of the tooling related to Let’s Encrypt has completely changed since.


    It was reported recently that Let’s Encrypt had recently launched their private beta. As someone who does their best to ensure encryption is as widely-available as possible, I was excited.

    Yesterday, I got my email stating that the domain maff.scot had been whitelisted for issuance using the letsencrypt utility. Awesome! Let’s see how you get it set up. To the best of my knowledge, there was no FreeBSD port or package for the utility, which meant I had to git clone their repo and set things up. Depending on how your system’s set up, this might be a breeze, or it might be a challenge.

    A few things to note, going in:

    • FreeBSD by default ships with csh as the default shell, and no sudo.
    • I very strongly embraced the BSD way of doing things, so that was still the case.
    • The letsencrypt utility has some questionable defaults, in that it will attempt to run its own server temporarily for use in verifying ownership of your domain. It can also futz with your Apache/nginx config files.
    • It doesn’t take into account what platform it’s running on, and as such, flies in the face of the FreeBSD filesystem hierarchy, documented in hier(7), defaulting to /etc/letsencrypt for configuration and storage, and /var/lib/letsencrypt for its working directory.
    • The documentation was a bit confusing on what I actually had to do to get things up and running in the event that a binary package was not available.

    With all these in mind, I felt it might be prudent to just set it all up inside a FreeBSD Jail. This would allow all dependencies to be satisifed from the letsencrypt client’s point of view, and would allow it to place files where it pleased, without making a mess of my main server.

    Preparing to run Jails

    I already had a jail system set up on my server, but I’ll document the process here anyway. To simplify things, I used the EzJail system to get everything set up for me, and did final configuration and such using a flavour.

    To start off, I ran pkg install ezjail to install ezjail. While the package itself is called “ezjail”, the utility used to actually work with it is ezjail-admin.

    After installing the package, the “base system”, what all jails will draw from, must be installed. This can be compiled from source, but if you’re running a RELEASE version of FreeBSD, it’s perfectly fine (and easier) to simply use the same distribution bundles that you installed your host FreeBSD system from. To install the base system, just run ezjail-admin install, adding -m and -p to include man pages and the ports tree, respectively. This will download the FreeBSD base and userland, manpages (if desired), and will invoke portsnap to download the ports tree, and install it all to /usr/jails/basejail, by default.

    After this, I set up my flavour for the jails I’d be running. A flavour is a set of files and configuration options that will be added to a jail you’re creating, and allows for decent customisation; specific flavours can have certain packages preinstalled, services pre-enabled or pre-configured. I just set up a default flavour, which disabled services like sendmail, and pre-populated /etc/resolv.conf. This can be easily done by copying the example flavour bundled with ezjail, and editing the name and files where appropriate.

    Since the machine I’m running on only has one IPv4 address, I needed to NAT traffic from my jails, by adding the following rules to my pf.conf:

    jails="10.0.1.0/24"
    wan="re0"
    wan_ip="0.0.0.0" # replaced with your real IP, obviously
    
    nat pass on $wan from $jails to any -> $wan_ip
    pass in from $jails to $jails # to allow inter-jail trafficCode language: PHP (php)

    It’s also a good idea to give jails their own loopback interface, separate from the host’s, by adding cloned_interfaces="lo1" to your rc.conf, and restart networking.

    Setting up the Let’s Encrypt jail

    Now, finally, we’re ready to create the jail itself, by running ezjail-admin create -f yourflavour letsencrypt 're0|10.0.1.10,lo1|127.0.1.10', which will create a jail named ‘letsencrypt’ using the flavour ‘yourflavour’, and will give it a private IP of 10.0.1.10 and a loopback IP of 127.0.1.10. These IPs haven’t been pre-configured on your machine, but will be added on-the-fly when the jail is started; hence why the interface names re0 and lo1 are specified.

    I then ran ezjail-admin start letsencrypt to actually start the jail. At this point, you may receive a warning about using jail.conf instead of JAIL_ variables if you’re running FreeBSD 10; this is a fault in ezjail, but has no impact on the operation of the actual jail, as it’s converted on-the-fly.

    Now you’re able to enter into the jail using ezjail-admin console letsencrypt, but before doing that, we need to install packages for the jail. To prepare it for running letsencrypt, install base dependencies using pkg -j letsencrypt install pkg git sudo bash on the host. This will install git and pkg inside the jail, so that letsencrypt-auto can install all packages it needs to operate. It will also install bash, necessary for running letsencrypt-auto, and sudo, necessary because letsencrypt expects to be run as an unprivileged user with sudo access.

    Entering the jail, installing Let’s Encrypt

    Now we can enter the jail with ezjail-admin console letsencrypt. This’ll give you a root shell inside your jail, from which we can create our unprivileged user with pw user add -n leuser -m -s /usr/local/bin/bash -G wheel, followed by passwd leuser to set the password you’ll enter when sudo prompts for one. Then, set up sudo by running visudo and adding %wheel ALL=(ALL) ALL. You’ll also need to run mkdir -p /etc/letsencrypt/www to create the directory which will be used for proving to the Let’s Encrypt systems that you own the domain you’re requesting a certificate for.

    Drop down to the unprivileged user with su - leuser, which gives us a clean login environment as the user, then pull down the Let’s Encrypt client with git clone https://github.com/letsencrypt/letsencrypt, and cd into the directory. From here, just run ./letsencrypt-auto, which will install all necessary packages, python modules, and finally sort out the letsencrypt binary itself.

    The documentation then dictates that you swap out all instances of the letsencrypt command with ./letsencrypt-auto, but this isn’t necessary every time, as letsencrypt-auto will check each and every time for updates to packages and python modules before actually doing anything, which can be very irritating to wait on. After running it once, you can simply make a symbolic link to the actual letsencrypt program by running ln -s $HOME/.local/share/letsencrypt/bin/letsencrypt $HOME/letsenc. From then on, you can simply run sudo ./letsenc ... from the unprivileged user’s home directory.

    Getting the host system ready for Let’s Encrypt

    As I mentioned, I wasn’t comfortable with letting the letsencrypt client run its own server for domain validation. Thankfully, an alternate authentication method was made available to me: webroot. Using this, the letsencrypt client will simply create a file in the webroot directory, which will then be requested by the validation service, at http://your-domain/.well-known/acme/. It will also expect the webroot path to remain the same, irrespective of whether you’re requesting a certificate for multiple domains.

    Thankfully, since I know it expects the file to be served at /.well-known/acme/, and I run nginx, I was able to set up a redirect across all vhosts in the same manner that a standard 404 page is served in nginx: Adding a root location directive, beneath nginx’s standard location 403.html, 404.html, 50x.html directive.

    location ~^/\.well-known\/acme-challenge\/.*$ {
    	root /usr/local/www/jail_symlinks/letsencrypt;
    }

    Followed by creating the symbolic link nginx would look for, via ln -s /usr/jails/letsencrypt/etc/letsencrypt/www /usr/local/www/jail_symlinks/letsencrypt. As I was using jails for serving web applications, I had a separate folder specifically for access to jails, but you can change this to any path you desire, of course.

    Using Let’s Encrypt to get a certificate

    Now that all setup is out of the way, we can finally get our certificate. To do this, I ran sudo ./letsenc --agree-dev-preview --server https://acme-v01.api.letsencrypt.org/directory certonly -a webroot --webroot-path /etc/letsencrypt/www. This presented me with a few dialogs, prompting me for an email address and list of domains to request certificates for. Once this was done, it performed validation that I owned the domains in question. This succeeded, and the certificates were issued and stored into /etc/letsencrypt/live. From here, you can simply use symlinks to provide nginx with your fullchain.pem and privkey.pem files, which contain the certificate and chain, and private key, respectively.

    At this point, I’ve successfully got Let’s Encrypt set-up, and a certificate issued. After adding ssl_certificate /path/to/fullchain.pem and ssl_certificate_key /path/to/privkey.pem to my site’s server block in nginx, I was up and running. You can also use the chain.pem file provided by letsencrypt to easily set up OCSP stapling. After doing this, your server block should contain something like the following (providing you also run ln -s /usr/jails/letsencrypt/etc/letsencrypt/live /etc/ssl/letsencrypt):

    ssl_certificate /etc/ssl/letsencrypt/maff.scot/fullchain.pem;
    ssl_certificate_key /etc/ssl/letsencrypt/maff.scot/privkey.pem;
    ssl_trusted_certificate /etc/ssl/letsencrypt/maff.scot/chain.pem;
    ssl_stapling on;
    ssl_stapling_verify on;
    resolver 8.8.8.8 valid=300;
    resolver_timeout 10s;

    A few notes on the resulting setup

    Having gone through all this, setting up new domains with a Let’s Encrypt certificate should be quite painless, as is renewing certificates. Let’s Encrypt issues certificates with a 90-day validity period, and they recommend renewing within 60 days of issuing, such that if something goes wrong, you have a month’s time to notice and fix it.

    While looking at how renewal works, I noticed there was a letsencrypt-renewer program included with letsencrypt. I’m not sure if this is fully-functioning as of yet, as the documentation states that an automated renewal system is not yet in-place.

  • New site, fantastically perl-y, because why not

    Oops, and then I didn’t have a blog for a few months. I pulled down my old blog (formerly located at blog.maff.me.uk), partially the .scot TLD launched and I wanted to move to maff.scot as soon as possible, and partially because I wanted a blog system I was happier working with (The old blog was dotClear-based, and hosted at Gandi because it was a free addon and I was lazy. I’d looked around for a while to see what blogging systems I could try out, but I didn’t want to go near WordPress and none of the other systems really appealed to me. Some friends suggested I try Jekyll, but I couldn’t really grok that; I also found Dapper online, but as far as static-site platforms go it wasn’t the best for a blog. So I wrote my own.

    To rewind a bit, I’ve been steadily improving my Perl skills for a good while now, so when it came to hunting for blogging software I was biased towards perl-based systems. It turns out there are quite a few! Unfortunately most were either too complex to work with, or didn’t have features I needed. What most of them did offer, was a simple publishing system based around YAML and Markdown. This actually seems pretty great, because Markdown is well-documented and easy to write posts in, without me having to faff about much with formatting. It also allows me to keep post metadata at the top of each post, in my editor.

    So having seen what other systems were like, and knowing what I did and didn’t like about each, I wrote my own, (slightly patriotically) named BlogAlba. It’s a single ~150-line perl script, designed to run as an application (though it could easily be changed to just output static HTML files and such). It’s been quite a fun learning project, and should (at this point) be quite easy to maintain and extend.

    The styling of my site has also changed; this time based around Bootstrap and a theme found on bootply via BootstrapZero, written by user cskelly. I’ve cut it down somewhat and modified it to fit my own preferences, but credit where it’s due of course 🙂

    Hopefully now that it’s a lot easier for me to write up posts, and everything’s being published on software I’m intimately familiar with, my site’ll see the love it deserves. If you’ve got any comments or questions, look to my twitter because I’m not gonna deal with the noise of an actual comments system.

  • Gone, but not forgotten

    Just a short post today.

    Yesterday (Wednesday the 20th), we took our dog to the vet for what we thought was a stomach bug. He’s had diabetes since about July of last year, and can’t have insulin without food, so we were concerned that he wasn’t eating. He was diagnosed with Pancreatitis, which is treated through starving him for a few days until the pancreas heals a bit, however due to his diabetes, this could have an extremely adverse effect – he’d lost 1.5 stone over the course of a day or so already, and was in a tremendous amount of pain.

    The vet informed us that, even if he pulled through and his pancreas got better, he’d be in a terribly fragile state and would have a long time to go before he regains weight – and there’s a high chance of recurrence, meaning he could be in and out of the vet very often, and he was in so much pain due to it.

    He was put to sleep yesterday afternoon. We were with him the whole time, and right to the end, he was wagging his tail because he was so happy to see us.

    Here’s to you, Max. You were a better friend and companion than anyone could ever have asked for.

  • Why I never (or rarely) place phone calls

    Note: This post was written in early 2013, and a lot of things have changed since then. Phone calls are alright, actually.


    If I want or need to contact someone, typically the first thing I check is my instant messenger. I use Trillian, which keeps me logged into every IM service I use regularly (AIM, MSN and Gtalk). I also log into Skype on it if I need to. If the person I want to talk to isn’t online or available there, I check Steam. If they’re not available there, I text them. If I don’t have their number or something, I message them on Facebook.

    Calling people is, for me, an absolute last resort.

    This is entirely because, while I have way more minutes and texts on my phone contract than I will reasonably use in a month, I grew up with SMS and instant messaging as my primary form of communication. I know that, if I send a message to someone, they’re not required to act upon it immediately and can respond when they’re ready to. Phone calls don’t afford that luxury. If someone phones you, you have to decide to answer or decline the phone call right there. If you miss the call, you have to contact the person later to find out why they were calling you, unless they left a voicemail (and who does that?).

    So when I want to phone someone, I have to take into consideration how busy that person is and how likely it is that they’ll be available to both answer the phone and have a chat. I’m not sure if this is simply a problem I have or something, but I generally have no idea what time is a good time to call someone (which is why, in the years that she’s been living away from home, I’ve barely called my sister even once.) I rarely even call my best friend for this reason.

    This isn’t to say I think phone calls are bad. Not at all, I’ll defend the importance of phone calls to the ends of the earth. I simply think they could be improved. Skype (and other internet-based voice calling systems) give you a good indicator, by whether or not the person: A) is online, and B) has their status set to “Available”.

    Yes, I know I haven’t posted anything in quite a while. I have quite a few draft posts, and for the most part I just can’t be bothered finishing them. I will eventually, don’t worry. I also have a lot more stuff I want to talk about.