Saturday, June 20, 2009

QualNet (Scalable Networks Technologies) Website and Issues

I had a number of issues with the QualNet website, which ended up resulting in this email dated June 3rd to license@scalable-networks.com and
evals@scalable-networks.com:

Dear Scalable Networks,

I recently signed up for a 30 day evaluation of QualNet. When I log in I get a welcome message that states the following:

"Thank you for evaluating QualNet. Your 30-day Evaluation License File has been generated and posted to your download page."

However, when I go to the download page and click the link to the license file (http://www.scalable-networks.com/distributions/download/license/evals/qualnet-4.5.1-eval-2009.07.03.lic) I am immediately redirected to the sitemap (http://www.scalable-networks.com/sitemap.php). Since I am on Linux/Firefox and was having other issues with your site (such as broken CSS suckerfish dropdown menus), I decided to try logging in on a Windows PC.

This attempt was even more broken/disturbing, [since] as soon as I logged in I received a non-html page that stated:

INSERT INTO ErrorLog (UID, address, SID, error, login, password) VALUES ('', '#.#.#.#', 'nodnhkck0rlkh0qc2442skijh5', 'Password is not correct', 'my@email.com', 'MyPassword'')

Subsequent attempts to log in on the Windows machine do not even take me to the login page, they simply show this SQL query. I initial[ly] thought my password was correct, however if you look closely there is an extra single quote at the end of it, which I must have hit while submitting the form with the enter key. I had to clear my cookies in order to be able to log in correctly. Unfortunately the license file link was still broken (as were the dropdown menus).

In summary:

1. Your CSS suckerfish dropdown menus have extra pixels [between] them and the popup which causes them to break in Linux and Windows Firefox.
2. You are likely not sanitizing your user input before inserting it in to your SQL database, which is a huge security hole.
3. You are storing your passwords in plain-text which is a very, very, bad practice. A simple SQL injection could potentially reveal every stored password.
4. You are sending passwords in plain-text over email which is not necessarily encrypted; this is also a very bad security practice.
5. And most importantly, I still cannot download my evaluation license file. Please let me know what I need to do to get this.


Thank You,

Clayton Shepard



P.S. http://xkcd.com/327/

(I apologize for the typos, noted in brackets. Clearly I removed my plaintext password, IP, and email.)


I guess I just find it ironic, and somewhat amusing, that a technology oriented company has such glaring flaws with their website and security. In their defense they very promptly replied with the license file. Also, the SQL table was just the "ErrorLog", which means they could still be using a hash for the actual passwords somewhere else; arguably this is still a security threat though, since mistyped passwords are likely very close to the original. For obvious reasons I did not try a SQL injection attack, so I can not verify whether or not that is actually a security hole (although my guess is that it is).


On entirely different note, I was unable to get QualNet 4.5 running on Ubuntu 9.04 AMD64 because of library issues. In short they require gcc 4.0 and glibc2.3 or earlier to compile/install. Getting glibc2.3 to run on 9.04 is a huge pain. When asked, their official tech support reply is to use Ubuntu 6.06 :(. Unfortunate.


This reminds of the MSDNAA (MSDN Academic Alliance) website which also sends plaintext passwords in emails. Sigh.

Wednesday, June 17, 2009

Showing scp's Progress Using zenity (pseudo terminal example)

I recently discovered zenity for making quick, straightforward, graphical interfaces for shell scripts. One such script I wrote uses scp for backups. Since scp prints its percentage progress to stdout I figured it would be pretty easy to simply use a regex to parse the output and pipe it to zenity. I guessed this venture would take about ten minutes (I am not very experienced with regex), since zenity --progress just expects a number printed to its stdin in order to update the progress bar. I couldn't have been more mistaken; after four hours of hacking and wtfs I gave up. Finally, after a discussion with my old operating systems professor and a little bit of coding I finally have a solution.

After piping scp's output to various c and perl programs I determined that the problem was probably a terminal mode problem. A standard (canonical) terminal sends input to the program as lines, thus if there are never any new lines (such as in scp's output) the program would never receive the data. After figuring out how to put c (and perl) in to raw mode, as well as playing with stty, I managed to get a couple programs working that could read input before a newline was sent. I tested these with stdin and pipes and they seemed to work fine, but they still wouldn't work with scp. After a bit of debugging I figured out that when the data was piped to my c program I couldn't put the terminal in to raw mode. Go figure, when you pipe data to a program it doesn't use a terminal... it uses a pipe (duh!). This is the point where I gave up, as I didn't really feel like digging through the scp source code, and I certainly didn't want to run a modified copy of scp (that would kind of defeat the whole purpose).

After discussing the problem with an old professor he hypothesized that scp was checking if it was being run on a terminal, and if it wasn't then it was disabling output. Sure enough, on line 396 of scp.c:

if (!isatty(STDOUT_FILENO))
showprogress = 0;


As a possible solution he mentioned pseudo terminals. Apparently back in the old days psuedo terminals were quite a pain since you had to find a free one manually before you could use it. Luckily linux provides a convenient function, forkpty(), that finds a free pseudo terminal, forks a new process, and attaches the new process to the terminal. Sweet. Now with some simple fileio it works fine:


#include <unistd.h>
#include <sys/types.h>
#include <stdio.h>

main(int argc, char **argv) {
int fd;
pid_t pid;
char c,c1,c2;

if (argc != 3) {
printf("usage: [[user@]host1:]file1 [[user@]host2:]file2\n\nThis is a program that wraps scp and prints out the numeric progress on separate lines.\n");
fflush(stdout);
_exit(1);
}

pid = forkpty (&fd, NULL, NULL, NULL);
if (pid == 0) {
execlp ("scp", "scp", argv[1], argv[2], (char *) NULL);
_exit (1);
} else if (pid == -1) {
return 1;
} else {
FILE *F;

F = fdopen (fd, "r");

//reading character by character isn't horribly efficient...
while((c = fgetc(F)) != -1) {
if (c == '%') {
if (c1 == ' ')
printf("%c\n", c2); //one digit progess
else if (c1 == '0' && c2 == '0')
printf("100\n"); //done
else
printf("%c%c\n", c1,c2); //two digit progress
}
fflush(stdout);
c1 = c2;
c2 = c;
}

fflush (F);
wait (0);
}
return 0;
}


Notably, I went ahead and parsed the scp output in c. It seemed to be a cleaner solution than piping this output to a perl script and then to zenity. I initially missed the fflush() in the while loop, which took me a while to figure out :/.

To compile it you need to use the -lutil switch. So first copy and paste this c program in to scpwrap.c. Then run "gcc -lutil scpwrap.c -oscpwrap". Before you can use it you have to get rid of scp's authentication prompt by setting up some authentication keys:


ssh-keygen -t rsa
cat .ssh/id_rsa.pub | ssh user@example.com 'cat >> .ssh/authorized_keys'


Now to use the wrapper you can do something like:


./scpwrap /home/ubuntu/somefile user@example.com:~ | zenity --progress


Of course you can add whatever zenity switches you want. You cannot, however, add any scp switches without modifying the c program... Sorry.

---------------------Notes and Sources---------------------------

Terminal raw mode "stty raw".

Perl expression to parse the scp output:
perl -015 -l -ne 'print /(\d+)%/'
Notice the "-015" that tells it to use carriage returns as the line delimiter. Pretty cool, it probably would have worked if scp wasn't checking if it was running on a terminal.

Perl code to put terminal in to raw mode:

#!/usr/bin/perl

use Term::ReadKey;

ReadMode 5; # Turn off controls keys
while (($key=getc) ) {
print "$key\n";
last if $key eq "q";
};
print "Get key $key\n";
ReadMode 0; # Reset tty mode before exiting


C code to put terminal in to raw mode.

Zenity Progress Example 1:

(for a in `seq 1 100` ;


do
echo $a;
sleep 0.03;


done) | zenity --auto-close --progress \


--text="Slow counting from 1 to 100" \
--title="Example Progress"


Zenity Progress Example 2:

#!/bin/sh
(
echo "10" ; sleep 1
echo "# Updating mail logs" ; sleep 1
echo "20" ; sleep 1
echo "# Resetting cron jobs" ; sleep 1
echo "50" ; sleep 1
echo "This line will just be ignored" ; sleep 1
echo "75" ; sleep 1
echo "# Rebooting system" ; sleep 1
echo "100" ; sleep 1
) |
zenity --progress \
--title="Update System Logs" \
--text="Scanning mail logs..." \
--percentage=0

if [ "$?" = -1 ] ; then
zenity --error \
--text="Update canceled."
fi


Update: I modified the scp source (openssh5.2p1) to include a '-n' switch to print out the progress meter on new lines, regardless of whether stdout is a tty. I proposed this new feature to the openssh-unix-dev listserv, but I doubt they will adopt it. The email thread and patch can be found in their archives.

Update 2: Hrm, the pseudo terminal hack doesn't work if you run it from a launcher (kind of the whole point).