Random Slacking

It all started as a joke.

As few of us started using Slack it seemed oddly appropriate that #random channel should have a freshly squeezed random number every day. But there were some complaints about the quality. The first issue arose when 42 was randomly selected a few days in a row and it all went down hill from there culminating in a whole weekend without a random number. Unforgivable!

To replace such flawed human being a simple script was needed. It was clear from the get-go that script would be written in Bash. Not only my favorite but also supported on my personal servers and extremely easy to schedule via crontab.

Albeit single digit number had a previous occurrence, single-person decision was made that two-digit numbers look the best and should be used going forward. Due to the previous issue with number 42, it was also decided such number cannot appear too often. After all, you don’t answer the question of life, the universe, and everything more than once in a blue moon.

Too keep things on a low key, it was necessary to avoid any Slack bot interface. No, the message should always appear to come from a user. After a while chat.postMessage call was discovered enabling just that. This did require a (legacy) token and came at a cost of future extensibility but it also allowed a lot of faking so it all worked out.

In any case, here is the final script:

#!/bin/bash

TOKEN="xoxp-111111111111-222222222222-333333333333-abcdefabcdefabcdefabcdefabcdef"
CHANNEL="random"
USERNAME="myuser"

TAGLINE_FILE="/srv/taglines.txt"

NUMBER=$(( RANDOM % 89 + 10)) #random number 10-99
if (( $NUMBER == 42 )) ; then NUMBER=$(( RANDOM % 89 + 10)) ; fi  #about 0.01% chance to get 42 second time

TAGLINE=`shuf -n 1 $TAGLINE_FILE | cut -d'*' -f1`

TEXT="Random number of the day is ${NUMBER}.\\n${TAGLINE}"

curl -X POST \
     -H "Authorization: Bearer $TOKEN" \
     -H 'Content-type: application/json; charset=utf-8' \
     --data "{\"channel\":\"$CHANNEL\",\"text\":\"$TEXT\",\"as_user\":\"true\",\"username\":\"$USERNAME\"}" \
     https://slack.com/api/chat.postMessage

PS: No, illusion is not full, as there will be hints this is sent via API and not by human being. However, hints are small enough that not many will note.

Broken Korean and Japanese in RichTextBox

For a while now my QText utility had an elusive issue. I got multiple reports from Korean and Japanese people that text input doesn’t work properly. Unfortunately they often wouldn’t leave e-mail or wouldn’t feed me with more information to understand the issue.

But eventually, one nice Korean gentleman did manage to show the problem by taking video of him taking notes in Notepad and QText side by side. To reproduce it on my side, I installed Korean keyboard and tried to repeat his (English) sequence: EKS CNR ZL.

In Notepad that sequence resulted with “단축키” while my QText caused text to read “단ㅊㅜㄱ키”. Due to my knowledge of the Korean Starcraft scene, I was aware that Korean letters are grouped into blocks. And obviously QText was somehow messing it up.

After a bit of bumbling around, I found the issue was in OnSelectionChanged handler with further analysis showing the SelectionLength property to be the one causing the actual issue:

protected override void OnSelectionChanged(EventArgs e) {
  this.IsSelectionEmpty = (^^this.SelectionLength^^ == 0);
  if (^^this.SelectionLength^^ == 0) { this.CaretPosition = this.SelectionStart; }
  base.OnSelectionChanged(e);
}

Next stop was Microsoft’s Reference Source for .NET where took a look into RichTextBox.cs and SelectionLength property only to see the following comment:

// RichTextBox allows the user to select the EOF character,
// but we don't want to include this in the SelectionLength.
// So instead of sending EM_GETSEL, we just obtain the SelectedText and return
// the length of it.

This little innocent note actually pointed toward SelectedText property which does a lot of work internally, including sending EM_STREAMOUT message. This call unfortunately terminates IME entry a bit early and Korean character block boundaries get broken.

Fix I decided on was to ignore EOF issue from the comment and use EM_EXGETSEL message to determine what is the current selection length. Short version of committed code went something like this:

protected override void OnSelectionChanged(EventArgs e) {
  var range = new NativeMethods.CHARRANGE();
  NativeMethods.SendMessage(this.Handle, NativeMethods.EM_EXGETSEL, IntPtr.Zero, ref range);
  this.IsSelectionEmpty = this.IsSelectionEmpty = (range.cpMin == range.cpMax);
  if (this.IsSelectionEmpty) { this.CaretPosition = range.cpMin; }
}

private class NativeMethods {
  internal const int WM_USER = 0x0400;
  internal const int EM_EXGETSEL = WM_USER + 52;

  [StructLayout(LayoutKind.Sequential)]
  internal struct CHARRANGE {
    public int cpMin;
    public int cpMax;
  }

  [DllImport("user32.dll", CharSet = CharSet.Unicode)]
  internal static extern IntPtr SendMessage(IntPtr hWnd, Int32 Msg, IntPtr wParam, ref CHARRANGE lParam);
}

Interpreting File Explorer GPS Coordinates

Illustration

Do you notice something wrong with coordinates of this picture taken in Pasco, Washington?

Let’s disregard for moment a pointless precision. Four decimals on Lat/Lon seconds already bring you into a millimeter precision range. With 15 decimals Windows show we are talking about less than picometer - couple orders of magnitude smaller than a virus and more than adequate to locate a single DNA strand (still in nanometer range).

Anything over 2 decimals on seconds (or 6 decimals on degrees) is already way better than any standard GPS can resolve. If we are talking about specialized equipment, we can probably justify 5 decimal digits. Going to 15 digits is just a sign of programmer too lazy to round.

Let’s not even discuss that semicolon is used instead of proper signs for decimal degrees. Yes, latitude should be written as 46° 15′ 12.51″ instead but that is not the biggest fault.

Did you notice it yet? Yep, latitude has no north/south specifier nor is east/west shown for longitude. Alternative approach of having negative numbers instead of south and west is also not here. How do I know? Because this picture has been taken in North America and not in China.

Positive latitude is correct since picture was taken in the north hemisphere. However, longitude is very wrong as degrees number should have a negative prefix for west hemisphere where picture was taken.

In any case, I made a little calculator to convert Microsoft’s coordinates into standard ones:

DegreesMinutesSeconds
Latitude:
Longitude:
LatitudeLongitude

Disabling SSH Password Prompt

After cancelling my hosting, I noticed my e-mail reports stopped working. Since I also upgraded my server with a troublesome version, I originally didn’t connect those two. However, issue with reports persisted even after I fixed the e-mail issue.

Manually running report immediately identified the problem. You see, I login to every server using public key. As my login on DreamHost server was gone, SSH simply decided to fallback to keyboard authentication. And so report waited for keyboard input that was never to come.

Solution intended for this troublesome issue actually already exists in the form of BatchMode option. Appending -o BatchMode=yes to SSH command will cause it to rather fail than ask user for anything. Exactly what doctor prescribed for my report script.

With this update, my “standard” SSH crypto settings for the report got updated to:

ssh
  -2
  -o KexAlgorithms=diffie-hellman-group-exchange-sha256
  -c aes192-ctr
  -o MACs=hmac-sha2-256
  -o BatchMode=yes
  example.com

TP-Link's Idea of Security

Illustration

My wired network finally got too big for a single router so I decided to get myself a switch.

I realistically needed the dumbest switch there is - just 4 gigabit ports and I would be happy. Thus my eyes were immediately drawn to TP-Link SG105 at $20 on Amazon. However, for only $10 more I noted one could get SG105E. The exactly same switch but with a basic manageability features.

Both switches look exactly the same in their steel shell. They are well built and my impression is they can take a beating. You can get inside the chassis by simply undoing two screws and you will see a really simple board. Based on the components, I don’t think you can get much over 1 Gbps on its bus and thus forget about actually reaching maximum speed when all ports are in use - acceptable compromise for home I guess. I would say 9V power supply is the only thing that actually looks cheap. Fortunately, switch works without any noticeable issues on much more common 12V too (albeit you probably forfeit warranty if you do that).

So, what do you get for extra money? Well, you get DSCP, a QoS priority system nobody seems to use in general and definitely not intended for home network. There is also rate limiting with a storm control. Probably not often needed at home but can be quite useful for troubleshooting naughty device.

Further more you get support for up to 32 VLANs - quite nice if your home network needs a bit of separation. Lastly you will also find more “enterprisey” features like port mirroring and link aggregation. Never figured why you need something like this on 5-port switch but I guess it doesn’t hurt to have them.

The most useful feature, and the reason I decided to give extra tenner was the GUI. From GUI you can easily see if your cable is connected, whether packets are flowing, and are there any transmission errors. Usually home switches and routers have ugly interface so I was ready for that. What I wasn’t ready for is abysmal security.

Let’s start with a good thing - you can change user name. Security-wise, that is probably the best thing you can do in your network to escape 95% automated attacks. Yes, this won’t help much if someone is “out to get you” but most script kiddies will be thwarted. And that’s as far as security goes for this device.

To start with, your password is restricted to English alphabet, digits, and underscore (_) sign. Restricting the length and character set is not significant just because it lowers number of combinations your password can take. I am sure you are using password manager and even these weak rules should give you years of good sleep if password is hashed.

But, if they used hashed passwords in the first place, they wouldn’t need character set restrictions. These restrictions are almost always a signal your password is saved in a clear-text. Combined with the login screen allowing for infinite number of guesses at unthrottled speed, and you have the whole security tumbling down.

But don’t worry anybody will brute force this device. Nope - there is no need as you can simply snoop all communication as there is no support for HTTPS. Everything you do on its web interface is for everybody to see. They didn’t even bother to do a simple digest authentication. Nope, all is sent in clear text.

For $20 it is hard not to recommend base model of this switch. It is sturdy, cheap, and reasonably performant. Unfortunately, for only $10 more you can get a device performing the same base function but with a woefully insecure user interface.

I would stick with unmanaged model.