Sunday, September 26, 2021

How-to install Discord on Debian

Unfortunately, Discord offers a .deb package that cannot actually be installed on Debian. The problem is that Discord depends on libappindicator1, which was deprecated over 3 years ago, instead of the replacement, libayatana-appindicator1. As a work around, the dependency can be changed in the .deb file and the application can be installed. Here is the workaround:

  
dpkg-deb -R discord-0.0.17.deb /tmp/discord-deb
sed -i 's/libappindicator1/libayatana-appindicator1/g' /tmp/discord-deb/DEBIAN/control
dpkg-deb -b /tmp/discord-deb discord-0.0.17-fixed.deb

 

This will modify your .deb so that it can be installed normally on Debian 11 “Bullseye”. If a newer version has come out and the problem has not been fixed, just change the version numbers in the file name accordingly.

UPDATE: This fix is still necessary for version 0.0.17

UPDATE: The fix is finally no longer needed for version 0.0.18

Monday, July 31, 2017

VLC won’t take snapshots on Debian 9 “Stretch”

If you are experiencing this problem, it appears to be due to a bug specific to the VDPAU driver. Unfortunately, VLC gives no obvious error to indicate the snapshot was not taken (if it works, you should see a message briefly showing where the image was saved to). The work around is to simply change the video decoder method. Go to Tools -> Preferences, then select Input / Codecs at the top of the dialog, and change the setting for Hardware-accelerated decoding from Automatic or VDPAU video decoder to VA-API video decoder via X11 (or DRM).


https://askubuntu.com/questions/769585/vlc-cant-take-snapshots-anymore-due-to-corrupt-vdpau-video-surface-error

Sunday, March 13, 2016

Changing the encryption password on CyanogenMod 13 (Android Marshmallow)

In order for your phone to be secure, you need a strong encryption password. Unfortunately, the default is to use the lock screen password and having a strong password on the lock screen makes it way too difficult to access the phone. You really want to use two different passwords: a strong one for encryption that is only required when you boot the phone, and a shorter one for the lock screen. Then you protect the lock screen by throttling unlock attempts and possibly limiting the number of attempts before the phone reboots (thus requiring the stronger password to decrypt). Apps like Cryptfs Password previously made this easy, but unfortunately on CM13 nightlies (Android Marshmallow), this no longer works as the interface has changed. In fact, using one of these apps, or the old command-line syntax can cause data loss! If you are coming here after attempting to change your password and finding that you can longer decrypt your phone, I’m sorry, I don’t know how to recover data in this case.

I do not know of an app that can change the encryption password on these devices yet, but you can still change it from the command-line. This must be done as root, so you will need to enable root in the developer options, then use su in the terminal. Note, however, that the syntax has changed. Previously, the command was:

vdc cryptfs changepw password newpassword

Now the command expects an additional parameter, the old password:

vdc cryptfs changepw password default_password newpassword

Currently, the old password parameter is not used (it doesn’t actually have to be the old password, it can be anything), but it must be present for the new password to be interpreted correctly. The command should indicate success by printing:

200 0 0

Yea, it would be nice if it gave helpful error messages, but all you get is cryptic numerical codes. You can verify that the password was set correctly with:

vdc cryptfs verifypw newpassword

If the new password is correct, this command will also print:

200 0 0

In order to set the encryption password correctly and separately from the lock screen, you will want to encrypt the phone, then set your lock screen with a password (opting to require the password at start up), then change the encryption password with the command above. Now the lock screen will be the password you originally selected when you set the lock screen password, but the stronger password will be required to decrypt the device on boot.

Hopefully some of you got here in time to avoid data loss. Thanks for reading!

Wednesday, October 21, 2015

How to unbrick a Buffalo WZR-HP-G300NH and install OpenWRT

So, after a failed firmware installation, all you get is a flashing red DIAG light? All is not lost, you probably don’t need any special equipment or to open the case to unbrick the Buffalo WZR-HP-G300NH. You can probably still tftp a new firmware image when the router boots up. Instructions here are for Debian, but should be easily adaptable for other Linux distros. First, download the firmware image you want to install. If you want to install OpenWRT, it is going to be the ar71xx and make sure you get the tftp version. Here is the one I used. Now you will need to make sure you have a tftp client installed:

aptitude install tftp-hpa

Now you need to configure your network to connect to the router and create a static arp entry for it. Directly connect the router to your computer by ethernet cable, but leave the router powered off. You will need the MAC address for the router, you can get it from the SSID on the label, just insert colons like: 001D12345678 = 00:1D:12:34:56:78. You will need to do this as root.

/etc/init.d/networking stop
ifconfig eth0 192.168.11.2
ifconfig eth0 netmask 255.255.255.0
arp -s 192.168.11.1 00:1D:12:34:56:78


Replace eth0 with the ethernet interface you are using, if necessary (it is probably eth0), and use the MAC address from your router, as described. But the IP address should be as shown, not based on your usual network configuration. Now change to the directory where you downloaded the firmware image and start up your tftp client and prepare to send the image to the router (don’t power it on yet). Once you start the tftp client, you will be typing at it’s command prompt.

tftp 192.168.11.1
tftp> verbose
tftp> binary
tftp> trace
tftp> rexmt 1
tftp> timeout 60
tftp> put openwrt-15.05-ar71xx-generic-wzr-hp-g300nh-squashfs-tftp.bin


(Replace the name of the image, if you are using a different one.) As soon as you hit enter on that last command, plug in the router. The tftp client will keep retrying until the bootloader on the router is ready to receive the image, then you should see the upload begin to progress. Wait a few minutes and the router should reboot. Now you can turn your normal networking back on.

/etc/init.d/networking start

If you installed OpenWRT, the default IP for the router will now be 192.168.1.1, not 192.168.11.1. If your image included LuCI, like the one I used, you can now point your web browser to that IP to access the web interface. Now you have not only unbricked your router, but you are free to enjoy all of the awesomeness of OpenWRT!

Most of the instructions here are based on this post, many thanks to the author!

Saturday, November 22, 2014

Better speech compression with Opus

In a previous post, we looked at configuring Audex for ripping CDs to the superior Opus format. While that was good for general purpose audio encoding, it doesn’t let us take advantage of Opus’ immense versatility, it’s ability to get excellent results across a wide range of bit rates.


You will notice at the low end of that graph are codecs that typically specialize in speech, because speech is more compressible that complex audio sources like music. Speex, for instance, can get excellent compression of speech with acceptable quality, yielding much smaller file size than MP3 or Vorbis. One of the benefits of Opus is that it should be able to replace this usage as well.

As you might have guessed, the opusenc commands we gave Audex can also be used directly on the command line. If you want to target a lower bit rate for speech encoding, all you need to do is add the --bitrate option. For speech, try something in the range of 16-48. In Audex, you might add two different profiles for compressing speech with Opus, just as there are multiple profiles for different qualities of compression with Vorbis.

opusenc takes raw, Wave, AIFF, or FLAC input (FLAC is still the preferred format for archival storage). If you pass a FLAC file that is already tagged with metadata, opusenc will incorporate that metadata automatically, so there is no need to pass it on the command line.

opusenc --bitrate 16 input.flac output.opus

For comparison, a 40 minute audio recording ripped as an uncompressed Wave file was about 403 MB, compressed with FLAC it was about 103 MB, opusenc with default settings got it down to about 26 MB, while the above command reduced it to about 4.5 MB. So targeting the lower bit rate was a space savings of over 80% and made it small enough to share by email.

Saturday, November 15, 2014

Ripping CD to .opus with Audex on Debian

The Opus codec is basically the one codec to rule them all. It is an open standard (RFC 6716) and it outperforms almost all other codecs, open and proprietary, over a huge range of bitrates. It also has a very low latency which is important for internet applications involving real-time communications and it is already supported by modern browsers like Firefox, Chrome, and Opera. But if you want to start storing your music in the best available format, you might have difficulty finding convenient tools that support it. Well, here is one that worked for me, so I’ll share it. It was pretty simple, although not entirely obvious.

Audex is a graphical CD ripper for KDE. It does not support ripping to Opus out-of-box, but it does have a feature to add a new encoder. For this, we will just use the command-line encoder found in opus-tools, so install the packages audex and opus-tools. Now, when you run Audex, go to “Settings” > “Configure Audex...”, select the “Profiles” section, and then “Add...”. Name the new profile “Opus”. Under the “Encoder” tab, select “Custom” from the first drop down. Under “Command pattern:”, put in “opusenc $i $o”, and under “Suffix:” put in “opus”. You can look at some of the other options if you wish (I set mine to replace spaces with underscores), but that is all that is necessary to get it working. Save your new profile, select the profile from the main window, and begin ripping your favorite discs.


If you also want to capture metadata, you will need a newer version of opus-tools than what is in Wheezy. You can download the source, and build it yourself. You will need to have the wheezy-backports repository enabled to get some of the dependencies:

sudo aptitude -t wheezy-backports install libogg-dev libflac-dev libopus-dev

Once the dependencies are met, you should be able to configure and install opus-tools:

cd opus-tools-src-dir
./configure
make
sudo make install


Now, you can change the “Command pattern:” in Audex to “opusenc --title "$ttitle" --artist "$tartist" --album "$title" --date "date" --genre "$genre" $i $o”. This will capture metadata and embed it in your new Opus files.

Update: If you are looking to get better compression for speech recordings, such as lectures, sermons, speeches, etc, see this post.

Thursday, November 13, 2014

Setting up root SSH login on CyanogenMod

I did this with the latest CyanogenMod 11 snapshots on a Nexus 4 and a Nexus 5. I recommend buying a device with an unlockable bootloader, like the Google Nexus devices, because it makes rooting and installing custom ROMs, etc, much more straightforward. Besides, if you buy a device you ought to own it, so why give your money to a company that tries to lock you out of your own devices, as if they still own it even after you have bought and paid for it? If you already have a device that is locked down, you may have to search the web to find a hack to get access to it (Good luck!), but I won’t be covering that here. What I found to be difficult to find and poorly documented elsewhere was how to configure your device for root login via ssh, after installing CyanogenMod. This can be useful for a variety of reasons, for instance, you can easily make a full back up of the phone securely over your wireless network. But as always, exercise caution when using root!

Before you begin, make sure you have a few options set on the Android device. Under “Developer options” make sure that “Android debugging” is enabled, “Root access” is set to “Apps and ADB”, and while you are here, set “Device hostname” to something memorable. (You should have learned to access the hidden “Developer options” menu while install CyanogenMod.) Now, with phone connected by USB, login from your computer with:

adb shell

then start setting up ssh by copying over the template configuration file:

cp /system/etc/ssh/sshd_config /data/ssh
vim /data/ssh/sshd_config

and add the line:

PermitRootLogin without-password

This does not do what it sounds like. It will not allow you to login without authenticating, rather, it disables authentication with a password and requires you to use public key authentication which we will set up in a minute. Next:

mkdir /data/local/userinit.d
cd /data/local/userinit.d
cp /system/bin/start-ssh 90sshd
vim 90sshd


and change:

   # don't daemonize - otherwise we can't stop the sshd service
   /system/bin/sshd -f /system/etc/ssh/sshd_config -D


to:

   # don't daemonize - otherwise we can't stop the sshd service
   ## Actually, yes, do daemonize (remove -D option)
   /system/bin/sshd -f /system/etc/ssh/sshd_config


Now, if you don’t already have one, you will need to generate an RSA key for ssh. On your computer (not the adb shell that is already logged into your Android device) run:

ssh-keygen

and with the default options you will get a ~/.ssh containing id_rsa and id_rsa.pub. You will need to copy id_rsa.pub to your Android device in order to be able to login. Still working from your computer:

adb push ~/.ssh/id_rsa.pub /sdcard/

Now, on the Android device:

cd /data/.ssh
touch authorized_keys
cat /sdcard/id_rsa.pub >> authorized_keys
chmod 600 authorized_keys


Note that the authorized keys file must not be readable by anyone else or ssh will refuse to use it and authentication will fail. Now, you should be able to reboot and login to your Android device:

ssh root@AndroidHostname

If you set a password for the RSA key you generated for ssh, it will prompt you for that password, but it will not prompt for a password for root on the Android device (because it is using the key instead). If you want to login from other devices, make sure you have an authorized key on that device as well. To add more authorized keys, simply concatenate them onto the authorized_keys file, the same way we did the first one. Now you can remotely access your Android device via ssh.

Saturday, September 13, 2014

Watch the NFL Sunday Ticket on Linux

If you subscribe to the DirecTV NFL Sunday Ticket, you can watch all of your Sunday football games on Linux. But it only works with certain browsers because it requires Flash Player 14 which is only available on Linux as a Pepper plugin. Only the Chromium family of browsers supports this API, and the NPAPI version that is used by other browsers is no longer developed on Linux by Adobe (version 11.2 is still receiving security updates). The easiest way to get this is to install Google Chrome. It is also possible to use it with the Chromium packages provided by various Linux distributions; packages are available to install it for both Debian and Ubuntu. For Debian it is in the contrib repository and for Ubuntu it is in Multiverse. It may also be possible to use it with the developer version of Opera, which is now Chromium-based as well, but I haven’t tested this.

Of course, this doesn’t mean that you must or even should swap browsers. You can use a Chromium-based browser with Flash for the NFL Sunday Ticket and still choose another browser, like Mozilla Firefox which seemed to come out ahead in our recent benchmarks, for other things. Ultimately, we would all really like to see web applications, including video streaming, developed with HTML5 and web standards. Mozilla is probably one of the biggest forces pushing for this. Some people even refuse to use the proprietary Flash plugin at all in order to help promote this lofty goal. But if you want to watch your NFL games on Linux this year, now you know how.

Sunday, August 17, 2014

Protip #3: You do want your OpenPGP key to expire

You think you don’t, but you really do.You are probably thinking you don’t want to have to transition to a new key on some arbitrary date. But you can always extend the expiration later. And if you lose your key and don’t have a revocation certificate, the expiration date serves as a kind of “dead man’s switch”. If you don’t prevent it from being triggered by extending the date, your key will be automatically invalidated. This way, if you lose your key (and you don’t have a revocation certificate or have lost that, too), your key will not remain valid forever.

If you use Thunderbird with the Enigmail extension, per my previous tutorial, it is pretty easy to change your key’s expiration date from the Key Management interface. Right-click your key and select Change Expiration Date. Then you can select how many years, weeks, or days it should be until your key expires.




Of course, you will need to re-upload your public key so that your friends can get the extended expiration from the key server. Of course, you can also do the same with GnuPG from the command line, but I’ll leave that as an exercise to the reader.

And now you have no reason to have no expiration date on your keys!

Friday, July 18, 2014

Create your Own Word Searches on Debian, Ubuntu, Mac OS X, or Windows

Creating your own word search is really simple. They can be easily generated by software, given a simple word list, and I’m going to share just such an application with you today. Word Search Creator is a desktop word search generator licensed under the GPLv2 (so it is free as in freedom, as well as price). The downloads page has packages specifically for Ubuntu, Windows, or Mac OS X. These are pretty straight-forward to install. Ironically, there is no package for Debian (the parent distro from which Ubuntu is derived), and the Ubuntu package is not installable on Debian stable. But no worries, this is open source software! So for Debian we will just install from source.

Installing from source on Debian

Before we can install Word Search Creator, we need to install the Qt4 developer tools:

aptitude install qt4-dev-tools

Now, download the source, unpack it and cd to the unpacked source directory. To build the application, just:

qmake
make


In order to install it system wide, as root:

make install

If you are running KDE, run kbuildsycoca4 to rebuild your application menus.

Create a Word Search

When you first open Word Search Creator, there is a control box on the right side that you use to create the word search. Here you can type in a word list and set the size of the grid (or set it to automatically enlarge based on the words you give it). Type in a title and hit Create/Shuffle to generate your word search (hitting it again will, as the name suggests, shuffle your word search).


The menus give you a number of other options you can set. By default, words are only hidden left to right or top to bottom, but you can choose which directions are allowed. You can also choose how the word list is ordered, and edit the formatting. Perhaps one of the coolest features is the ability to change the shape of the puzzle by excluding squares from the grid.


Having fun with it

You can work the puzzle right there on screen, highlighting the words as you find them, and they will automatically get struck off the list.


You can also save it as a word search file, export it to pdf or svg, or copy it to the clipboard as an image (Ctrl + C). Working with it as an image, you can also use an image editor to decorate your word search. Here, I have simply filled in the empty squares and given it a yellow background color to highlight the smiley face.

And here is a full page puzzle.


Try it out yourself, and have fun!

Wednesday, June 25, 2014

Windows Browser Benchmarks

Ok, so this a bit off topic for this blog as it isn’t really a how-to, but I thought it might be interesting to my audience nonetheless. I ran the major browsers through four different benchmarks: Google’s Octane 2.0, Mozilla’s Kraken 1.1, and Apple’s new JetStream and Speedometer (the latter focuses on measuring the responsiveness of web apps by simulating user interactions). For graphing purposes, I normalized the scores on the various benchmarks so that the fastest browser was always 100 (this also means inverting scores for Kraken, which measures time rather than some unit of speed).

To make things interesting, I decided to include some less common variants, as well as the major browsers. I have been hearing about optimized Firefox-derivatives like Pale Moon and Waterfox and wanted to see how they stack up. Here is what I found:



The official Mozilla build was generally faster, although Waterfox was a bit ahead on the Kraken. Pale Moon was consistently last. Both Waterfox and Pale Moon are based on older versions of Firefox. Apparently, the optimizations don’t make up for the improvements in newer versions of Mozilla Firefox, at least not at this time.

And here is how Mozilla Firefox stacks up against other major browsers:


Firefox was the leader except on Octane, where it was pretty close behind Chrome and Opera (which is now based on Chrome, hence the very similar scores). Internet Explorer was consistently near the bottom, losing on both Octane and the Kraken by a wide margin. Although it wasn’t last on Speedometer and JetStream, even coming in second on Speedometer, it was still nearer the bottom than it was to catching Firefox in the lead.

And here I put them all on one chart for a more complete overview:


Finally, I decided to do a combined comparison by looking at how far behind the lead each browser was on each benchmark. This graph is like a target with the bullseye in the center. A browser that was fastest on all benchmarks would be dead center, and the one losing by the widest combined margin would be furthest from the center:

Here we can see that Firefox was the clear winner. Waterfox still outperformed Chrome and Opera, while Pale Moon fell behind them. Internet Explorer was clearly last. Note, however, that the benchmarks are not really meant to be combined in this way and you could probably easily shift these rankings by choosing different benchmarks. Nevertheless, I think the results are interesting.

And for anyone who is particularly interested, here are the original numbers:


Octane Kraken Speedometer JetStream
Firefox 30 9169 3709.8 25.57 65.589
Pale Moon 24 7005 4413.8 19.15 57.805
WaterFox 28 8483 3405.5 21.5 62.103
Chrome 35 9698 3824.3 16.1 55.168
Opera 22 9551 3853.7 15.7 46.022
Internet Explorer 11 6416 6286.4 18.14 50.282

Wednesday, May 7, 2014

Generating and learning strong passwords, Python version

Just for fun, I rewrote my password shell scripts in Python. These scripts work essentially the same way and are compatible with the scripts from the previous post. The real purpose of this exercise is to give you the chance to compare some of the syntax and features of the languages.

This is my first post using Python, but I’m not going to explain all of the basics of Python syntax here. If you aren’t familiar with Python, you may want to read a tutorial or introduction to the language first.

Here is what genpw.py looks like:

#!/usr/bin/python3

import random
import sys

chars = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', '!', '"', '#', '$', '%', '&', '\'', '(', ')', '*', '+', ',', '-', '.', '/', ':', ';', '<', '=', '>', '?', '@', '[', '\\', ']', '^', '_', '`', '{', '|', '}', '~' ]
length = 13
pw = ""

for i in range(1, len(sys.argv)):
    if sys.argv[i] == "--alnum":
        chars = chars[0:62]
    elif sys.argv[i] == "--length":
        length = int(sys.argv[i+1])
    elif sys.argv[i] == "--forbidden":
        forbiddenchars = sys.argv[i+1]
        for ch in forbiddenchars:
            chars.remove(ch)

end = len(chars) - 1

for i in range(0, length):
    index =  random.randint(0, end)
    ch = chars[index]
    pw += ch

print(pw)


First, we start with a list of printable ascii characters. Since it has been sorted into numbers, letters, and symbols; we can get the alphanumeric subset with a simple slice operation. And we can remove any forbidden characters by simply calling the remove() method of the list of characters. Then, we find how many characters are in the resulting list and generate a random number within that range for each character in the final password. We simply use that number as the index to choose one of the characters from our list and then print the completed password string.

The approach here is slightly different from the one that I used in the Bash script. There, we generated a stream of random numbers and filtered out only the desired characters until we had the desired length. Here, we create a list of desired characters and select the desired number of characters randomly.

And here is what setpw.py looks like:

#!/usr/bin/python3

import sys
import os
import hashlib

if len(sys.argv) > 1:
    name = sys.argv[1]
else:
    name = "default"

pw = input().encode('ascii')
pwhash = hashlib.sha512(pw).hexdigest()
hashfile = os.path.expanduser("~/." + name + "pwhash")

print("\033[1A\033[0K", end="")
with open(hashfile, 'w') as f:
    f.write(pwhash)


This one is even more similar to the Bash version, it’s approach does not substantially differ.

Finally, here is what ppw.py looks like:

#!/usr/bin/python3

import sys
import os
import hashlib
import getpass

if len(sys.argv) > 1:
    name = sys.argv[1]
else:
    name = "default"

pw = getpass.getpass("").encode('ascii')
pwhash = hashlib.sha512(pw).hexdigest()
hashfile = os.path.expanduser("~/." + name + "pwhash")

with open(hashfile, 'r') as f:
    storedhash = f.read()

if pwhash == storedhash:
    print("Correct")
else:
    print("Wrong\a")


Again, the approach here is essentially the same as the Bash version. You may notice that instead of input(), I used getpass.getpass(""). This prevents it from echoing the characters to the terminal. By default, getpass() uses the prompt Password:, so to make it more consistent with the Bash version I passed it an empty string instead.

Hopefully you found this little exercise entertaining and educational.

Sunday, April 27, 2014

Generating and learning strong passwords

In the wake of the recent catastrophic security vulnerability known as “Heartbleed”, many people have been tasked with thinking of new strong passwords for their online accounts and learning them. I’m not writing about Heartbleed, per se, but suffice it to say that you need to change passwords for any affected sites (after the vulnerability has been patched) and any sites you may have reused those passwords on. What I’m sharing here is an approach to generating and learning strong passwords. There are many approaches to password security, including password managers and using long passphrases instead of simple passwords, but I’m just sharing one approach here.

Humans are not very good at generating random passwords, so it can be helpful to use a proven computer algorithm and then simply work to memorize the password that was generated. We are going to use a bit of Bash scripting with the OS pseudo-random number generator and some basic Unix utilities for this. One of the best ways to memorize a strong, random password is to practice typing it. To help with this, we are also going to use a bit of Bash scripting that will let us type the password repeatedly and check if it is correct.

We could create three different shell scripts for this and keep them somewhere like /usr/local/bin (for system-wide use) or somewhere in your home directory (for personal use). Or, we could define them as functions in /etc/bash.bashrc (for system-wide use) or ~/.bashrc (for personal use). I’ll present them both ways, first as individual scripts and at the end as a series of functions. Putting them in separate script files would make them available from other shells, etc. (If you login to csh and invoke one of the scripts it will simply call Bash to run it. If you defined them as functions they would be unavailable in csh.)

First, here is a one-liner to generate a random password:

cat /dev/urandom | tr -cd "[:graph:]" | head -c 13 && echo

The first part reads from the pseudorandom number generator and passes it to the next part, the tr command removes all characters that are not printable ascii (you could also use "[:alnum:]" to generate an alphanumeric password), head -c takes only the specified number of characters and then terminates the pipeline, and the echo command simply outputs a newline, so that we don't end up with the command prompt being printed on the same line at the end of the password.

Now, we’ll look at a more complete example that takes command line options instead of manually editing our command:

#!/bin/bash
chars="[:graph:]"
length="13"
forbidden=""
for i in $(seq 1 $#); do
    if [[ "${!i}" == "--alnum" ]]; then
        chars="[:alnum:]"
    elif [[ "${!i}" == "--length" ]]; then
        ((n=$i+1))
        length="${!n}"
    elif [[ "${!i}" == "--forbidden" ]]; then
        ((n=$i+1))
        forbidden="${!n}"
    fi
done
cat /dev/urandom | tr -cd "$chars" | tr -d "$forbidden" | head -c "$length"
echo


This script takes several arguments. The --alnum argument limits the password to alphanumeric characters rather than printable ascii. The --length option is followed by the number of characters to generate and --forbidden is an additional list of forbidden characters (useful for sites that accept special characters with a few stated exceptions). The default is 13 characters consisting of printable ascii characters. 13 random ascii characters meets the NIST recommendation for 80 bits of entropy for a strong password (learn more about password strength on Wikipedia).

The for loop here counts the number of arguments passed to the script (stored in $#) and loops over them. The ${!var} notation treats $var as the name of another variable. In other words, if $i is 1, then ${!i} is the same as $1 which is the first argument that was passed to the script. The double parentheses are used to evaluate a mathematical expression. After evaluating the command line arguments, we have essentially the same pipeline we used before. The -d option for tr deletes characters from the input, while -c means to delete everything but the specified characters (the “complement” of the specified character set). So the first tr command removes all of the characters except for printable ascii (or alphanumeric, if specified), the second removes additional characters specified with --forbidden.

Now, on to our password practicing tools. First, we need a way to set the password:

#!/bin/bash
name=${1:-default}
read pw
echo -ne "\033[1A\033[0K"
echo -n $pw | sha512sum | tr -d ' -' > ~/.${name}pwhash


The read command takes input from the user and stores it in a variable named pw. By default, read prints what you are typing to the terminal. We allow it to do so here, so that you can make certain you are typing the password correctly the first time. However, as soon as we have finished typing and hit “enter”, we clear that line so the password is no longer visible. The -n option tells echo not to automatically output a newline at the end, and the -e tells it to interpret escape sequences. The sequence \033[1A moves the cursor up one line, and \033[0K deletes the current line. Rather than storing the password itself, we store a hash of the password for a bit of extra security (hopefully, of course, the machine we are doing this on is already secure, but this is a simple precaution to take). The sha512sum prints a couple of spaces and a hyphen at the end; the tr -d ' -' removes these. This script optionally takes one argument, a name so that you set and practice multiple passwords. The notation ${1:-default} is equivalent to $1 if it is set, otherwise it defaults to default.

Now, we need a way to practice typing the password we set:

#!/bin/bash
name=${1:-default}
read -s pw
userhash=$(echo -n $pw | sha512sum | tr -d ' -')
storedhash=$(cat ~/.${name}pwhash)
if [[ $userhash == $storedhash ]]; then
    echo "Correct"
else
    echo -e "Wrong\a"
fi


This time we used the -s option so that read does not print what you are typing to the terminal. Similar to the first script, this one optionally allows you to specify a name and then compares the hash of the password you type to the one that was previously stored. If they match, it informs you that you have typed the password correctly; if not, it let’s you know it was wrong. The \a is the bell character; it may give an audible alert, or in some cases a visual alert or nothing at all, but it is a nice touch to get your attention when the password is typed incorrectly.

Putting them all into functions is quite simple:

function genpw() {
    chars="[:graph:]"
    length="13"
    forbidden=""
    for i in $(seq 1 $#); do
        if [[ "${!i}" == "--alnum" ]]; then
            chars="[:alnum:]"
        elif [[ "${!i}" == "--length" ]]; then
            ((n=$i+1))
            length="${!n}"
        elif [[ "${!i}" == "--forbidden" ]]; then
            ((n=$i+1))
            forbidden="${!n}"
        fi
    done
    cat /dev/urandom | tr -cd "$chars" | tr -d "$forbidden" | head -c "$length"
    echo
}
function setpw() {
    name=${1:-default}
    read pw
    echo -ne "\033[1A\033[0K"
    echo -n $pw | sha512sum > ~/.${name}pwhash
}
function ppw() {
    name=${1:-default}
    read -s pw
    userhash=$(echo -n $pw | sha512sum)
    storedhash=$(cat ~/.${name}pwhash)
    if [[ $userhash == $storedhash ]]; then
        echo "Correct"
    else
        echo -e "Wrong\a"
    fi
}
function unsetpw() {
    name={1:-default}
    shred -uxn1 ~/.${name}pwhash
}


I added an extra one here to unset the password by removing the hash from your system, although this one is fairly trivial. In addition to learning one handy way to generate and learn strong random passwords, hopefully this little exercise has also given us a look at some handy Unix tools and Bash scripting features. For comparison, I’ve also written a Python version of these scripts.

Saturday, March 15, 2014

Installing your CUPS shared printer on Windows

This is one of those things that really isn’t that complicated, but it doesn’t work as intuitively as it should and I find myself looking it up every time I have to do it again, so I’m going to go ahead and document the process here in a clear and easy to follow fashion. I’m not showing how to set up the printer with CUPS on Linux, I’m assuming that is already done and just showing how to add that printer on Windows (Windows 7 is shown here).

First, you need to know the name of your printer. If you have forgotten, you can easily find this by using your web browser to pull up localhost:631, this is an administrative interface for your CUPS server. Click the Printers tab and you will see your printer’s name under Queue Name in the first column.



Now that you know the name (and the IP address or domain name for the computer), we are ready to add the printer in Windows. Pull up Devices and Printers from the Start menu. Click the Add Printer button to pull up the Add Printer dialog. Of course, we will be selecting Add network, wireless, or Bluetooth printer. It won’t find the printer, but don’t worry, just select The printer I want isn't listed. Now use Select a shared printer by name. Ignore the examples, the correct format to enter is:

http://ipaddress:631/printers/Printer_Name

or:

http://domainname:631/printers/Printer_Name

Now, you will have to select the manufacturer and model (or series) of your printer. Now you’ve installed the printer and you will presented with an option to print a test page to make sure it works.







As I said, it was pretty easy, just not exactly intuitive. And now you should be able to print from Windows to the printer attached to your Linux machine (or other Unix system, including Mac).

Sunday, March 9, 2014

Fun Unicode Characters for Facebook (and Generally Anywhere).

 Here is just a sample of fun unicode characters for Facebook. You can use these pretty much anywhere (including Google+), but I’ve specifically selected a few that don’t have emoticon equivalents supported by Facebook (at least that I’m aware of), don’t get converted to graphic emoticon representations by Facebook, and do display properly on most systems.

There are several different ways you can type the characters, depending on your system. You can use the hex codes on Windows and Linux (at least GTK apps). Using hexadecimal input for unicode characters on Windows can be a little tricky, though. Older alt codes can be used for some, but not all of the characters. Although the characters you can type with alt codes is limited, they have two advantages: they don’t require any special configuration and since they are decimal numbers they don’t contain any letters that are likely to cause conflicts with program shortcuts, so I’ve included them in the chart where applicable. To use the alt codes, you simply hold the Alt key while typing the number (you don’t use the + key like you do for the hex codes). Please note the leading 0 is important, alt code 145 produces a different character (æ) from 0145.

The easiest and most convenient input method is the compose key on Linux. It doesn’t cover all unicode characters, but it covers more useful characters than alt codes and they tend to be much easier to type and remember because they tend to be mnemonic (while not on the list because Facebook provides emoticon equivalents, the compose sequence for a smiley is :), a frowney is :(, and a heart is <3). There is a caveat, however, for the compose key on GTK apps. GTK overrides the configurable behavior of the compose key, unless you specifically configure to it use the underlying configuration from X. In order to do this, you will want to add a line to your ~/.Xsession like this:

export GTK_IM_MODULE="xim"

Then log out and back in. You can also type the above line directly into a terminal and then launch the GTK app from that terminal if you want to just quickly try it. The highlighted compose key sequences below may not work in GTK apps—including Firefox and OpenOffice—without this extra configuration, however.

Of course, if you have trouble typing any of the characters, you can also copy and paste them from here. That isn’t exactly the point here, but it will work.

DescriptionComposeAltHexCharacter
left single quote<'01452018‘
right single quote
(apostrophe)
>'01462019’
left double quote<"0147201C“
right double quote>"0148201D”
en dash--.01502013–
em dash---01512014—
hedera2766❦
side-ways hedera2767❧
degree symboloo24800B0°
copyright symboloc016900A9©
registered trademark symbolor017400AE®
trademark symboltm01532122™
bullet point.=72022•
cross
271D✝
outlined cross271E✞
check mark2714✔
x mark2718✘
snowman2603☃
infinity symbol88236221E∞
radiation symbol2622☢
skull and crossbones2620☠
eighth note#e13266A♪
beamed sixteenth notes#S266C♬
musical sharp symbol##266F♯
musical flat symbol#b266D♭

Bonus: Tux


It is often asked if there is a unicode character for Tux, the penguin who serves as the Linux mascot. There is no character for Tux in the unicode standard, however there is a private area for fonts to include non-standard characters. Linux Libertine, an excellent free font, includes Tux at code point e000. You can use this character if you can specify the font, such as on a web page (better use @font-face or the browser will fallback to something else if it isn’t installed) or in a document where you select the font. If you use this on Facebook, it will only display properly for those who have the font installed and have a browser that automatically falls back to a font that has the character available if it isn't in the currently selected font.

Here is what it looks like, if you have the font installed:

And here is what it looks like a bit larger:

Note: I changed the font color for Tux to black and the background to white, because it does look rather odd in reverse. I also made sure to remove the text-shadow effect.

Typing Arbitrary Unicode Characters in Linux

Ok, this one is a little strange. The X server that provides a graphical environment on Linux does not offer a feature to input arbitrary unicode characters by code point. It does provide a powerful feature to enter some unicode characters by mnemonic sequences with the compose key. GTK, a toolkit used by Firefox, OpenOffice, and Gnome applications, does provide a way to input arbitrary unicode characters. If you are using these and have not reconfigured it, you can input arbitrary unicode character by holding down the Ctrl and Shift keys while you type the letter u followed by the hex code for the unicode character you want. To be clear, the only keys you hold are Ctrl and Shift, the rest are typed in a sequence and then you release Ctrl and Shift.

Now, here is where it gets interesting. GTK overrides the default input for the X server and provides it’s own set of compose key sequences. This is nice for consistency, but the default configuration for the X server may provide compose sequences for characters that are not supported by GTK. Additionally, the X compose feature is configurable: you can add new sequences for characters you want to use. This is very convenient. It is possible to use the default X input method in GTK apps, but you lose the ability to input arbitrary unicode characters. If you prefer to use the default X input method, you can accomplish this by adding a line to your ~/.Xsession like this:

export GTK_IM_MODULE="xim"

You can also change this for a single app by entering the same thing on the command line in a terminal app and then launching the desired application from the same terminal. Now you will be able to use compose sequences such as Compose + #e to get a musical eighth note like this: ♪. You can also add your own compose key sequences by editing /usr/share/X11/locale/en_US.UTF-8/Compose. Personally, I think having a powerful, configurable compose key is more valuable than arbitrary unicode input, but I’m still looking for a way to have both.

Typing Arbitrary Unicode Characters in Windows

There is actually a way to directly type in unicode characters by code point in Windows, but it may take some configuration to get it to work properly. To use this method, you have to memorize the hex code for the characters you want to use, but it will allow you to type in obscure characters like the ornamental typography symbol called a hedera ❦ or a musical note ♪.

This method is supported on Windows 2000 and up; I'm demonstrating it on Windows 7. You will need to create a registry key to enable this feature and log out and back in (or reboot on older versions). Caution! Editing the registry can be dangerous, follow the directions and don't mess with anything else.

First, open regedit. Now, in the tree in the left panel, expand the path HKEY_Current_User/Control Panel/Input Method. In the open space on the right, right-click and select New > String Value. Type in the name EnableHexNumpad. Now, right-click the value and edit it, type 1 in the Value data field and click Ok. Now log out and in (or reboot).






Now, all you have to do is hold the Alt button, press + on the numpad, and then enter the hexadecimal code for the unicode character you want. Unfortunately, shortcuts in some applications may interfere with this. For instance, in Firefox (English language versions) there is a bug, preventing you from entering codes containing the letters B, E, and F since these trigger the Bookmarks, Edit, and File menus. Linux doesn't seem to have this problem since it typically uses Ctrl + Shift instead of Alt (and starts the sequence with a u, rather than +). Nevertheless, this can be a handy technique, so give it a try. Unicode contains a huge number of characters, you can find handy codes with a simple web search. (A few cools ones are in my newer post.)


Saturday, March 8, 2014

Easily Type Accented Characters, Curly Quotes, and Other Symbols in Linux with the Compose Key.

Setup


While there are a variety of ways to input special characters not found on your keyboard, the compose key provides one of the easiest. The key sequences are fairly mnemonic, making them easier to remember, and they are often shorter than equivalent hex codes and easier to use than copy and paste. But in order to use these, you may first have to make sure your system is set up to use a compose key.

KDE


In KDE, pull up your System Settings and select Input Devices. Under the Keyboard section, select the Advanced tab and check the Configure keyboard options box. Click the arrow to expand the Compose key position section, and then check the box for the key you wish to use. I’m using the right win key, which on my keyboard is actually the Tux key.





Gnome


In Gnome, pull up your System Settings and select Keyboard. Under the Typing tab, select Layout Settings. Then, under the Layouts tab select the Options... button. Under Compose key position, select the key you want to use as the compose key. Again, I’m using the right win key, which is actually the Tux key on my keyboard.






Usage


Now that your desktop environment is configured to use the compose key, all you have to do is hold down the compose key while typing the key sequence for the character you want to type. Note that some of these characters—such as the caret, tilde, and double quotes— require the shift key. You can press and release the shift key as needed while holding the compose key.

Accents and Diacritics


You don't really have to memorize the combinations for each accented character, there is generally a character for each accent, so you simply type [compose key] + [accent character] + [letter]. For instance, you use a single quote for an acute accent, so on my system Tux + ' + e gives me the accented characters for typing “résumé”.

AccentCharacterExample
acute'á
grave`à
circumflex^â
brevebă
diaeresis or umlaut"ä
tilde~ñ
cedilla,ç

Punctuation


NameKey SequenceCharacters
curly double quotes<" and >" “ and ”
curly single quotes<' and >'‘ and ’
en dash--.–
em dash---—

The right single quote character is also the preferred character for an apostrophe. The en dash is used to indicate a range of values, and for attributive compounds; the em dash is used to indicate a break in thought or interruption of speech, and to set off the attribution of a quote. Wikipedia has more information on dashes, if you are uncertain which to use.

Currency


NameKey SequenceCharacters
cent|c¢
pound-L£
euro=c€

Other Symbols


NameKey SequenceCharacters
degreeoo°
copyrightoc©
registered trademarkor®
trademarktm™


Friday, March 7, 2014

Batch file processing from the command line (photo-editing, renaming, etc)

One of the convenient things about the command line is being able to easily perform batch operations on a large number of files, things that are systemically applied to each file in the same way, such as replacing all of the spaces in file names with underscores or hyphens, resizing images or converting from .png to .jpg, etc. Here I'm going to present some of the basic tools for performing these kind of operations and you can then put them together in various ways to perform any number of customized tasks. Note that I'm using Bash for the interactive shell (or interpreter) here, and the parameter expansions presented here, although useful, are not portable.

Looping

The most common idiom you will see for iterating over a set of files is using the glob to match a set of files:

for f in /path/*

The * matches any file in /path, so it becomes the list of files in that directory. The variable f becomes each file (or rather, the full path to each file) in turn, and we can use that in the code that follows. The command following the for should begin with do and the loop will continue until it reaches the done command and then repeat for each file. The glob can be used to match part of a file, so we could operate on only the .png files in /path like this:

for img in /path/*.png

In addition to the glob, you can also use other things like brace expansion. For instance, /path/*.{png,jpg,gif} will give you all of the files ending in .png, .jpg, or .gif. If you have a set of pictures with names like DSC_nnnn.JPG, but you only want to work on images 5 through 22, /path/DSC_{0005..0022}.JPG would let you do this. You can also use command substitution to loop over the output of a command by wrapping the command with $() or ``.[1]

Parameter Expansion

Bash parameter expansion provides a really handy way of manipulating file names. Here we will see how to separately get the filename, path, and extension, and substitute one character for another.

Get the base name of a file:

base=${file##*/}

Get the path to a file:

path=${file%/*}

Strip the last extension from a filename:

new=${file%.*}

Strip all extensions from a filename:

new=${file%%.*}

These work by stripping a prefix (# and ##) or suffix (% and %%) from $file. In the first example, the * comes before the / because we are stripping a forward slash and everything that comes before it, while in the latter two examples the * comes after the . because we are stripping a dot and everything that comes after it. The double forms strip the longest match, while the single forms strip the shortest match. But with the latter two examples, beware files and directories with unexpected dots! For instance:

file="/home/user/my.pics/selfie.jpg"
echo ${file%%.*}


will print "/home/user/my",

file="/home/user/web2.0essay"
echo ${file%.*}


will print "/home/user/web2". Errors like these are easier to avoid when you are typing a quick command and know what kind of files you are dealing with. If you are writing a script that might later be used in different context, you must be extra careful that it doesn't break when file and directory names don't conform to your initial expectations.

Replacing spaces in a filename with hyphens:

new=${file// /-}

This form actually does pattern matching. You can also require it to match at the beginning or end by replacing the second forward slash with % or #, respectively. If you leave out the last part, whatever matches the pattern will be replaced by nothing, that is, it will be deleted. In this case, you can also omit the final forward slash. So you could remove only a three character file extension with:

new=${file/%.???}

Or you could remove a two digit prefix with:

new=${file/#[0-9][0-9]}

Resizing Images

For command line image processing, we will be using convert from the imagemagick package. The basic command for resizing an image is:

convert picture.jpg -resize 1232x816 smallerpicture.jpg

Note that this will not necessarily make the image exactly 1232x816, it will make it fit inside a box that is 1232x816; it will not squeeze, stretch, or crop the image to fit that exact size. If you want to distort the image to fit:

convert picture.jpg -resize 1232x816\! smallerpicture.jpg

Distortion, however, is often undesirable and it may be better to crop the image. Suppose you wanted to create a series of 64x64 thumbnails without distorting the images. You could crop them with:

convert picture.jpg -resize 64x64^ -gravity center -extent 64x64 thumbnail.jpg

The ^ means to make the image fill, rather than fit into, the 64x64 box. The extent crops the image to 64x64, and the -gravity center means to center the image when cropping so the thumbnail comes from the center of the original image.

Now suppose that you wanted to shrink a series of larger images, but you don't want to enlarge any that are smaller. You can do that like so:

convert picture.jpg -resize 64x64\> resized.jpg

You will notice that all of the above examples require a file name to be supplied for the output, so if we actually want to use them on a batch of files, we will need to combine them with a loop, like this:

mkdir /path/images/thumbnails
for img in /path/images/*.{jpg,gif,png}
do basename=${img##*/}
name=${basename%.*}
convert "$img" -resize 64x64^ -gravity center -extent 64x64 "/path/images/thumbnails/${name}-thumb.jpg"
done


For each image.jpg this will produce an image-thumb.jpg in /path/images/thumbnails. Note that this will create jpg thumbnails for gif and png images, too. You may also note that I didn't bother to write out a script for this, these commands can easily enough be typed in on the command line for a simple task, as explained in Protip #2. Of course, you could write a script if you will be doing the exact same operation frequently.

Convert Image Types

You will notice that our thumbnail example actually converted any gif or png images to jpg when generating thumbnails. Similarly, it is very simple to convert one image type to another, such as if you wanted to use a series of jpg images to make an animated gif or png (similar to this), you just leave out the resize part:

for img in /path/*.jpg
do convert "$img" "${img%.*}.png"
done

Renaming Files

We saw the basics for this when we introduced parameter expansion, but I'm going to go ahead and show a full example. Suppose that we have some files with spaces in their names and find this annoying when manipulating them from the command line, so we decide to replace the spaces with underscores. But some of the files have hyphens and the resulting "_-_" just doesn't look right, so you want to collapse the spaces surrounding a hyphen. Easy enough, we'll just use two steps:

for f in /path/*
do f1=${f// - /-}
new=${f1// /_}
mv "$f" "$new"

done

But what if the path contains spaces? That would be a problem here, but it's not too hard to get around:

for f in /path/*
do basename=${f##*/}
f1=${basename// - /-}
new=${f1// /_}
mv "$f" "${f%/*}$new"


We simply removed the path first, and added it back at the end.

And More!

You can do many more interesting things on the command line with Bash, and ImageMagick offers a huge selection of image editing features not mentioned here. If you want to learn more, you may want to check out the Bash Reference Manual and Examples of ImageMagick Usage. I also recommend GreyCat's Wiki, which has several resources on Bash, including an introductory guide, pitfalls, FAQ, and quick reference sheet.

Tuesday, February 25, 2014

Protip #2: Using loops from the commandline

Remember that the same things you can do in a shell script, you can also do directly from the command line. This includes looping constructs like for, while, and until. In a shell script you might write:

#!/bin/bash
for f in /home/user/Documents/*; do
    new=${f// /-}
    mv "$f" "$new"
done


to rename all of the files in your Documents folder, replacing spaces with hyphens (note that the parameter expansion, ${f// /-}, is not portable). But for something this simple, you don't need to write a script, you can just type this in on the command line, like this:

for f in /home/user/Documents/*
do new=${f// /-}
mv "$f" "$new"
done


or on one line:

for f in /home/user/Documents/*; do new=${f// /-}; mv "$f" "$new"; done

The indentation is irrelevant to the interpreter, we just use indentation in shell scripts for human readability. Those of you who have worked with a programming language with an interactive toplevel, such as Lisp or Python, may recognize how handy this is. Of course, many of you already know this and probably just went, "Duh!", but someone out there either didn't realize they could use loops from the command line, or just didn't really think of it because we usually see them in scripts. That person, upon reading this, was enlightened.1