20090607

Dealing with rkhunter warnings

rkhunter often warns on file property changes after upgrade and such, and sometimes you just aren't sure whether it is due to recent upgrades, or because you really were compromised. The following script was written to compare the checksum of all files rkhunter warns about against the originals in a debian repository.

Naturally you should run this on a machine which is working off the same repository, and is at the same versions. Alternatively, separate the script into 2 parts: first part dumps the require aptitude arguments, second part does the checking. Run the first on the suspect machine, second on a machine known to be good.

#!/bin/bash
desc="
This script will verify whether files for which rkhunter has logged a 
warning for is still valid. It does this by finding which debian package
it came out of, and downloads them, unpacks them, then checks
the checksums.

Run it by supplying a rkhunter log file as first argument
"

# this script should not be ran on a suspect machine, but on a machine
# running the same distribution

IFS="
"
function find_suspect_files
{
 grep -1 Warning "$1"| grep File | awk '{print $2}'
}

function find_packages
{
 for suspect_file in $1
 do
  package=$(dpkg -S $suspect_file|awk '{print $1}'|sed 's/.$//')
  echo $package 
 done

}

function make_aptitude_args
{
 for package in $1
 do
  version=$(dpkg -p $package | grep Version | awk '{print $2}')
  echo $package=$version
 done
}

function cleanup
{
 popd
 rm -rf tmp
}

function setup
{
 rm -rf tmp
 mkdir tmp
 pushd tmp
}

if [ $# -ne 1 ];
then
 echo "$desc"
 exit 1
fi

suspect_files=$(find_suspect_files "$1")
packages=$(find_packages "$suspect_files" | sort | uniq)
aptitude_args=$(make_aptitude_args "$packages")

setup

aptitude download $aptitude_args

for deb_file in *.deb
do
 ar -x $deb_file
 tar zxf data.tar.gz 
 rm -rf data.tar.gz control.tar.gz
done

for suspect_file in $suspect_files
do
 suspect_sum=$(sha256sum $suspect_file | awk '{print $1}')
 clean_sum=$(sha256sum ".$suspect_file" | awk '{print $1}')
 if [ $suspect_sum == $clean_sum ];
 then
  echo "$suspect_file: OK"
 else
  echo "***WARNING****"
  echo "Checksum mistmatch for $suspect_file!!!"
  echo "Should be: $clean_sum"
  echo "Is: $suspect_sum"
 fi
done
cleanup

Cheers,
Steve

Labels: , ,


20090604

microbric viper review

The microbric viper is neat. Good quality parts and unique idea. Makes a decent robotics platform if you get the wheel add-on. However, you gotta have small fingers to get some of the parts in place. Despite this, the hardware is solid, I like it. The one thing I would ask for however is more short-nuts and a printed manual, not a CDROM with a PDF. Take a leaf from LEGO and their construction manuals.

While the hardware is decent, the microbric viper is sadly let down by the software.

The microbric viper uses the basicAtom (by basicmicro), a PIC 16F87{6,7} with a custom bootloader. Now there is nothing wrong with this - arduino uses a custom bootloader too. However the custom bootloader uses a proprietary programming protocol. This is pretty fail, but what really fails is the programming software only runs under windows (or wine under ubuntu, but only for now).

IMHO the basic-esque language used by basicAtom is no better than what picaxe offers. I am completely at a lost as to why companies would use the basicmicro's products and lock themselves to a single supplier. Think about it: if basicmicro goes bust, your products using the basicAtom will not longer have a supported development environment.

Robotics companies need to seriously consider how their selection of controller will affect their customers - specifically those customers who aren't going to be running windows and staying with in the limits of whatever custom language designed by the controller vendors.

Arduino would be the best choice IMHO. Open hardware, open software. You don't have to pay premiums for the bootloader, and the number of people who will consider your product increases to include people like me.

I bought the microbric viper because it was on sale: reduced to $29 from $199. If I had known I could only program it under windows or that it used such a closed platform, I won't have bought it, even for that price.

Cheers,
Steve

Labels: , , , ,


20090529

New addition to the work bench

Thanks to Anthony from Area I.T. & T, I am now a happy owner of a dual channel 40Mhz oscilloscope.

I am happier than a pig in mud!

Cheers,
Steve

Labels:


20090518

Sketch to calibrate SEN-08663

Got my hands on a ADJD-S371 on a breakout board from Sparkfun. The code below can be used to calibrate it. The most up-to-date version of the code can be found at my git repository under colour_sensor_calibration.

#include <Wire.h>
/* Calibrates the sensor to get white balance. Pin 2 should be connected
 * to LED on the breakout board's LED pin. Calibration is done by placing the
 * breakout board inside a pin pong ball, and using the built-in LED for
 * illumination.
 *
 * Amount of light is measured by charging N capacitors for time X then
 * reading off the voltage. (Conjecture)
 *
 * N is controlled by CAP_XXX
 * T is controlled by INT_XXX
 *
 * Calibration is done by adjusting the integration time. No real reason.
 */
int _slave_id = 0x74;
int _LED_pin = 2;

uint8_t read_register(uint8_t addr)
{
  i2c_send(_slave_id, &addr, 1);
  return i2c_read(_slave_id);
}

void write_register_int(uint8_t addr, int data)
{
 write_register_multibyte(addr, (uint8_t*)&data, 2);
}

/* write data[i] = register+i */
void write_register_multibyte(uint8_t addr, uint8_t* data, uint8_t bytes)
{
 for (int i = 0; i < bytes; ++i)
 {
  write_register(addr+i, data[i]);
 }
}

void write_register(uint8_t addr, uint8_t data)
{
 uint8_t bytes[] = {addr, data};
 i2c_send(_slave_id, bytes, 2);
}

uint8_t i2c_read(uint8_t id)
{
 Wire.requestFrom(_slave_id, 1);
 for(int i = 0; i<10 && !Wire.available(); ++i, delay(10));
 if (!Wire.available())
 {
  return 11;
 }
 return Wire.receive();
 
}

void i2c_send(uint8_t id, uint8_t * data, uint8_t len)
{
 Wire.beginTransmission(id);
 for(int i = 0; i < len; ++i)
 {
  Wire.send(data[i]);
 }
 Wire.endTransmission();
}

#define CTRL    0x00
#define CONFIG    0x01

#define CAP_RED   0x06
#define CAP_GREEN   0x07
#define CAP_BLUE   0x08

#define INT_RED_LO   0x0A
#define INT_RED_HI   0x0B
#define INT_GREEN_LO  0x0C
#define INT_GREEN_HI  0x0D
#define INT_BLUE_LO  0x0E
#define INT_BLUE_HI  0x0F

#define DATA_RED_LO  0x40
#define DATA_RED_HI  0x41
#define DATA_GREEN_LO  0x42
#define DATA_GREEN_HI  0x43
#define DATA_BLUE_LO  0x44
#define DATA_BLUE_HI  0x45

int read_colour(uint8_t low_addr)
{
 int lo = read_register(low_addr);
 int hi = read_register(low_addr+1);

 return lo|(hi<<8);
}

int red_integration_time = 2048;
int green_integration_time = 2048;
int blue_integration_time = 2048;

void set_integration_times(int red, int green, int blue)
{
 write_register_int(INT_RED_LO, red);
 write_register_int(INT_GREEN_LO, green);
 write_register_int(INT_BLUE_LO, blue);
}

void setup()
{
 pinMode(_LED_pin, OUTPUT);
 digitalWrite(_LED_pin, HIGH);

 Serial.begin(57600); 
 Wire.begin(); // join i2c bus (address optional for master)
 Serial.println("Setting up...");

 // datasheet says, wait 10us for hardware reset, so lets wait 1000
 delay(1);

 // gain setup
 write_register(CAP_RED, 0x08);
 write_register(CAP_GREEN, 0x08);
 write_register(CAP_BLUE, 0x08);

 set_integration_times(
  red_integration_time, 
  green_integration_time, 
  blue_integration_time
 );

 // ask for colour data and offset
 write_register(CTRL, 0x01);
}

void loop()
{
 if (read_register(CTRL))
 {
  return;
 }
 
 int red, green, blue;
 red = read_colour(DATA_RED_LO);
 green = read_colour(DATA_GREEN_LO);
 blue = read_colour(DATA_BLUE_LO);
 
 Serial.println("--------------");
 Serial.print("red: ");Serial.println(red);
 Serial.print("green: ");Serial.println(green);
 Serial.print("blue: ");Serial.println(blue);


 Serial.print("red_int: ");Serial.println(red_integration_time);
 Serial.print("green_int: ");Serial.println(green_integration_time);
 Serial.print("blue_int: ");Serial.println(blue_integration_time);

 // have to calibrate against blue, because LED has a blue bias otherwise
 // it would look like blue has high gain than it does
 float P = 1;
 int reference = blue;
 red_integration_time += (reference - red)*P;
 green_integration_time += (reference - green)*P;
 blue_integration_time += (reference - blue)*P;

 // set the new integration times
 set_integration_times(
  red_integration_time, 
  green_integration_time, 
  blue_integration_time
 );
 
 // ask for colour data again
 write_register(CTRL, 0x01);
}

Cheers,
Steve

Labels: , ,


20090508

Facebook python authentication gateway

Edit: it occurred to me what I have below is the basics of a thin facebook api wrapper. I might make it into one at some point in the future.

If you don't know what this does, you don't need it. Hope this helps some one. Written because pyfacebook is broken, always returns error 100.

def get_session(auth_token):
        params={
                "api_key":FB_API_KEY,
                "v":"1.0",
                "auth_token":auth_token,
                "generate_session_secret":1,
                "method":"auth.getSession",
        }

        sorted = params.items()
        sorted.sort(key=lambda x:x[0])

        str_to_hash = ''.join(["%s=%s"%(x[0], x[1]) for x in sorted])
        str_to_hash += FB_API_SECRET

        md5 = hashlib.md5()
        md5.update(str_to_hash)

        sig = md5.hexdigest()

        params["sig"] = sig

        encoded_params = urllib.urlencode(params)
        headers = {
                "Content-type":"application/x-www-form-urlencoded",
        }

        conn = httplib.HTTPConnection(FB_API_HOST)
        conn.request("POST", FB_API_PATH, encoded_params, headers)

        response = conn.getresponse()

        print response.status, response.reason
        return response.read()

This Works For Me when I use it with iphone facebook-connect client:

[FBSession sessionForApplication:myApiKey getSessionProxy:myURL delegate:self];

Cheers,
Steve

Labels: , ,


20090429

Stripping trailing whitespace from XCode

Firstly, my usual approach of s/\s+$//g doesn't work since it eats up the newline too. s/\s+$/\n/g doesn't work either because the Replace: field in the find dialogue doesn't escape the \n.

Final solution is as shown: s/[ \t]+$//g

Cheers,
Steve

Labels: , , , ,


20090406

Family Planning

YLDE comic: half as funny half as often.


because imitation is the best form of flattery.

Cheers,
Steve

Labels: ,


20090402

Finally

I cheated thought.

Cheers,
Steve


20090216

Futurlec Ultrasonic Sensor Note

Part number US1440, these sensors are not dual use, which means the transmitter and receiver is not exchangeable. They also look identical from the outside, so if you build my arduino ultrasound ranger with these (as I did) and find you can't see echoes, try swapping your transmitter and receiver around! It cost me no small amount of headach this morning.

Cheers,
Steve

Labels:


Arduino ultrasound ranger

Code to drive it is avaliable under GPL.

An updated version of the schematic as a .sch file is available also.

Cheers,
Steve

Labels: , , ,


20090213

The libertarian argument against vaccination

Goes like this:

I have a right to decide what happens to my children!

To that I say, we have the right to not be a victim of your stupidity. Further, laws represent social contracts that all members of society enter into for everyone's benefit. Getting vaccinated is one such contract which serves to prevent epidemics of infectious diseases.

If you really don't want to vaccinate your child, then please ensure your child never comes into physical contact with the rest of society for our sake. I would not welcome them without vaccinations.

Cheers,
Steve

Labels:


20090206

MATHS FAIL

What is the period if you want to generate a 40KHz signal? It certainly isn't 250E-6 seconds. The same calculator returns 2500E-3 for 1/4 which is 2.5, not 0.25.

The calculator is PEMDAS.

Cheers,
Steve


This page is powered by Blogger. Isn't yours?