Android and Linux

Sunday, January 22, 2012

ssh problem with Locale Execute Plugin

I recently found ssh commands to be flaky when running them with the Locale Execute Plugin for Tasker. A check of the log showed a couple interesting lines:

D/LocaleExecute( 7130): stderr: ssh: Warning: Reading the random source seems to have blocked.
D/LocaleExecute( 7130): stderr: If you experience problems, you probably need to find a better entropy source.

/dev/random is a random number generator that keeps a pool of random bits for use in cryptography, but it uses computer activity to generate them and if the computer isn't active enough, it will block the sending of random bits until it gets some more.

/dev/urandom is more foolproof in operation because, when it runs out of random bits from computer activity, it generates some more on it's own, but if an attacker knew the algorithms used by urandom, they could in theory use that to hack anything replying on urandom as an entropy source. But as the man pages say "Knowledge of how to do this is not available in the current unclassified literature, but it is theoretically possible that such an attack may exist. If this is a concern in your application, use /dev/random instead."

Unless you think the NSA is trying to crask the ssh link between your phone and computer, it should be safe to link /dev/random to /dev/urandom.

cd /dev
mv random random.bak
ln -s urandom random


I don't know why this problem only manifested itself when ssh was ran with the Locale Execute Plugin. I assume when ran from a terminal, the terminal app was creating enough noise for the kernel to keep the entropy pool filled or something.

Thursday, January 19, 2012

Pulling Sender and Subject from Gmail part 2

I'm not a database guy. I've used sqlite3 several times on Android to pull information out of db files, but I usually just dump everything and filter it with tools I'm familiar with and never sat down and tried to learn much about it until tonight. What I learned was just enough basics to make a database admin say "Aww, that's cute... he's twying to wearn something" but it's already useful.

My problem was that I had never actually viewed a db file before. I had dumped them and looked at the output and wondered why there was no way to identify and extract a certain column. It wasn't until I actually tapped on a file and opened it to see that the columns were indeed named and sought out a way to utilize that.

It's actually so simple I could kick myself for not looking sooner. I was toying with pulling data from the gmail file again and found that you can pull data from other columns and limit the output to only show one record (like head -1), but that gives you the oldest record at the top of the file. Turns out, the first column in the gmail file it named _id and it's just line numbers, and you can sort the output by the _id column in reverse order and grab that top line to get the newest. It's as simple as "ORDER BY _id DESC LIMIT 1"

Anyway, I came up with a cleaner way to grab the sender, sender's email address and the subject from the most recent email, or all three together like I had previously posted. This script will do all four.

Here is what it looks like. I just signed up for an account at RootzWiki, so that's my most recent email.
# mailsender email
staff@rootzwiki.com
# mailsender name
RootzWiki
# mailsender subject
New Registration at RootzWiki
# mailsender
"RootzWiki" <staff@rootzwiki.com> New Registration at RootzWiki
#
Using this, it's easy to trigger a Tasker action based on any of those criteria.

First you set up an event profile based on a ui notification owned by gmail, and use it to trigger a task like this:

1- using the Locale Execute Plugin, execute one of the commands and redirect it to a file
2- wait 1 second (usually a good idea with commands like this)
3- read line 1 from the output file to %var
4- Do something if %var matches whatever

The email address is probably the best thing to match, but you could also use it to for a name or a certain subject, just adjust the command accordingly.

All you need to do is replace YOURNAME with your google login name on the second like because the database file is named after your gmail name.
#! /system/bin/sh

yourmail="YOURNAME@gmail.com"

dir="/data/data/com.google.android.gm/databases/"
case "$1" in

name)
sqlite3 ${dir}mailstore.${yourmail}.db "select fromAddress from messages ORDER BY _id DESC LIMIT 1" | grep -o '"[^"]*"' | tr -d \";;

email)
sqlite3 ${dir}mailstore.${yourmail}.db "select fromAddress from messages ORDER BY _id DESC LIMIT 1" | grep -o \<.*\> | tr -d '<>';;

subject)
sqlite3 ${dir}mailstore.${yourmail}.db "select subject from messages ORDER BY _id DESC LIMIT 1";;

*)
sqlite3 ${dir}mailstore.${yourmail}.db "select * from messages ORDER BY _id DESC LIMIT 1" | awk '/@/{FS="|";print $4,$11}';;

esac
If you want to play around, you can also extract a preview to the email, or even the entire body with these sqlite3 commands:

"select snippet from messages"
"select body from messages"

I think I'm done playing with it, but your gmail messages are completely accessible from the command line on Android. Might be useful for something.

Edit: Jan 20. Here's a QR code to copy the script to your phone's clipboard.

Wednesday, January 18, 2012

Screenshot command

This command will take a screenshot on Android ICS:

/system/bin/screencap -p /sdcard/FILENAME.png

You might want to make the filename be the date and time:

/sdcard/$(date +%m.%d.%Y-%H:%M).png

I found that in /system/bin/bugmailer.sh, a script to send bug reports. The p option and calling it a png file both seem to have the same result, but if you leave both off, it ends up as a data file that nothing will open. It seems redundant but for safety's sake, I'll follow their example of both using -p and naming it a png. Unfortunately, there are no other options.

It's a neat trick. With Tasker, I can trigger a screenshot and scp that sucker right to my computer automatically.

Tuesday, January 17, 2012

Pulling sender and subject from Gmail

This came up on the Tasker group today. Someone wanted a way to get the sender and/or subject from Gmail to have Tasker keep beeping until they read an email from an important person. Or something like that.

The Android Gmail client doesn't have an API to allow you to get any information about a new email. But we're root and we don't care about that API business.

In the directory /data/data/com.google.android.gm/databases is a file named mailstore.YOURNAME@gmail.com.db. Breaking out the trusty sqlite3, we find that the sender and subject is contained in the 4th and 11th fields of the messages table and we can extract that by dumping the table...
sqlite3 mailstore.YOURNAME@gmail.com.db "select * from messages"
...and filtering it with awk.
awk '/@/{FS="|";print $4,$11}' | tail -n1
The last line seems to be the most recent email. For some reason I can't get awk to grab the last line on my phone, so I had to use tail.

That is what I posted on the Tasker group but that was a test and it needs tweaked. It is essentially grepping all the lines containing "@" then printing the 4th and 11th fields. I tried that first because you can get some gibberish in those messages, and I wanted to grab the lines with email addresses and that was a quick way, but the receiver's (your) email address is on the same line as the information we want so it would be a lot safer to grab lines containing your email address instead of the general "@" symbol.
awk '/YOURNAME@gmail.com/{FS="|";print $4,$11}' | tail -n1
The end result is something like "John" <john_doe@isp.net> Re: blah blah

Instead of posting a huge long line that makes my blog look funny, I'll put it all together like this:
#! /system/bin/sh
email=YOURNAME@gmail.com
file=/data/data/com.google.android.gm/databases/mailstore.${email}.db
sqlite3 ${file} "select * from messages" | awk '/@/{FS="|";print $4,$11}' | tail -n1
I didn't actually test it, but Tasker can listen for notifications which belong to any apps including Gmail. You can have a profile that watches for Gmail notifications, then executes that script and sends the output to a file, then reads the line from the file into a variable, and acts on it accordingly. You could have it read the sender's name to you, remind you to read the email if it's someone important, or whatever.

Saturday, January 7, 2012

ssh on ICS

Since getting the Galaxy Nexus, I've been unable to use ssh until now. The problem was something with the router. Everything was set up properly, all my other computers can ssh to each other, and I could ssh from outside my network, but once connected to wifi, I couldn't ssh from the computer to the phone or from the phone to the computer. I finally solved it by buying a new router.

There is still one oddity though. When connected to wifi, the phone will not ssh to the external IP address of anything on the network. What I mean is that if my computer's assigned IP address is 192.168.1.5 and ssh is running on port 1234 and the external IP address is 123.45.54.321, I should be able to connect to 123.45.54.321 port 1234. I always use that since it's the same address I would use if I were trying to connect remotely. But for some reason it won't work.

Luckily Tasker provides an easy fix. I set up a profile to write "connected" to /sdcard/Tasker/wifi when connected to my wifi and write "disco" when disconnected. Since I already had to write a script to connect to multiple ssh servers, I can read that file and see if I'm on wifi and use the proper IP.

#! /system/bin/sh

if grep -q connected /sdcard/Tasker/wifi
then
comp1ip=192.168.1.9
comp2ip=192.168.1.5
else
comp1ip=$(hip)
comp2ip=$(hip)
fi

case "$1" in

comp1)
echo "$comp1ip ssh-rsa AAA==" > /data/data/com.magicandroidapps.bettertermpro/home/.ssh/known_hosts

ssh USER@$comp1ip -i PATH/TO/KEYFILE -p PORT;;

comp2)
echo "$comp2ip ssh-rsa BBB==" > /data/data/com.magicandroidapps.bettertermpro/home/.ssh/known_hosts

ssh USER@$(hip) -i PATH/TO/KEYFILE -p PORT;;

esac


There's also another improvement that can be made to that script by changing the section for each computer.

comp1)
echo "$comp1ip ssh-rsa AAA==" > /data/data/com.magicandroidapps.bettertermpro/home/.ssh/known_hosts

if [ -z "$2" ]
then
ssh USER@$(hip) -i PATH/TO/KEYFILE -p PORT
else
shift; ssh USER@$(hip) -i PATH/TO/KEYFILE -p PORT "$*"
fi
;;


What this does is check for arguments to the script. If there are none, it will connect normally. If there are arguments, it will run them as commands on the remote computer.

So, the command s comp1 would login to computer 1, but s comp1 cd ~foo && touch bar will run the command on computer 1 to cd to the foo directory and create the file bar.

That makes it a lot simpler to bounce commands off the remote computer.

Wednesday, December 21, 2011

Woe is me...

Since getting the Galaxy Nexus, I've had a little trouble and have been flashing ROMs like crazy and spending enough time in recovery that I could have put Betty Ford's kids through college. Wait... I'm not sure that made sense.

Anyway, I assumed the problems were from hacks being rushed to the public with little testing, but I think I actually got a lemon and am going to swap it for a new one.

To begin with, I kept losing root after an hour or two for some unknown reason. I noticed that the file manager I was using was registering battery usage almost as high as the display after one such unrooting, so I stopped using it. That helped me get through a day or two with root intact, but I'm not entirely sure that was the problem because I was working in the terminal last night and lost root again.

I've also had random shutdowns and really bad slowdowns, and I've spend a couple of days trying, and failing, to get ssh to work. Oddly, I can ssh from the phone to my computer from anywhere on the cell network, but it simply will not work when connected to my router.

On the router, I had assigned the phone a certain IP address but it seemed to connect at a different one for the past few days. I kept setting it, thinking maybe I had kept forgetting to hit "apply" or something, until I finally realized tonight that I had set it yesterday for a different MAC address.

A little investigation revealed that my phone's MAC address changes on every boot. Oops, MAC addresses aren't supposed to do that! It's a pretty neat trick but not only troublesome for IP reservation, but could be causing a lot of other problems as well.

I found someone else on XDA who had the same problem and Samsung said it was a hardware problem and swapped it for him. Verizon's phone number is right there on the charger and I didn't know Samsung's so I called the big V and they were a little puzzled. They called Samsung and they were puzzled too, but the Verizon guy told me to swap it.

I'm going to swap it at the store tomorrow so I don't have to wait for one to be shipped.

It nearly brought a tear to my eye, but I just typed "fastboot oem lock" in a terminal and brought my phone back to stock. But hopefully I'll be ready to start playing with the GNex for real after tomorrow.

Sunday, December 18, 2011

Galaxy Nexus

I finally got a Galaxy Nexus. I went Thursday at 11:15, walked in and told them I wanted a Galaxy Nexus and they said "We don't have them yet. They're coming in via UPS today. We're getting 8 of them and can save one for you if you want."

Yes, I live in a small town.

I didn't get around to buying one until yesterday afternoon. Since I enjoy voiding warranties within an hour of purchase, I promptly rooted it but didn't have time to do much else. Last night, I was a little upset because I kept losing root. I still don't know what the problem was, I'd flash the recovery and su binary and I would be doing something as root in a terminal when suddenly it would tell me "only root can do that" and I could no longer su. The root checker app said I had root, and the superuser app showed that certain apps were allowed and logged them as allowed when I opened them, but they still reported that they couldn't gain root.

It kept losing root after numerous flashes and rootings until I flashed this ROM this morning, and that seems to have cleared it up.

Anyway, my impressions on the Galaxy Nexus...

This puppy is huge! I'm charging the battery on my digital camera to try to get some comparisons of the Nexus One and Galaxy Nexus, but if you want a good idea of the size, it's almost the exact same size as a dollar bill, except a little shorter.

You ever go to a cell phone store and look at the flip phones and think "awww, such cute little screens, but I don't know how you could get anything done on that tiny little window." I felt that way when picking up the N1 after 20 minutes with the GNex.

The N1 had a habit of turning in my pocket, the GNex stands tall and it's thinner, so although it's much larger, it rides in my pocket better than the N1.

There are some things I don't really like.

The phone has very few features and it's easy to pull it out of your pocket and try to use it upside down. The earplug is on the bottom, which may or may not be a good thing, I'm not really sure yet.

The battery cover is a cheap piece of plastic that snaps in place instead of sliding. It's not what I would have designed, but it does raise the possibility of easy replacement, so there may be some cool looking battery covers showing up soon.

There are no hardware buttons for "back" "menu" "home" and "search", instead there are software buttons for "back" "home" and "recent apps". Three small dots are used for settings, and they may be at the top or the bottom of an app. I miss being able to always find them in one place.

And no trackball. Oh, how I miss that, but no other phones have them either. I've really been dreading the loss of the trackball, but I'll have to adapt.

With the launcher, you can't add widgets by long pressing the home screen, you have to do it from the app drawer. The app drawer has tabs for apps and widgets, and everything side scrolls now, which takes some getting used to.

LauncherPro still works, so that gives you the old school feel with long press widget adds etc, but it hasn't had an update in forever so it will surely stop working one of these days and old fogies like me will be dragged kicking and screaming into the future.

I really do love the phone. My gosh, when I pull that thing out it feels like I'm using a tablet. I have a lot of setup to do to get things working the way I want, so that means a lot of playing with this cool phone!

Followers