Here at the Hollow in what can euphemistically be called a "cabin", there is no cell service, and I have not signed up for long distance, as all the phone is normally used for is to call a local dialup internet number.
It would be nice to be able to occasionally make outgoing long distance calls in this situation though. With some difficulty, Google voice can be used in this situation.
The difficulty is because my google voice number is itself a long distance call from here, so I can't just call it up and use it as intended. And google voice's web interface was not designed with dialup in mind; it assumes you have a phone line that's not carrying your internet connection.
verifying the phone
This is the tricky part. Google voice wants to call you back on your phone and have you verify a number. To start this process, you need to use the internet. It's impossible to hang up from the net before they call back.
Since it's a one-off, I didn't try to automate this, and just had someone do the internet side of the verification, call me with the number, and then trigger google voice to call me back.
(Google voice's forums are full of similar stories.)
making outgoing long distance calls
Here's the fun part. You'll need a shell account somewhere else, where you can download and install pygooglevoice.
Then create a ~/.gvoice file, filling in your login info and your phone number.
[auth]
email=
password=
[gvoice]
forwardingNumber=
phoneType=1
Now to make a call, you can just run something like this on the shell account:
sleep 2m; ./gvoice --batch call XXX-XXX-XXXX
The sleep gives you time to free up the phone line. Google voice then calls you and connects you with the number you requested.
How a window manager with tiling layouts makes a 1024x600 resolution livable.
I spend a lot of time in front of a screen, and for the past year I have used only my netbook. No desktops, no laptops. Just a cheap $200 computer that is nearly a kid's toy. The most challenging thing about this is dealing with the 1024x600 screen resolution. When I moved to this screen from something with many more pixels, it at first seemed very cramped.
After a year, I think that the most important part of coping with the small screen is the flexability and customizability of layouts provided by the Xmonad window manager. In this post I will explain a few layouts I have developed for fitting specific tasks onto the netbook screen.
(I assume that you know maybe 0.1% of Haskell (about what I do), and can read Haskell code without having a brain aneurysm.)
web browsing
It's important that the web browser have as few toolbars and other cruft as possible, as horizontal space is especially at a premium. I've configured both Epiphany and Firefox to put everything in one tool bar. But now I use Chromium, which comes pre-configured that way.
What the netbook is designed for. You just want a web browser, taking up
the full screen, and with its own tabs. So far, so easy: that's Xmonad's
Full
layout.
But, you sometimes want to see two websites side-by-side. This layout
accomplishes that, allowing the sizes to be adjusted as needed. It also
uses Xmonad's Magnifier
to zoom the smaller window when it's focused,
which is useful if you briefly need to see more of a web site.
mySplit = magnifiercz' 1.4 $ Tall nmaster delta ratio
where
-- The default number of windows in the master pane
nmaster = 1
-- Percent of screen to increment by when resizing panes
delta = 3/100
-- Default proportion of screen occupied by master pane
ratio = 60/100
web development
If you're doing web development, you'll want probably one big web browser
window, but also with a nice wide terminal on the same screen, in order to
see web server logs. A simple way to do this is to mirror Xmonad's Tall
layout by 90 degrees.
myWide = Mirror $ Tall nmaster delta ratio
where
-- The default number of windows in the master pane
nmaster = 1
-- Percent of screen to increment by when resizing panes
delta = 3/100
-- Default proportion of screen occupied by master pane
ratio = 80/100
The myWide
layout uses the full screen width for a single terminal,
and splits the width when there are more. This is sufficient for viewing logs
and doing minor things at the shell prompt, in between testing the result in
the web browser. Of course a terminal can be temporarily moved to the master
area by pressing mod-return
, if you need it to be larger.
chat
Tips on configuring Pidgin for a netbook: Set it up to use vertical tabs to save horizontal space. Configure the input area to only 1 line tall, and turn off as much other cruft as you can. The menu bars, sadly, cannot be disabled, nor can the excessively large borders. In my screenshots, you can see that stuff wasting space that could be used to show four more lines of text.
For chat, you want to put the buddy list on the side of the
screen, and use the rest for conversation windows. Xmonad's IM
module
takes care of allocating a sidebar on the screen for the buddy window. The
rest of the screen can be occupied by any layout you choose.
I like to have the conversation windows be as wide as possible, and
typically only want to see two conversations at a time. But sometimes I
might have a dozen visible. A good layout to cope with those needs is
Grid
.
myChat' l = withIM size roster l
where
-- Ratio of screen roster will occupy
size = 1%5
-- Match roster window
roster = Title "Buddy List"
myChat = myChat' Grid
The withIM
layout puts the buddy list on the left; I prefer it on the right
for some reason, so I tweaked my layout to do that. All it took was
using the reflectHoriz
layout modifier to get a mirror image of
the layout. Then I reflect the inner layout back to its normal orientation.
Being able to throw in a few function calls and mutate a layout like that
is where Xmonad shines.
myChat' l = reflectHoriz $ withIM size roster $
reflectHoriz $ l
logs
Ever notice that tail -f
wastes the last line of the terminal? On a netbook
this matters.
shorttail
lets the last line be used.
I have a dedidated workspace that I use to tail logs, and as a place to
send long-running tasks (such as compiles). The layout for this needs to
keep windows wide, to see whole logged lines, but they need only be five
or so lines tall. And it's convenient to have one bigger window with the
small ones below. Xmonad has a perfect layout for this, called Dishes
,
because it's sorta like a stack of plates.
myDish = limitWindows 5 $ Dishes nmaster ratio
where
-- The default number of windows in the master pane
nmaster = 1
-- Default proportion of screen occupied by other panes
ratio = 1/5
In the second screenshot above, I have 6 windows open, but only 5 are
visible. The limitWindows 5
accomplishes this. It's handy mostly because
gnome-terminal
has a bad habit of crashing when resized to 0x0.
(That's gotta be a bug in something!)
Notice that the screenshots above also have Procmeter in a sidebar on
the right. I (ab)used the withIM
layout to do that:
myLogs' l = reflectHoriz $ withIM procmeterSize procmeter $
reflectHoriz $ l
where
-- Ratio of screen procmeter will occupy
procmeterSize = 1%7
-- Match procmeter
procmeter = ClassName "ProcMeter3"
myLogs = myLogs' myDish
coding
Everything above was easy. Doing coding (or writing) on a small screen is where it gets hard. When I'm coding I want to have one window that is exactly 80 columns wide, and as tall as possible, where I do the main development. Then I need a minimum of two other windows also visible: one action window for running tests and the like, and one to view references (emails, man pages, other files, etc). I may need to view any of these windows fullscreen at any time, of course.
As an example of the three window rule:
While I'm writing this post, I have a reference window open
with my .xmonad/xmonad.hs
, and an action window open where I am
managing screenshots.
Often, deep into something, I will accumulate many other reference and action
windows. But three seems to be the magic, minimum number for me;
use of screen
or anything else doesn't reduce it; if I can't see all
three at once, I will waste time and concentration flipping back and forth.
The Xmonad layout I've developed to handle this is based on the handy
FixedColumn
layout, which automatically keeps the master window 80
columns wide. I modify this by adding the Magnifier
, so that my action
and reference windows "pop out" over the master window when focused.
myCode = limitWindows 3 $ magnifiercz' 1.4 $ FixedColumn 1 20 80 10
The 1.4 was carefully tuned, to magnify a window to be big enough to be
usable for editing, reading, or command-line, while not obscuring too much
of the other two windows. And again I use limitWindows
, to only show
three windows, in order to keep them all as big as possible. Other windows
are hidden offscreen, but I can rotate to them with alt-tab as needed.
reading ebooks
When I'm reading an ebook, I want to have the reader in the middle of the screen. But a widescreen netbook like mine is too wide to comfortably read text all the way across, so it's nice to have margins. (In the margins, I put terminals, or notes.)
The ThreeColumns
module has a layout that does just that.
myBook = ThreeColMid nmaster delta ratio
where
nmaster = 1
-- Percent of screen to increment by when resizing panes
delta = 3/100
-- Default proportion of screen occupied by master pane
ratio = 2/3
putting it all together
I join all my layouts together, so Xmonad will allow switching between them. These three combinations all have the same layouts, only ordered differently, so that different workspaces can have different default layouts.
codeFirst = myCode ||| myWide ||| myGrid ||| myDish
dishFirst = myDish ||| myCode ||| myWide ||| myGrid
gridFirst = myGrid ||| myDish ||| myCode ||| myWide
Xmonad layouts can be decorated with things like title bars. To save horizontal space, I leave off the title bars on layouts where they are not needed to disambiguate windows. Two helper functions can be applied to add or remove titles (and also cause the layout to avoid the Gnome panel.)
withTitles l = noFrillsDeco shrinkText myTheme (desktopLayoutModifiers l)
noTitles l = desktopLayoutModifiers l
I have semi-dedicated workspaces; one for each of the above activities.
To assign a layout to a workspace, I use the PerWorkspace
module.
Notice that the "web" workspace has only two available layouts.
Meanwhile, the "book" workspace always uses the specialized myBook
layout; I don't use that layout elsewhere.
perWS = onWorkspace "logs" (withTitles $ myLogs' dishFirst) $
onWorkspace "web" (noTitles $ (mySplit ||| myWide)) $
onWorkspace "chat" (noTitles $ myChat' gridFirst) $
onWorkspace "book" (noTitles $ myBook) $
(withTitles $ codeFirst)
Finally, I allow toggling between the currently selected layout and
fullscreen mode, and use smartBorders
to avoid displaying borders when
there is only one window onscreen.
myLayout = smartBorders $ toggleLayouts Full perWS
Xmonad layout optimised for the small screen of a netbook: Done! (For now...)
PS: Thanks to #xmonad
regulars for always having the answer
I need up their sleeves.
The Debian Installer has a USB boot image that is supposed to be written raw to the USB stick. Problem is that means the image has a fixed size, 256 MB, and all the other gigabytes on your typical USB stick are unusable after writing this image to it. It's a bit of a cheat for me to blog about this, since I'm slighly responsible for the thing that I'm working around. But still.
The real problem is not the fixed size of the image, but that it is written to the USB stick as a "super floppy", without any partition table. If there were a partition table, you could make a second partition in the rest of the space of the USB stick, and use it to store files, etc. So, let's set that up. It's not really hard:
- Use your favorite partition tool to partition the USB stick. Make a 256 MB DOS partition, that will be used to hold the installer, and set it bootable. Make a second, or more partitions for your own use.
- Unplug and replug the USB stick so the device files show up, and
write the installer image to the first partition (/dev/sda1 in this
example).
zcat boot.img >/dev/sda1
- Make the USB stick bootable by installing the
mbr
package, and runninginstall-mbr /dev/sda
- Copy a Debian ISO image to the USB stick somewhere. You can put it on the first partition, as ususal, or if you prefer, can put it on one of the later, larger partitions. That's useful if you want to use a larger ISO than the netinst. The installer should find it anywhere.
On my Palm Pre, I'm running a PalmOS emulator, with a VNC client in it, connecting to a VNC server on the same phone, in order to get to an xterm. About the most roundabout way to get a prompt on a phone one can imagine, and also very wasteful of screen space because of that PalmOS emulator. I hope better methods become available.
- Install Classic. (This will only work for a week w/o being bought, BTW.)
- Login as root to Debian chroot on the Pre.
- Download PalmVNC:
cd /media/internal/ClassicApps; wget http://palmvnc2.free.fr/stable/PalmVNC.prc
apt-get install tightvncserver
su
to your non-root account on the Pre.- Create a VNC password file containing an empty password by running:
mkdir -p ~/.vnc; echo | vncpasswd -f > ~/.vnc/passwd; chmod 600 ~/.vnc/passwd
- Run
tightvncserver -interface 127.0.0.1 -geometry 320x320
(It only listens to localhost, so the empty password is ok (ish). The geometry is all that is visible on the Pre without scrolling.) - Start Classic (or restart it).
- In Classic, select PalmVNC and tell it to connect to
localhost
, and change the display from 0 to 1. It will prompt for a password, just hit Ok for a blank one. - Optionally, make VNC auto-start on boot, add to rc.local
something like this:
su joey -c 'cd; tightvncserver -interface 127.0.0.1 -geometry 320x320'
TODO:
- Need way to send arrow keys!
- xmonad configuration
Update: Here's another screenshot, of FBReader on the Pre. One of the missing apps on the Pre is a good offline e-book reader with no vendor lock-in. FBReader is what I use on my laptop, so it's great to have it on my phone. Especially since I have room for my entire e-book library on the Pre's generous flash drive.
Previously: Palm Pre, ssh to Debian chroot on Palm Pre
Following setting up a Debian chroot on the Pre, I wanted to be able to ssh into the chroot. This sets that up, including starting Debian's ssh on boot.
Actually, I went a step further and hooked Debian's
rc3.d
init scripts into the Pre's webOS boot process,
so all services installed in Debian will start on boot.
So as a bonus, cron, at, etc will also work.
Since the Pre's EVDO IP address changes all the time, dynamic DNS is needed if you want to ssh in over EVDO. I used ez-ipupdate to handle that. (If you didn't want to ssh via EVDO, you could omit that part, and add "-i eth0" to both the firewall rules below.)
- Use
novacom
and the cable to get a root shell, andchroot /media/debian
- Install ssh:
apt-get install openssh-server openssh-client
- Hook Debian init scripts into webOS startup:
cat > /media/pre-root/etc/event.d/debian_start <<EOF # start Debian services after webOS boot is complete to avoid delaying that start on stopped finish script echo "Starting Debian services..." chroot /media/debian /etc/init.d/rc 2 end script EOF
- Edit
/etc/rc.local
and add these commands to it:# Add firewall rule to allow SSH access on port 22, # both wifi and EVDO. iptables -D INPUT -p tcp --dport 22 -j ACCEPT || true iptables -I INPUT -p tcp --dport 22 -j ACCEPT
- If you want to easily be able to determine the phone's address
while it's on wifi, you can use mDNS (hostname.local):
apt-get install avahi-daemon
- Install ez-ipupdate:
apt-get ez-ipupdate
- Follow the prompts to configure ez-ipupdate to use dyndns or your preferred dyanmic DNS service. When it asks if ppp is used, say yes.
- Edit
/etc/ez-ipupdate/default.conf
and make sure the interface is set to 'ppp0' (See Debian bug #536512 for why you need to do this currently.) - Hook ez-ipupdate into webOS's ip-up script, so it is run
whenever the address changes:
HOOK=/media/pre-root/etc/ppp/ip-up.d/09ez-ipupdate-debian echo '#!/bin/sh' > $HOOK echo '/usr/sbin/chroot /media/debian /etc/ppp/ip-up.d/ez-ipupdate >/dev/null 2>&1 || true' >> $HOOK chmod a+x $HOOK
- Reboot the Pre. Now is a good time to learn that Orange+Sym+R on the keypad is equivilant to ctrl-alt-del. :-) The ssh daemon should be started automatically.
TODO:
- Enable avahi for mdns for wifi.
- Cleanly stop Debian services on shutdown. Problem with doing this is that I can't just run '/etc/init.d/rc 0', because that will kill every process in webOS too, and hang the phone. It'd need a very custom runlevel to be set up in Debian.
I got a Palm Pre because I want a Linux smartphone that is not locked down (like the G1), on which I can play with Debian and even my own kernel. But I also want one that seems likely to be widely viable going forward, and there I have my doubts about OpenMoko, sadly.
(Or, I got a Palm Pre because I dreamt last night that I got one, and decided my subconcious must have made a decision after dithering for years. And because Madduck rules.)
Debian chroot on Palm Pre
This is a quick installation of a Debian chroot on the Palm Pre phone. Similar methods are explained at the Pre Dev Wiki. But they have you download a prebuilt Debian image and modify the Palm webOS system to install ssh; I preferred to use debootstrap and keep webOS changes to a minimum.
Also, since the Pre uses LVM, its media partition can be resized on the fly. That allows for a larger Debian filesystem, and I think is a nicer method than the loopback filesystem approach documented elsewhere, but do read the warnings about Palm, LVM, and upgrades here.
On the Pre:
- Enable dev mode
by opening the Pre's Launcher and typing the following into it:
upupdowndownleftrightleftrightbastart
- Plug the Pre into your laptop, tell it to charge via USB, while doing the following on the laptop.
On a Linux laptop:
- Run debootstrap to build an armel chroot:
sudo debootstrap --foreign --arch=armel sid /tmp/debian
- Download novacom,
cd
to it, and build it:sudo apt-get install libusb-dev; make
- Transfer the armel chroot from the laptop to the Pre:
(cd /tmp; sudo tar czv debian) | sudo ./novacom put file:///tmp/debian.tar.gz
- Run
sudo ./novacom
to get root shell on the Pre. - In that shell, use LVM to resize the existing /media/internal volume
down to 1 GB, and create a new 6 GB one for Debian:
cp -a /media/internal /opt umount /media/internal lvresize -L 1G /dev/mapper/store-media mkdosfs -F 32 /dev/mapper/store-media mount /media/internal mv /opt/internal/ /opt/internal/. /media/internal rmdir /opt/internal lvcreate -l 100%FREE -n debian store mkfs.ext3 /dev/store/debian mkdir /media/debian echo "/dev/mapper/store-debian /media/debian auto noatime 0 0" >> /etc/fstab mount /media/debian
- Then in the Pre's root shell, you can unpack Debian, set up some bind
mounts to allow accessing the Pre's filesystems from inside Debian, and
chroot in to finish debootstrap:
cd /media tar zxvf /tmp/debian.tar.gz mkdir /media/debian/media/pre-root /media/debian/media/internal echo "/ /media/debian/media/pre-root bind defaults,bind 0 0" >> /etc/fstab echo "/var /media/debian/media/pre-root/var bind defaults,bind 0 0" >> /etc/fstab echo "/var/log /media/debian/media/pre-root/var/log bind defaults,bind 0 0" >> /etc/fstab echo "/tmp /media/debian/tmp bind defaults,bind 0 0" >> /etc/fstab echo "/proc /media/debian/proc bind defaults,bind 0 0" >> /etc/fstab echo "/dev /media/debian/dev bind defaults,bind 0 0" >> /etc/fstab echo "/dev/pts /media/debian/dev/pts bind defaults,bind 0 0" >> /etc/fstab echo "/sys /media/debian/sys bind defaults,bind 0 0" >> /etc/fstab echo "/media/internal /media/debian/media/internal bind defaults,bind 0 0" >> /etc/fstab mount -a chroot debian /debootstrap/debootstrap --second-stage ln -sf /proc/mounts /etc/mtab ln -sf /media/pre-root/etc/resolv.conf /etc/resolv.conf apt-get clean
- Now customise the Debian chroot as usual.
How this could be made easier:
- Make a debian package of novacom.
- Installation script? debcoexist? d-i?
TODO:
- Install openssh in Debian and configure it to start at boot.
- Set up VNC, install VNC app in webOS to allow accessing a Debian desktop.
Last time I created a code_swarm
video, I forgot to document
the whole video editing process. Let's try to record the key
stuff this time.
- Run
code_swarm
(see its docs). Note that its output is best if run on a display without subpixel rendering -- so desktop, not laptop. - Now to convert the frames into a dv video. (There is a small quality loss
here.)
ffmpeg -f image2 -r 24 -i ./frames/code_swarm-%05d.png -s ntsc out.dv
- Import video into kino.
- Edit video in kino.
- Sound. Needs to be in wav format. Use effects, and Dub sound in to video.
- Final encoding. Kino's exporters are not very reliable; I have it export to a raw dv, and then use xvidenc (packaged in debian-multimedia) for the encoding.
I have finally figured out how to make clicking on a mp3 link in firefox cause the url to be instantly passed to mpd and played. If this seems like it should be easy, think again..
Firefox makes it hard, because while it lets you configure an program to run for a mp3, if the mp3 is not streamed, it will first download the whole mp3, and then run your program, passing it the local file. That's not what we want: It's slow, and it's much easier to queue an url in mpd than a new file.
The trick to making it work is an addon called MediaPlayerConnectivity. Confusingly, this addon sometimes refers to itself as "MPC" -- not to be confused with "mpc(1)". Warning: This addon is a ugly mess that wants to do a lot of other stuff than play mp3s, so make sure to disable all that.
MediaPlayerConnectivity's preferences allows you to specify a command to run for mp3 files (but annoyingly, not ogg vorbis). This command will be passed the url to the mp3. So you need to write a little script that runs mpc add and starts the queued url playing.
My take on that is mpqueue,
which uses the mpinsert
command from mpdtoys to add the url just
after the currently playing song in the playlist.
Then it uses mpc next
to skip to it. This way, after whatever you clicked
on finishes playing, mpd continues with whatever was next in your playlist,
and the music never stops.
BTW, since I use a mpd proxy this is all done on whatever remote mpd the proxy is currently set to use, rather than my laptop. Clicking on a link and having the sound system in the next room switch to playing it is pretty nice. :)
Previously: My mpd setup
I've used unison for a long while for keeping things like my music in sync between machines. But it's never felt entirely safe, or right. (Or fast!) Using a VCS would be better, but would consume a lot more space.
Well, space still matters on laptops, with their smallish SSDs, but I have terabytes of disk on my file servers, so VCS space overhead there is no longer of much concern for files smaller than videos. So, here's a way I've been experimenting with to get rid of unison in this situation.
Set up some sort of networked filesystem connection to the file server. I hate to admit I'm still using NFS.
Log into the file server, init a git repo, and check all your music (or whatever) into it.
When checking out on each client, use
git clone --shared
. This avoids including any objects in the client's local.git
directory.
git clone --shared /mnt/fileserver/stuff.git stuff
- Now you can just use git as usual, to add/remove stuff, commit, update, etc.
Caveats:
git add
is not very fast. Reading, checksumming, and writing out gig after gig of data can be slow. Think hours. Maybe days. (OTOH, I ran that on an Thecus.)- Overall, I'm happy with the speed, after the initial setup. Git pushes data around faster than unison, despite not really being intended to be used this way.
- Note that use of
git clone --shared
, and read the caveats about this mode ingit-clone(1)
. git repack
is not recommended on clients because it would read and write the whole git repo over NFS.- Make sure your NFS server has large file support. (The userspace one doesn't; kernel one does.) You don't just need it for enormous pack files. The failure mode I saw was git failing in amusing ways that involved creating empty files.
- Git doesn't deal very well with a bit flipping somewhere
in the middle of a 32 gigabyte pack file. And since this
method avoids duplicating the data in
.git
, the clones are not available as backups if something goes wrong. So if regenerating your entire repo doesn't appeal, keep a backup of it.
(Thanks to Ted T'so for the hint about using --shared, which makes this work significantly better, and simpler.)
The way .ssh/authorized_keys
is typically used is not secure. Because
using it securely is hard, and dumping in passwordless ssh keys is easy. I
spent about 5 hours today locking down my authorized_keys
.
rsync
The only easy case is a rsync of a single directory. Follow these good instructions.
If you need to rsync multiple separate directories, it's easy to find
several
documents involving a
validate-rsync.sh
. Do not use, it is insecure -- it allows rsync to be
run with any parameters. Including parameters that allow the remote system
to rsync in a new ~/.ssh/authorized_keys
. Oops. (You can probably also
trick validate-rsync.sh
into running other arbitrary commands.) To be
secure, you have to check the rsync parameters against some form of
whitelist.
git
Locking down git should be easy. Use git-shell
.
Unless you also want to be able to log in to an interactive shell on the
same account. To do that, you'll need to generate a separate ssh key for
git. Both git servers I use are named git.*
, so I set it up like this in
~/.ssh/config
on the client:
Host git.*
IdentityFile ~/.ssh/id_rsa.git
Then on the server, I added the key to authorized_keys
, prefixed with this:
command="perl -e 'exec qw(git-shell -c), $ENV{SSH_ORIGINAL_COMMAND}'"
(I also tried the simpler command="git-shell -c $SSH_ORIGINAL_COMMAND"
; but
it didn't work with alioth's old version of openssh, and I didn't want
to worry about exposing SSH_ORIGINAL_COMMAND to the shell.)
Before arriving at that, I took a detour to using gitosis. It can make it impressively easy to manage locked down git over ssh, but you have to fit how it does things. Including repository layout, and a dedicated account. So I spent several hours changing my git repo layout. In the end, I decided gitosis was too complicated and limiting for what I needed, but I do recommend checking it out.
svn
Like git, this is fairly easy, since svn provides svnserve
. The svnbook
documents how to use it in .authroized_keys. Basically, just use
command="svnserve -t"
A similar approach as used for git can be used here if you want to have a dedicated ssh key that causes svnserve to be run.
d-i daily builds
d-i has a d-i-unpack-helper
that can be put in authorized_keys.
unison
Can probably be locked down similarly to rsync, but I haven't tried yet.
duplicity
The only way seems to not use duplicity over ssh at all, and instead use a different transport.
too hard
What if you want to allow locked down git, and a rsync, and maybe unison too, all to the same account? You'll end up with some nasty mismash of all of the above, and there are plenty more things using ssh as a transport that need other techniques to lock them down.
Until this becomes easier, a majority will just dump passwordless ssh keys
in ~/.ssh/authorized_keys
, creating exploitable trust paths that don't
need to exist.