#!/bin/sh # getChallengeResponse.sh - login to my online banking website using the challenge-reponse mechanism # Purpose of this script (work in progress) is to further automate online banking. # More info: http://globalblindspot.blogspot.be/2010/07/getting-emvcap-challengeresponse-to.html # Author: Tom Van Braeckelpin="$1" challenge="$2" if [ -z "$pin" -o `expr length "$pin"` -ne 4 -o -z "$challenge" -o `expr length "$challenge"` -ne 8 ]; then echo "Usage: $0 " echo "Example: $0 3117 12345678" exit 1 fi # Can you guess what this method does ? bintodec() { bin="$1" echo "obase=10; ibase=2; $bin" | bc } # remove < and " " compact() { while read line; do echo "$line" | tr -d '<' | tr -d ' ' done } # args: command to execute on the card execOnCard() { cla="$1" ins="$2" p1="$3" p2="$4" le="$5" data="$6" tosend="${cla}${ins}${p1}${p2}${le}${data}" #echo "Sending $tosend" >&2 echo "$tosend" | scriptor 2>/dev/null | grep -A 10000 "<" # does not work: # echo "$cla $ins $p1 $p2 $le $data" | scriptor 2>/dev/null | grep "<" } execOnCardRespond() { cla="$1" ins="$2" p1="$3" p2="$4" le="$5" data="$6" result=$(execOnCard $cla $ins $p1 $p2 $le $data) ; echo "result = $result" >&2 # get length in hex length=$(echo "$result" | cut -d ' ' -f 3); #echo "length = $length" execOnCard 00 c0 00 00 $length | compact } # Can you guess what this method does ? hextobin() { hex="$1" echo "ibase=16; obase=2; $hex" | bc } # do a read data with the correct length... readData() { p2="$1" recordLength=$(execOnCard 80 ca 9f $p2 00 | cut -d ' ' -f 3) #echo "recordLength = $recordLength" >&2 # cut off first bytes (status code, length) # cut off last bytes (9000Normalprocessing) # for some reason we NEED CLA 80 here, 00 doesn't work... execOnCard 80 ca 9f $p2 $recordLength | compact | tail -c +7 | head -c -23 echo } readRecord() { p1="$1" p2="$2" errorWithLength=$(execOnCard 00 b2 $p1 $p2 00) #echo "errorWithLength = $errorWithLength" recordLength=$(echo "$errorWithLength" | cut -d ' ' -f 3) #echo "recordLength = $recordLength" execOnCard 00 b2 $p1 $p2 $recordLength | compact } readRecords() { SFI="$1" # five most significant bits recNr="$2" # second byte lastRecNr="$3" # third byte if [ "$SFI" = "1" ]; then p2=0c # (sfi << 3) + 4 else echo "I don't know p2 !" sleep 3 fi # READ RECORD(s) for i in `seq $recNr $lastRecNr`; do readRecord 0$i $p2 done } zeropadfront() { targetLength="$1" # echo "targetLength = $targetLength" while read line; do # echo "got line $line" length=$(expr length "$line") while [ $length -lt $targetLength ]; do line="0${line}" length=$(expr length "$line") done echo "$line" done } ################################################################# ###################### EXECUTION STARTS HERE #################### ################################################################# # reset execOnCard reset #select file/application aid=A0000000048002 # securecode aut #aid=A0000000043060 # maestro (debit) response=$(execOnCardRespond 00 a4 04 00 07 ${aid}) echo $response # this is needed, otherwise the commands below fail... PDOL=$(echo "$response" | grep -o -E "9F38........" | tail -c +7) echo "PDOL = $PDOL" # for securecode get a PDOL of "9F3501" (eg "9F38039F3501") # this is the "Terminal Type" - don't know the value, but I use 00... # get processing options: # - Application Interchange Profile (AIP) # - Application File Locator (AFL) if [ -z "$PDOL" ]; then response=$(execOnCardRespond 80 a8 00 00 02 8300); echo $response # eg: ...94080801030110010201 AIP=3800 # this means "initiate", "data auth", RFU AFLs="08010301 10010201" else # PDOL specifies one tag with value of 1 byte, but I don't know which value... response=$(execOnCardRespond 80 a8 00 00 03 830100); echo $response # 770E82021000940808010100080404009000:Normalprocessing. AIP=1000 # this means "initiate" AFLs="08010100 08040400" fi echo "Found AIP = $AIP and AFLs = $AFLs" # Read SecureCode records and extract valueable info cardinfo=$(readRecords 1 1 1) PAN=$(expr substr "$cardinfo" 9 18) echo "Application Primary Account Number (PAN) = $PAN" authinfo=$(readRecords 1 4 4) bitmap=$(expr substr "$authinfo" 11 22) echo "Proprietary Authentication Challenge-Reponse Bitmap = $bitmap" # This works for maestro: if false; then readRecords 1 1 3 # second group in AFL SFI=10 # five most significant bits recNr=1 # second byte lastRecNr=2 # third byte offlineDataRec=1 # fourth byte # p2=binary(firstbyte)100 left shift 3 OR 100 ??? # p2=binary(firstbyte) shift right 3 # I calculated 84, but it seems to be (13) 14 / (1B) 1C / (23) 24 # and also 03 04 0B 0C but we found those above p2s="14 1C 24" # READ RECORD(s) for p2 in $p2s; do for i in `seq $recNr $lastRecNr`; do echo -n "p2 = $p2, recordNr = $i: " readRecord 0$i $p2 done done fi # get pin try counter length pinTry=$(readData 17) echo "pinTry = $pinTry" if [ "$pinTry" != "02" -a "$pinTry" != "03" ]; then echo "WARNING: pinTry < 2 !" sleep 15 fi # get Application Transaction Counter echo -n "Application Transaction Counter = " readData 36 # get Last Online ATC Register echo -n "Last Online ATC Register = " readData 13 echo -n "Log Entry = " readData 4D echo -n "Log Format = " readData 4F # submit pin execOnCard 00 20 00 80 08 24${pin}FFFFFFFFFF # generate Application RQ Cryptogram # p1=80=Authorisation Request Cryptogram countrycode=0056 # OTF mentions 0000, chip&pin uses 0826 currencycode=0978 # OTF mentions 0000, chip&pin uses 0826 date=$(date +"%y%m%d") CardholderVerificationMethodResults=010002 # 8000000000 = Terminal Verification Codes: Data authentication was not performed (recommended by optimized to fail) # 00 = transaction type # 0000 = ICC Dynamic Number ARQC_response=$(execOnCardRespond 80 AE 80 00 22 000000000000000000000000${countrycode}8000000000${currencycode}${date}00${challenge}0000${CardholderVerificationMethodResults}) echo "ARQC_response = $ARQC_response" CID=$(expr substr "$ARQC_response" 11 2) ATC=$(expr substr "$ARQC_response" 19 4) AC=$(expr substr "$ARQC_response" 29 16) #IAD=$(expr substr "$ARQC_response" 51 15) # testing to see if we get the same response as in chip&pin - we do, so this is OK. # CID=80; ATC=A52D; AC=AD452EF6BA769E4A; IAD=06770A03A48000; bitmap=00001F00000000000FFFFF00000000008000 # generate Application Cryptogram for challenge 12345678 # 5a33 = Authorisation Response Code, generated by terminal or bank (for online stuff) IAuthData=0000000000000000000000000000000000000000 # Issuer Authentication Data (NOT Issuer Application Data !) AC_response=$(execOnCardRespond 80 AE 00 00 2e 5a33000000000000000000000000${countrycode}8000000000${currencycode}${date}00${challenge}0000${CardholderVerificationMethodResults}${IAuthData}) echo "AC_response = $AC_response" #AC_response="$ARQC_response" # Testing which response we need - normally the second one, but let's try this for a laugh CID=$(expr substr "$AC_response" 11 2) ATC=$(expr substr "$AC_response" 19 4) AC=$(expr substr "$AC_response" 29 16) # extract response echo "CID=$CID, ATC=$ATC, AC=$AC, IAD=$IAD" # length of bitmap is used as the target length for the response bitmap_hex_length=$(expr length "$bitmap") bitmap_bin_length=$(expr "$bitmap_hex_length" \* 4) echo bitmap_hex_length=$bitmap_hex_length, bitmap_bin_length=$bitmap_bin_length # Do logical AND with bitmap CIDATCAC_bin=$(hextobin "${CID}${ATC}${AC}${IAD}" | zeropadfront "$bitmap_bin_length") echo "CIDATCAC_bin = $CIDATCAC_bin" bitmap_bin=$(hextobin "$bitmap" | zeropadfront "$bitmap_bin_length") echo " bitmap_bin = $bitmap_bin" # if a bit of bitmap = 1, then we add the bit from CIDATCAC_bin to filtered_bin filtered_bin= for bitpos in `seq 1 $bitmap_bin_length`; do bitmap_bit=$(expr substr "$bitmap_bin" "$bitpos" 1) if [ $bitmap_bit -eq 1 ]; then CIDATCAC_bin_bit=$(expr substr "$CIDATCAC_bin" "$bitpos" 1) filtered_bin=${filtered_bin}${CIDATCAC_bin_bit} fi done echo "filtered_bin = $filtered_bin" # Note: if ATC>0x26(38) then response = 8 characters # if ATC=0xFFFF(65536) then response = 12 characters !!! is this correct ? filtered_dec=$(bintodec $filtered_bin) echo "RESPONSE = $filtered_dec" exit # this is never executed if false; then # Make AND of ARQC and Cap bit Filter: fortis: 77269F2701 00 9F3602 00B7 9F260886F857BEB767E8FB 9F100F 0601560384B0A80701030000000000 kbc: 77269F2701 00 9F3602 0004 9F260831F94BDAB5DF0F38 9F100F 0601560384B0400701030000000000 kbc: 77269F2701 00 9F3602 0005 9F2608B29D6D20BFE004AD 9F100F 0601560384B0400701030000000000 # extracted values output 00 00B7 86F857BEB767E8FB 0601560384B0A80701030000000000 output 00 0004 31F94BDAB5DF0F38 0601560384B0A80701030000000000 bitmask 00 00FF 000000000003FFFF filter .. ..04 ...........30F38 binary 0100 110000111100111000 decimal 1249080 fi Example protocol log: Collected from a NatWest reader and card performing a respond computation (ISO 7816, T=0 protocol). Personal details have been redacted. Command: 00a4040007 (select application) Proc: a4 Data: a0000000048002 Proc: 61 Status: 6112 (more data available) Command: 00c0000012 (application selected) Proc: c0 Data: 6f108407a0000000048002a5055f2d02656e Proc: 90 Status: 9000 (OK) Command: 80a8000002 (initiate transaction) Proc: a8 Data: 8300 Proc: 61 Status: 6108 (more data available) Command: 00c0000008 (transaction initiated) Proc: c0 Data: 8006100008010100 Proc: 90 Status: 9000 (OK) Command: 00b2010c00 (get static data length) Proc: 6c Status: 6c57 (wrong length) Command: 00b2010c57 (read static data) Proc: b2 Data: 7055 8e0a 00000000000000000100 (CVM list) 9f5501 a0 (unknown) 9f5612 00001f00000000000fffff00000000008000 (bit filter) 8c15 9f02069f03069f1a0295055f2a029a039c019f3704 (CDOL1) 8d17 8a029f02069f03069f1a0295055f2a029a039c019f3704 (CDOL2) Proc: 90 Status: 9000 (OK) Command: 80ca9f1700 (get PIN try counter length) Proc: 6c Status: 6c04 (wrong length) Command: 80ca9f1704 (get PIN try counter) Proc: ca Data: 9f170103 (3 remaining tries) Proc: 90 Status: 9000 (OK) PIN entered: ? Command: 0020008008 (verify PIN) Proc: 20 Data: 24xxxxffffffffff Proc: 90 Status: 9000 (OK) Challenge entered: 12345678 Command: 80ae80001d (generate ARQC) Proc: ae Data: 0000000000000000000000000000800000000000000000000012345678 Proc: 61 Status: 6114 (more data available) Command: 00c0000014 (return ARQC) Proc: c0 Data: 80 1280 0042b7f9a572da74caff 06770a03a48000 Proc: 90 Status: 9000 (OK) Command: 80ae00001f (generate AC) Proc: ae Data: 5a330000000000000000000000000000800000000000000000000012345678 Proc: 61 Status: 6114 (more data available) Command: 00c0000014 (return AAC) Proc: c0 Data: 80 1200 00424f1c597723c97d78 06770a03258000 Proc: 90 Status: 9000 (OK) Response returned: 4822527
Various wacky and hacky technological research projects, shared with the world so that restless brains may find peace of mind here.
vrijdag 31 mei 2013
getChallengeResponse.sh script
donderdag 31 januari 2013
Love is Math As Well
We don't remember what it was like
that first time
what we talked about
whether we showed each other things
which we didn't yet have
the stale wines
in the polished vases
warm bodies in winter
whether we read
from closed books
added ourselves together and
knew we never
would have to divide
together exponential
a multiplication with
in the cross that we
no longer wanted to carry
a conclusive casting out of nines.
[I translated "Liefde is ook Wiskunde" by Bart Plouvier from Dutch to English for the national poetry day in Belgium.]
donderdag 6 september 2012
File type associations with xdg-open and xdg-mime (for openbox) example
Just so I don't forget, here is how to do it - it's very simple, really:
xdg-mime default xarchiver.desktop application/x-compressed-tar
Why ?
When I clicked on a .tar.gz file in chromium, my desktop environment would hang.
This was caused the fact that chromium calls xdg-open to know which program to use to open the .tar.gz file. xdg-open used "xdg-mime query default application/x-compressed-tar" to figure out what application to use (which was none, because I hadn't configured any default application).
After that, xdg-open doesn't stop. If /etc/debian-version exists, it additionally uses run-mailcap to figure out which program to use. And mailcap was configured to run "less" somewhere down the line, which stops and apparently, stops it's parent processes for some unknown reason when run in this configuration.
So I deleted /etc/debian-version because I don't see the point of having it. We'll see if something what breaks.
How ?
xdg-mime will create the file ~/.local/share/applications/mimeapps.list which then contains:[Default Applications]
application/x-compressed-tar=xarchiver.desktop
zondag 17 juni 2012
Rudimentary PDF to LaTeX conversion in Linux
I finally got around to trying a rudimentary PDF to LaTeX conversion in Linux.
"It's like turning a hamburger into a cow" :-)
Usage:
./pdftolatex.sh "filename.pdf"
Example output:
# pdftolatex.sh test.pdf
PDF to LaTeX conversion script
Copyleft 2012 (c) Tom Van Braeckel <tomvanbraeckel@gmail.com>
WARNING: this is a rudimentary first stab. Proceed with caution.
Checking if all dependencies are found...
/usr/bin/pdftohtml
Dependency pdftohtml found.
/usr/bin/gnuhtml2latex
Dependency gnuhtml2latex found.
/usr/bin/pdflatex
Dependency pdflatex found.
Converting test.pdf to test.pdfs.html
Page-1
Page-2
Page-3
Page-4
Page-5
Page-6
Page-7
Page-8
Page-9
Page-10
Page-11
Fixing up test.pdfs.html to test.pdf_fixedup.html...
Readying test.pdf_fixedup.html for tex conversion in test.pdf_fixedup_ready_for_tex_conversion.html
Converting test.pdf_fixedup_ready_for_tex_conversion.html to test.pdf_frompdf.tex
The resulting file is in test.pdf_frompdf.tex
Fixing up test.pdf_frompdf.tex to test.pdf_frompdf_fixedup.tex
Converting test.pdf_frompdf_fixedup.tex to test.pdf_frompdf_fixedup.pdf for inspection...
Opening test.pdf_frompdf_fixedup.pdf with Evince - you can try another PDF viewer if you like...
[Update] You can also try the following method, using abiword, but the method above yields better results, in my opinion:
abiword --to=tex "filename.pdf"
"It's like turning a hamburger into a cow" :-)
Usage:
./pdftolatex.sh "filename.pdf"
Example output:
# pdftolatex.sh test.pdf
PDF to LaTeX conversion script
Copyleft 2012 (c) Tom Van Braeckel <tomvanbraeckel@gmail.com>
WARNING: this is a rudimentary first stab. Proceed with caution.
Checking if all dependencies are found...
/usr/bin/pdftohtml
Dependency pdftohtml found.
/usr/bin/gnuhtml2latex
Dependency gnuhtml2latex found.
/usr/bin/pdflatex
Dependency pdflatex found.
Converting test.pdf to test.pdfs.html
Page-1
Page-2
Page-3
Page-4
Page-5
Page-6
Page-7
Page-8
Page-9
Page-10
Page-11
Fixing up test.pdfs.html to test.pdf_fixedup.html...
Readying test.pdf_fixedup.html for tex conversion in test.pdf_fixedup_ready_for_tex_conversion.html
Converting test.pdf_fixedup_ready_for_tex_conversion.html to test.pdf_frompdf.tex
The resulting file is in test.pdf_frompdf.tex
Fixing up test.pdf_frompdf.tex to test.pdf_frompdf_fixedup.tex
Converting test.pdf_frompdf_fixedup.tex to test.pdf_frompdf_fixedup.pdf for inspection...
Opening test.pdf_frompdf_fixedup.pdf with Evince - you can try another PDF viewer if you like...
Script source code:
#!/bin/sh
file="$1"
dependencies="pdftohtml gnuhtml2latex pdflatex"
echo "PDF to LaTeX conversion script"
echo "Copyleft 2012 (c) Tom Van Braeckel <tomvanbraeckel@gmail.com>"
echo
echo "WARNING: this is a rudimentary first stab. Proceed with caution."
echo
if [ -z "$file" ]; then
echo "Usage: $0 <pdf file>"
echo "The resulting .tex file will be stored somewhere here."
exit 1
fi
echo
echo "Checking if all dependencies are found..."
for dependency in $dependencies; do
which $dependency
if [ $? -ne 0 ]; then
echo "Dependency $dependency not found, install it using:"
echo "sudo apt-get install $dependency"
exit 1
else
echo "Dependency $dependency found."
fi
done
echo
echo "Converting $file to ${file}s.html"
pdftohtml -nomerge "$file" "$file".html
echo
echo "Fixing up ${file}s.html to ${file}_fixedup.html..."
# This nasty br in a b causes problems later on
sed "s,<br/></b>,</b><br/>,g" "${file}s.html" > "${file}_fixedup.html"
# ending with bold text menas it is the end of a title and can be on a newline
sed -i "s,</b><br/>\$,</b><br/><br/>,g" "${file}_fixedup.html"
# starting with bold text means it is the start of a title so can be on a new line
sed -i "s,^<b>,<br/><b>,g" "${file}_fixedup.html"
# spaces ?
sed -i "s,\ , ,g" "${file}_fixedup.html"
# there is no use in a space before a newline, and it causes a bogus indent when converting to .tex later on
sed -i "s, <br/>,<br/>,g" "${file}_fixedup.html"
# encoding, although gnuhtml2latex ignores this
sed -i "s,<HEAD>,<HEAD><meta http-equiv='Content-Type' content='text/html; charset=UTF-8' />," "${file}_fixedup.html"
echo
echo "Readying ${file}_fixedup.html for tex conversion in ${file}_fixedup_ready_for_tex_conversion.html"
cp "${file}_fixedup.html" "${file}_fixedup_ready_for_tex_conversion.html"
# br is ignored and should be replaced by a newline
sed -i "s,<br/>,<p></p>,g" "${file}_fixedup_ready_for_tex_conversion.html"
# Remove bogus links - this fixes the empty } problem
sed -i "s/<A name=[0-9]\+><\/a>//g" "${file}_fixedup_ready_for_tex_conversion.html"
echo
echo "Converting ${file}_fixedup_ready_for_tex_conversion.html to ${file}_frompdf.tex"
# -c = table of contents
# -s = write to standard out
# -p Break page after title / table of contents
# -H use hyperref package to process anchors
# -g images
# -n Use numbered sections
gnuhtml2latex -c -s -p -H -n "${file}_fixedup_ready_for_tex_conversion.html" > "$file"_frompdf.tex
echo "The resulting file is in ${file}_frompdf.tex"
echo
echo "Fixing up ${file}_frompdf.tex to ${file}_frompdf_fixedup.tex"
sed -i 's/\\par/\\newline/g' "${file}_frompdf.tex"
( cat header.inc ; tail -n +7 "${file}_frompdf.tex" ) > "${file}_frompdf_fixedup.tex"
echo
echo "Converting ${file}_frompdf_fixedup.tex to ${file}_frompdf_fixedup.pdf for inspection..."
pdflatex -interaction nonstopmode "${file}_frompdf_fixedup.tex" > tex_to_pdf_errors_and_warnings.txt
echo
echo "Opening ${file}_frompdf_fixedup.pdf with Evince - you can try another PDF viewer if you like..."
evince "$file"_frompdf_fixedup.pdf
The script uses one extra file, header.inc, which contains customizations:
\documentclass[a4paper,11pt,oneside]{article}
\usepackage{a4wide} % Iets meer tekst op een bladzijde
\usepackage[dutch]{babel} % Voor nederlandstalige hyphenatie (woordsplitsing) en het euro-symbool
\usepackage{amsmath} % Uitgebreide wiskundige mogelijkheden
\usepackage{amssymb} % Voor speciale symbolen zoals de verzameling Z, R...
\usepackage{url} % Om url's te verwerken
\usepackage{graphicx} % Om figuren te kunnen verwerken
\usepackage[small,bf,hang]{caption} % Om de captions wat te verbeteren
\usepackage{xspace} % Magische spaties na een commando
\usepackage[utf8]{inputenc} % Om niet ascii karakters rechtstreeks te kunnen typen
\usepackage{float} % Om nieuwe float environments aan te maken. Ook optie H!
\usepackage{flafter} % Opdat floats niet zouden voorsteken
\usepackage{listings} % Voor het weergeven van letterlijke text en codelistings
\usepackage{marvosym} % Om het euro symbool te krijgen
\usepackage{eurosym} % Om het euro symbool te krijgen
\usepackage{textcomp} % Voor onder andere graden celsius
\usepackage{fancyhdr} % Voor fancy headers en footers.
\usepackage{graphics} % Om figuren te verwerken.
\usepackage[a4paper,plainpages=false]{hyperref} % Om hyperlinks te hebben in het pdfdocument.
\usepackage[usenames,dvipsnames]{xcolor}
% Definitie algemene macro's
\newcommand{\npar}{\par \vspace{0.2ex }}
\setlength\textheight{9.75in}
\setlength\textwidth{7in}
\topmargin -0.5in
\headheight 0.0in
\oddsidemargin -.25in
[Update] You can also try the following method, using abiword, but the method above yields better results, in my opinion:
abiword --to=tex "filename.pdf"
zaterdag 2 juni 2012
zaterdag 5 mei 2012
Please don't blame the weather
Please don't blame the weather
It’s got nothing to do with the weater.
Blame me and sincerely blame yourself.
Try waking up in the morning and
feeling better than the day before.
Wash off your guilt, get over yourself,
and stop wasting time persuing shit.
Contemplate life’s meaning and
the sadness of existence.
Blame me and sincerely blame yourself.
Try waking up in the morning and
feeling better than the day before.
Wash off your guilt, get over yourself,
and stop wasting time persuing shit.
Contemplate life’s meaning and
the sadness of existence.
donderdag 1 maart 2012
Keycodes and coffeeshops in the Linux kernel
We are using gpio-keys to configure 2 GPIO's coming from 2 sensors (left and right on our device) as keyboard interrupt lines.
So I had to choose 2 obscure keycodes to map on "proximity meter left" and "proximity meter right"...
Here are the results:
{
So I had to choose 2 obscure keycodes to map on "proximity meter left" and "proximity meter right"...
Here are the results:
{
.gpio = INT_PROX_L,
These keynames and their order are easy to memorize now, because (since we read from left to right) we know that coffee = left and shop = right :-)
.code = KEY_COFFEE,
.desc = "Proximity Left",
},
{
.gpio = INT_PROX_R,
.code = KEY_SHOP,
.desc = "Proximity Right",
},
zondag 8 januari 2012
rsync and scp autocompletion
Apparantly, rsync and scp boast tab autocompletion !
When you have configured passwordless SSH access (by copying over your public key) and you use these tools, tab autocompletion works as expected.
For example, typing the following on a bash shell:
rsync localfile.txt exampleserver:/examp<TAB>
will automatically autocomplete the foldername.
In the example's case, it becomes:
rsync localfile.txt exampleserver:/examplefolder/
The same goes for scp, like:
scp localfile.txt exampleserver:/examp<TAB>
becomes
rsync localfile.txt exampleserver:/examplefolder
rsync and scp are able to do this because the passwordless SSH allows them to see what files can be found on the other server without asking for a password.
On my LAN network, it takes about 1 second to autocomplete, which is perfectly acceptable for me. It certainly beats having to open a seperate SSH session and manually making a lising ;-)
When you have configured passwordless SSH access (by copying over your public key) and you use these tools, tab autocompletion works as expected.
For example, typing the following on a bash shell:
rsync localfile.txt exampleserver:/examp<TAB>
will automatically autocomplete the foldername.
In the example's case, it becomes:
rsync localfile.txt exampleserver:/examplefolder/
The same goes for scp, like:
scp localfile.txt exampleserver:/examp<TAB>
becomes
rsync localfile.txt exampleserver:/examplefolder
rsync and scp are able to do this because the passwordless SSH allows them to see what files can be found on the other server without asking for a password.
On my LAN network, it takes about 1 second to autocomplete, which is perfectly acceptable for me. It certainly beats having to open a seperate SSH session and manually making a lising ;-)
Super-sleek shell script as a simple touchscreen controller for Linux
#!/bin/sh
# Beautifully simple shell script to detect screen touches
# I use it to toggle the music player on my FriendlyARM 2440 Mini
# but it can be used for any Linux touch screen
# but it can be used for any Linux touch screen
# Copyleft 2011 - t-Omicr0n
while true; do
head -c 1 /dev/input/event0
echo "You touched it !"
done &
Hunting advice
Let's say you're a hunter. If a deer takes your gun, shoots itself and then straps itself to the roof of your car..... you have to take it home and eat it ! -- Two and a Half Men
donderdag 15 september 2011
Calculating significance indicates insignificance
Calculating significance indicates insignificance -- Jasper Nuyens, 2011
dinsdag 6 september 2011
Joan Halifax's "Compassion"
Equanimity is a state of mental or emotional stability or composure arising from a deep awareness and acceptance of the present moment.
Great TED talk: Joan Halifax: Compassion and the true meaning of empathy
Great TED talk: Joan Halifax: Compassion and the true meaning of empathy
woensdag 29 juni 2011
How to replace a failed disk of a RAID 5 array with mdadm on Linux
This is easy, once you know how it's done :-) These instructions were made on Ubuntu but they apply to many Linux distributions.
First of all, physically install your new disk and partition it so that it has the same (or a similar) structure as the old one you are replacing.
Then, install mdadm if you haven't already:
Optional but might be a good idea if you can: reboot to make sure the whole md (multi-disk) software stack is loaded.
Let's check the status of our disks - mdadm should have discovered at least *something* on boot:
So this looks like it created one RAID device (/dev/md0) that consists of /dev/sdb2 and /dev/sdc2. We are need at least 3 disks for our RAID 5 so let's add another one:
Hmm, this doesn't work because the RAID array in /dev/md0 is not active.
Let's activate it then:
Hmm, mdadm is not aware of the physical disks that /dev/md0 consists of. That's strange, because that information is clearly visible in /proc/mdstat, remember ?
A look at the man page reveals the --scan option, that tells mdadm to scan /proc/mdstat (and others) for RAID device information.
Let's try again:
Ok, so we knew that - the RAID 5 is missing a disk.
But we need to activate it anyhow, to be able to add the missing disk !
So we force it:
Hmm, something's keeping our RAID array busy...
Let's just restart that RAID volume to fix that:
And try again:
Success !
Let's see what happened just now:
evy@evy-server:~$ cat /proc/mdstat
Personalities : [linear] [multipath] [raid0] [raid1] [raid6] [raid5] [raid4] [raid10]
md0 : active raid5 sdb2[1] sdc2[2]
3858200832 blocks level 5, 64k chunk, algorithm 2 [3/2] [_UU]
Aha, there is movement !
The RAID 5 array is online, and the [_UU] flags show us that one disk is missing.
Here's some more info that demonstrates this nicely:
So let's try to add that missing disk, which had been our intent all along.
And this works.
Check it:
The RAID has already started rebuilding!
We can watch the progress like this:
Aaaaaaah, there's no greater time to go to bed than when your RAID 5 is recovering :-)
First of all, physically install your new disk and partition it so that it has the same (or a similar) structure as the old one you are replacing.
Then, install mdadm if you haven't already:
sudo apt-get install mdadm
Optional but might be a good idea if you can: reboot to make sure the whole md (multi-disk) software stack is loaded.
Let's check the status of our disks - mdadm should have discovered at least *something* on boot:
evy@evy-server:~$ cat /proc/mdstat
Personalities : [linear] [multipath] [raid0] [raid1] [raid6] [raid5] [raid4] [raid10]
md0 : inactive sdb2[1](S) sdc2[2](S)
3858200832 blocks
So this looks like it created one RAID device (/dev/md0) that consists of /dev/sdb2 and /dev/sdc2. We are need at least 3 disks for our RAID 5 so let's add another one:
evy@evy-server:~$ sudo mdadm --manage /dev/md0 --add /dev/sda3
mdadm: cannot get array info for /dev/md0
Hmm, this doesn't work because the RAID array in /dev/md0 is not active.
Let's activate it then:
evy@evy-server:~$ sudo mdadm --assemble /dev/md0
mdadm: no devices found for /dev/md0
Hmm, mdadm is not aware of the physical disks that /dev/md0 consists of. That's strange, because that information is clearly visible in /proc/mdstat, remember ?
A look at the man page reveals the --scan option, that tells mdadm to scan /proc/mdstat (and others) for RAID device information.
Let's try again:
evy@evy-server:~$ sudo mdadm --assemble /dev/md0 --scan
mdadm: /dev/md0 assembled from 2 drives - not enough to start the array while not clean - consider --force.
Ok, so we knew that - the RAID 5 is missing a disk.
But we need to activate it anyhow, to be able to add the missing disk !
So we force it:
evy@evy-server:~$ sudo mdadm --assemble /dev/md0 --scan --force
mdadm: SET_ARRAY_INFO failed for /dev/md0: Device or resource busy
Hmm, something's keeping our RAID array busy...
Let's just restart that RAID volume to fix that:
evy@evy-server:~$ sudo mdadm --stop /dev/md0
mdadm: stopped /dev/md0
And try again:
evy@evy-server:~$ sudo mdadm --assemble /dev/md0 --scan --force
mdadm: /dev/md0 has been started with 2 drives (out of 3).
Success !
Let's see what happened just now:
Personalities : [linear] [multipath] [raid0] [raid1] [raid6] [raid5] [raid4] [raid10]
md0 : active raid5 sdb2[1] sdc2[2]
3858200832 blocks level 5, 64k chunk, algorithm 2 [3/2] [_UU]
The RAID 5 array is online, and the [_UU] flags show us that one disk is missing.
Here's some more info that demonstrates this nicely:
evy@evy-server:~$ sudo mdadm --detail /dev/md0
/dev/md0:
Version : 00.90
Creation Time : Mon Feb 7 18:27:14 2011
Raid Level : raid5
Array Size : 3858200832 (3679.47 GiB 3950.80 GB)
Used Dev Size : 1929100416 (1839.73 GiB 1975.40 GB)
Raid Devices : 3
Total Devices : 2
Preferred Minor : 0
Persistence : Superblock is persistent
Update Time : Mon Apr 25 13:04:09 2011
State : clean, degraded
Active Devices : 2
Working Devices : 2
Failed Devices : 0
Spare Devices : 0
Layout : left-symmetric
Chunk Size : 64K
UUID : 90b591c9:2fd9536f:86e10ba8:fe4e4a37
Events : 0.172
Number Major Minor RaidDevice State
0 0 0 0 removed
1 8 18 1 active sync /dev/sdb2
2 8 34 2 active sync /dev/sdc2
/dev/md0:
Version : 00.90
Creation Time : Mon Feb 7 18:27:14 2011
Raid Level : raid5
Array Size : 3858200832 (3679.47 GiB 3950.80 GB)
Used Dev Size : 1929100416 (1839.73 GiB 1975.40 GB)
Raid Devices : 3
Total Devices : 2
Preferred Minor : 0
Persistence : Superblock is persistent
Update Time : Mon Apr 25 13:04:09 2011
State : clean, degraded
Active Devices : 2
Working Devices : 2
Failed Devices : 0
Spare Devices : 0
Layout : left-symmetric
Chunk Size : 64K
UUID : 90b591c9:2fd9536f:86e10ba8:fe4e4a37
Events : 0.172
Number Major Minor RaidDevice State
0 0 0 0 removed
1 8 18 1 active sync /dev/sdb2
2 8 34 2 active sync /dev/sdc2
evy@evy-server:~$ sudo mdadm --manage /dev/md0 --add /dev/sda3
mdadm: added /dev/sda3
mdadm: added /dev/sda3
And this works.
Check it:
evy@evy-server:~$ sudo mdadm --detail /dev/md0
/dev/md0:
Version : 00.90
Creation Time : Mon Feb 7 18:27:14 2011
Raid Level : raid5
Array Size : 3858200832 (3679.47 GiB 3950.80 GB)
Used Dev Size : 1929100416 (1839.73 GiB 1975.40 GB)
Raid Devices : 3
Total Devices : 3
Preferred Minor : 0
Persistence : Superblock is persistent
Update Time : Wed Jun 29 23:39:54 2011
State : clean, degraded, recovering
Active Devices : 2
Working Devices : 3
Failed Devices : 0
Spare Devices : 1
Layout : left-symmetric
Chunk Size : 64K
Rebuild Status : 0% complete
UUID : 90b591c9:2fd9536f:86e10ba8:fe4e4a37
Events : 0.176
Number Major Minor RaidDevice State
3 8 3 0 spare rebuilding /dev/sda3
1 8 18 1 active sync /dev/sdb2
2 8 34 2 active sync /dev/sdc2
/dev/md0:
Version : 00.90
Creation Time : Mon Feb 7 18:27:14 2011
Raid Level : raid5
Array Size : 3858200832 (3679.47 GiB 3950.80 GB)
Used Dev Size : 1929100416 (1839.73 GiB 1975.40 GB)
Raid Devices : 3
Total Devices : 3
Preferred Minor : 0
Persistence : Superblock is persistent
Update Time : Wed Jun 29 23:39:54 2011
State : clean, degraded, recovering
Active Devices : 2
Working Devices : 3
Failed Devices : 0
Spare Devices : 1
Layout : left-symmetric
Chunk Size : 64K
Rebuild Status : 0% complete
UUID : 90b591c9:2fd9536f:86e10ba8:fe4e4a37
Events : 0.176
Number Major Minor RaidDevice State
3 8 3 0 spare rebuilding /dev/sda3
1 8 18 1 active sync /dev/sdb2
2 8 34 2 active sync /dev/sdc2
The RAID has already started rebuilding!
We can watch the progress like this:
evy@evy-server:~$ cat /proc/mdstat
Personalities : [linear] [multipath] [raid0] [raid1] [raid6] [raid5] [raid4] [raid10]
md0 : active raid5 sda3[3] sdb2[1] sdc2[2]
3858200832 blocks level 5, 64k chunk, algorithm 2 [3/2] [_UU]
[>....................] recovery = 0.0% (673180/1929100416) finish=429.6min speed=74797K/sec
Personalities : [linear] [multipath] [raid0] [raid1] [raid6] [raid5] [raid4] [raid10]
md0 : active raid5 sda3[3] sdb2[1] sdc2[2]
3858200832 blocks level 5, 64k chunk, algorithm 2 [3/2] [_UU]
[>....................] recovery = 0.0% (673180/1929100416) finish=429.6min speed=74797K/sec
dinsdag 28 juni 2011
Reverse engineered Logitech C110 color changing driver
I reverse engineered the windows driver of my Logitech C110 keyboard and remade it for Linux (with libusb) so that we can now change the color of the led lights in any shade between red and blue.
Attached is a proof of concept that I keep running all the time. It slowly, gradually makes the backlight color change from blue to red and back.
This open source Linux driver outperforms the proprietary windows driver because it enables continuously changing the backlight color in addition to setting just one, fixed color.
You can find it here: http://code.google.com/p/logitech-keyboard-change-color/downloads/list
The most interesting line of code (MILOC) is this one:
where:
I hope you enjoy this keyboard as much as I do, and I hope Logitech starts shipping more of their products with Linux compatibility !
Or at least throwing some documentation online so we don't have to reverse engineer these things all the time :-)
Enjoy !
Attached is a proof of concept that I keep running all the time. It slowly, gradually makes the backlight color change from blue to red and back.
This open source Linux driver outperforms the proprietary windows driver because it enables continuously changing the backlight color in addition to setting just one, fixed color.
You can find it here: http://code.google.com/p/logitech-keyboard-change-color/downloads/list
The most interesting line of code (MILOC) is this one:
int written = usb_control_msg(handle, CONTROLFLAGS, 0x00000009, 0x00000307, 0x00000000, buffer, 0x00000005, 5000);
where:
- handle is a pointer to the (properly initialized) USB device 046d:c22b
- #define CONTROLFLAGS 0x21 hold the RequestTypeReservedBits (as per the USB specs)
- unsigned char buffer [] = {0x07, 0x00, 0x00, 0x00, 0xFF}; is sent to the keyboard where:
- buffer[1] determines the led color (between 0x00 = blue and 0xFF = red)
- buffer[4] determines the led intensity (between 0x00 = off and 0xFF = maximal)
I hope you enjoy this keyboard as much as I do, and I hope Logitech starts shipping more of their products with Linux compatibility !
Or at least throwing some documentation online so we don't have to reverse engineer these things all the time :-)
Enjoy !
zondag 17 april 2011
Abonneren op:
Posts (Atom)