Hashing It Out

While .NET finally includes CRC-32 and CRC-64 algorithms, it stops at bare minimum and offers only a single standard polynomial for each. Perfectly sufficient if one wants to create something from scratch but woefully inadequate when it comes to integrating with other software.

You see, CRC is just the method of computation and it’s not sufficient to fully describe the result. What you need is polynomial and there’s a bunch of them. At any useful bit length you will find many “standard” polynomials. While .NETs solution gives probably most common 32 and 64 bit variant, it doesn’t cover shorter bit lengths nor does it allow for custom polynomial.

Well, for that purpose I created a library following the same inheritance-from-NonCryptographicHashAlgorithm-class pattern. Not only does it allow for 8, 16, 32, and 64 bit widths, but it also offers a bunch of well-known polynomials in addition to custom polynomial support.

Below is the list of currently supported variants and, as always, code is available on GitHub.

CRC-8CRC-16CRC-32CRC-64
ATMACORNAAL5ECMA-182
AUTOSARARCADCCPGO-ECMA
BLUETOOTHAUG-CCITTAIXMGO-ISO
C2AUTOSARAUTOSARMS
CCITTBUYPASSBASE91-CREDIS
CDMA2000CCITTBASE91-DWE
DARCCCITT-FALSEBZIP2XZ
DVB-S2CCITT-TRUECASTAGNOLI
GSM-ACDMA2000CD-ROM-EDC
GSM-BCMSCKSUM
HITAGDARCDECT-B
I-432-1DDS-110IEEE-802.3
I-CODEDECT-RINTERLAKEN
ITUDECT-XISCSI
LTEDNPISO-HDLC
MAXIMEN-13757JAMCRC
MAXIM-DOWEPCMPEG-2
MIFAREEPC-C1G2PKZIP
MIFARE-MADGENIBUSPOSIX
NRSC-5GSMV-42
OPENSAFETYI-CODEXFER
ROHCIBM-3740XZ
SAE-J1850IBM-SDLC
SMBUSIEC-61158-2
TECH-3250IEEE 802.3
WCDMA2000ISO-HDLD
ISO-IEC-14443-3-A
ISO-IEC-14443-3-B
KERMIT
LHA
LJ1200
LTE
MAXIM
MAXIM-DOW
MCRF4XX
MODBUS
NRSC-5
OPENSAFETY-A
OPENSAFETY-B
PROFIBUS
RIELLO
SPI-FUJITSU
T10-DIF
TELEDISK
TMS37157
UMTS
USB
V-41-LSB
V-41-MSB
VERIFONE
X-25
XMODEM
ZMODEM

Mikrotik Upgrade via SSH

New Mikrotik version came out and my firewall was just a bit too tight to allow remote WinBox connection. But I did have SSH…

And yes, upgrading to new version is easy enough from command line too. It’s just that one needs to execute two (you can omit the check) commands for the same GUI experience.

/system/package/update check-for-updates /system/package/update download /system/reboot

And that’s it, the new version is in.

Start Application Without the X Bit Set

When one plays in many environments, ocassionally you can expect issues. For me one of those issues was starting Linux application from a shared drive. For reasons I won’t get into now, except to say security-related, executable (aka X) bit was removed. Thus it wasn’t possible to start application.

But, as always in Linux, there are multiple ways to skin a cat. For me the method that did wonders was usage of ld-linux library. For example, to start a.out application, one could use the following command:

/usr/lib64/ld-linux-x86-64.so.2 ./a.out

PS: This is for applications (e.g., files with ELF header). If you want to run a script without executable bit set, just call the interpreter directly, e.g.:

bash ./a.sh

Sleep Until the Next Full Second

For a bash script of mine I had to execute a certain command every second. While this command lasted less than a second, its duration was not always the same. Sometimes it would be done in 0.1 seconds, sometime in 0.5, and rarely in more than 1 second (that’s curl download for you). This variance made using a simple sleep command a bit suboptimal.

What I needed was a command that would wait until the next full second. What I needed up with was this

SLEEP_SEC=`printf "0.%03d" $((1000 - 10#$(date +%N | head -c 3)))`
if [[ "$SLEEP_SEC" == "0.000" ]]; then SLEEP_SEC="1.000"; fi
sleep $SLEEP_SEC

The first line is just taking the current nano-second count and trimming it to the first three digits that are then subtracted from 1000 and prefixed with 0.. This essentially gives millisecond precision count until the next full second. For example, if current nanosecond counter is 389123544, this would result in 0.611. And yes, you lose a bit of precision here as number gets truncated but the result will be precise enough.

If you wonder what is 10# doing here, it’s just ensuring numbers starting with 0 are not misdetected by bash as octal numbers.

The if conditional that follows is just to ensure there is at least 1 second of sleep if the previous command took less than 1 ms. Rare occurrence but cheap enough to protect against.

Finally, we send this to the sleep command which will do its magic and allow the script to continue as the next second starts. And yes, it’s not a millisecond precise despite all this calculation as sleep is not meant to be precise to start with. However, it is consistent and it triggers within the same 2-3 milliseconds almost every time. And that was plenty precise for me.

Windows as Ansible Client

I control quite a few of computers in my network using Ansible. However, one set of clients were traditionally unreachable - Windows computers. And yes, there were ways around it but early Ansible really had trouble connecting to vanilla Windows installations without any agents involved. Well, those days are over.

Since Windows has OpenSSH built-in for a while now (as an optional component), it’s almost as easy to prepare a Windows client as it is to prepare a Linux one.

The first step is to install OpenSSH and one can do it either by manual clickety-clicking or by executing the following in administrative PowerShell prompt.

Add-WindowsCapability -Online -Name OpenSSH.Client~~~~0.0.1.0

Start-Service sshd

Set-Service -Name sshd -StartupType 'Automatic'

New-NetFirewallRule -Name "SSH-192_168_0_0" -DisplayName "SSH (192.168.0.0/16)" -Enabled True -Profile Any -Direction inbound -Protocol TCP -LocalPort 22 -RemoteAddress 192.168.0.0/16 -Action Allow  -ErrorAction SilentlyContinue

Next comes the need to create an administrative user since Windows equivalent of root user is actually disabled on most systems. And yes, you can skip this step if you’re ok with using client user for administrative tasks. I personally like to keep it separate and naming such user root helps with setup on Ansible “server” side.

Add-Type -AssemblyName System.Web

NET user /add /y root "$([System.Web.Security.Membership]::GeneratePassword(20, 2))"

NET localgroup /add Administrators root

REG add "HKEY_LOCAL_MACHINE\Software\Microsoft\Windows NT\CurrentVersion\Winlogon\SpecialAccounts\Userlist" /v root /t REG_DWORD /d 0 /f

Lastly, we need to add a public SSH key for passwordless authentication. This is as easy as writing a file.

New-Item -Path "$Env:ALLUSERSPROFILE\ssh" -Force -Name "administrators_authorized_keys" -ItemType "file" -Value "ssh-ed25519 `n"

ICACLS "$Env:ALLUSERSPROFILE\ssh\administrators_authorized_keys" /inheritance:d

ICACLS "$Env:ALLUSERSPROFILE\ssh\administrators_authorized_keys" /remove "NT AUTHORITY\Authenticated Users"

And that’s all. On Ansible side we just add cmd as ansible_shell_type and we’re good. Something like this:

ansible_connection: ssh
ansible_shell_type: cmd

Indeed, one could also use powershell instead of cmd but I found cmd working for all my scenarios while PowerShell is sometimes wonky for older Windows clients.

Regardless, you can now use Ansible to change your Winodws client configuration too.