OAuth

OAuth is an open protocol to allow secure API authorization in a simple and standard method from desktop and web applications.

liboauth provides functionality to encode URLs and sign requests according to the OAuth standard, implemented in compatible POSIX-C.

oauth-utils is a collection1) of command-line tools implementing an OAuth consumer.

Documentation

  • liboauth doxygen - Source Code Documentation
  • oauth-tools has a built-in –help

manual pages are available for both

Download

liboauth is now maintained at http://liboauth.sf.net/ - Thanks to sourceforge.
and http://oauth.googlecode.com/svn/code/c/liboauth/ - Thanks to google.

Source

Build debian packages

git clone git://gareus.org/liboauth
cd liboauth
git branch upstream 
#make maintainer-clean
git-buildpackage
#make check
cd .. && sudo dpkg -i liboauth*.deb

git clone git://gareus.org/oauth-utils
cd oauth-utils
git branch upstream
#make maintainer-clean
git-buildpackage
#make check # connects to http://term.ie/oauth/example !
cd .. && sudo dpkg -i oauth-utils*.deb

oauthsign usage and example

Both oauthsign and oauthverify are documented in un*x manual pages. You may want to consult proof-read man oauth-utils as well.

usage examples
perform requests with fixed tokens

oauthsign -c consumer-key -C "" -t access-token -T token-secret 'http://example.org/?do=admin'
oauthsign -X -d "do=requesttoken" 'http://example.org/' consumer-key ""

debug oAuth parameters - print oauth base-string:

oauthsign -b -c consumer-key -C "" -t access-token -T token-secret 'http://example.org/?do=admin'



test server walk-through
see also example.sh below.

Get a request-token for the consumer key with consumer-secret secret from the server and save it to /tmp/test.oaf:

oauthsign -X -f /tmp/test.oaf -w -e -c key -C secret http://term.ie/oauth/example/request_token.php


Exchange this request-token for an access token and replace the token+secret in /tmp/test.oaf:

oauthsign -X -f /tmp/test.oaf -w http://term.ie/oauth/example/access_token.php


Perform some requests with the consumer and access token/secrets in same file:

oauthsign -x -f /tmp/test.oaf "http://term.ie/oauth/example/echo_api.php?method=foo%20bar&bar=baz"
oauthsign -x -f /tmp/test.oaf -d method=foo%20bar -d "bar=baz &test%" --post http://term.ie/oauth/example/echo_api.php



output of oauthsign –help

oauthsign - command line utilities for oauth
Usage: ./src/oauthsign [OPTION]... URL [CKey] [CSec] [TKey] [Tsec]
Options:
  -h, --help                  display this help and exit
  -V, --version               output version information and exit
  -q, --quiet, --silent       inhibit usual output
  -v, --verbose               print more information
  --no-warn                   dont print any warnings.

  -b, --base-string           print OAuth base-string and exit
  -B, --base-url              print OAuth base-URL and exit
  -r, --request <type>        HTTP request type (HEAD, PUT, POST, GET [default],..)
  -p, --post                  same as -r POST
  -d, --data <key>[=<val>]    add url query parameters.
  -m, --signature-method <m>  oauth signature method (PLAINTEXT,
                              RSA-SHA1, HMAC-SHA1 [default])

  -c, --CK, --consumer-key    <text>
  -C, --CS, --consumer-secret <text>
  -t, --TK, --token-key       <text>
  -T, --TS, --token-secret    <text>

  -a, --callback <url>        specify oauth_callback url (or 'oob') // 1.0 Rev A
  -A, --verifier <text>       specify oauth_verifier // 1.0 Rev A

  -f, --file <filename>       read tokens and secrets from config-file
  -w                          write tokens to config-file
  -F <filename>               set config-file name w/o reading the file.
  -x                          make HTTP request and return the replied content
  -X                          make HTTP request and parse the reply for tokens
                              use '-X -w' to request and store tokens.
  --dry-run                   take no real actions (with -x, -w or -X)
  -e, --erase-tokens          clear [access|request] tokens.
  -E, --erase-all             wipe all tokens and reset method to HMAC-SHA1.
  --erase-consumer-key        unset consumer-key
  --erase-consumer-secret     unset consumer-secret
  --erase-token-key           unset token-key
  --erase-token-secret        unset token-secret

  The position of parameters -d, -f, -F, -e, -E and all tokens matters!

  Tokens are read from file at the moment the -f option is parsed overriding
  the current value(s). Optional trailing key/secret params are parsed last.
  eg.
    '-f config.txt -e -C secret -F out.txt -w' reads the settings from file,
  then deletes the access/request tokens and finally overrides the consumer-
  secret. Only the consumer-key is left from config.txt and will be saved
  to out.txt along with the new secret. If -X is given and the HTTP request
  succeeds, the received token and secret will be stored as well.

  The request URL is constructed by first parsing all query-parameters from
  the URL; then -d parameters are added, and finally oauth_XYZ params
  appended.

doc/example.sh from oauth-utils

#!/bin/bash

CONFIGFILE=${1:-"./oauthconf"}

OAUTHSIGN=./src/oauthsign
if ! test -x $OAUTHSIGN; then
  OAUTHSIGN=../src/oauthsign
fi
if ! test -x $OAUTHSIGN; then
  OAUTHSIGN=$(which oauthsign)
fi
if ! test -x $OAUTHSIGN; then
  echo " oauthsign executable not found."
  exit 1
fi

# default config
OPT=""
CONKEY="key"
CONSEC="secret"
BASEURL="http://term.ie/oauth/example/"
DOPARAM=""
RQT="request_token.php"
ACT="access_token.php"
#AUT="authenticate.php?"
TST="echo_api.php"
TSQ="?method=foo%20bar&bar=baz"

#TODO: make these into config files and different tests.
if [ 1 == 0 ]; then     # test PLAINTEXT signature
  OPT="-m PLAINTEXT"
elif [ 1 == 0 ]; then   # test RSA-SHA1 signature
# NOTE: the way RSA-keys are passed to oauthsign
# will change in the future.
# so far oauthsign want a public key as CONSUMER SECRET
# and oauthverfiy expects a private key..
  OPT="-v -m RSA-SHA1"
  CONSEC="-----BEGIN PRIVATE KEY-----
MIICdgIBADANBgkqhkiG9w0BAQEFAASCAmAwggJcAgEAAoGBALRiMLAh9iimur8V
A7qVvdqxevEuUkW4K+2KdMXmnQbG9Aa7k7eBjK1S+0LYmVjPKlJGNXHDGuy5Fw/d
7rjVJ0BLB+ubPK8iA/Tw3hLQgXMRRGRXXCn8ikfuQfjUS1uZSatdLB81mydBETlJ
hI6GH4twrbDJCR2Bwy/XWXgqgGRzAgMBAAECgYBYWVtleUzavkbrPjy0T5FMou8H
X9u2AC2ry8vD/l7cqedtwMPp9k7TubgNFo+NGvKsl2ynyprOZR1xjQ7WgrgVB+mm
uScOM/5HVceFuGRDhYTCObE+y1kxRloNYXnx3ei1zbeYLPCHdhxRYW7T0qcynNmw
rn05/KO2RLjgQNalsQJBANeA3Q4Nugqy4QBUCEC09SqylT2K9FrrItqL2QKc9v0Z
zO2uwllCbg0dwpVuYPYXYvikNHHg+aCWF+VXsb9rpPsCQQDWR9TT4ORdzoj+Nccn
qkMsDmzt0EfNaAOwHOmVJ2RVBspPcxt5iN4HI7HNeG6U5YsFBb+/GZbgfBT3kpNG
WPTpAkBI+gFhjfJvRw38n3g/+UeAkwMI2TJQS4n8+hid0uus3/zOjDySH3XHCUno
cn1xOJAyZODBo47E+67R4jV1/gzbAkEAklJaspRPXP877NssM5nAZMU0/O/NGCZ+
3jPgDUno6WbJn5cqm8MqWhW1xGkImgRk+fkDBquiq4gPiT898jusgQJAd5Zrr6Q8
AO/0isr/3aa6O6NLQxISLKcPDk2NOccAfS/xOtfOz4sJYM3+Bs4Io9+dZGSDCA54
Lw03eHTNQghS0A==
-----END PRIVATE KEY-----"
fi

# read config file - override above settings
if [ -e $CONFIGFILE ]; then
 . $CONFIGFILE
fi

echo " --- oauthsign test and example"
echo " --- connecting to $BASEURL"

TOKENFILE=`mktemp /tmp/oauth.XXXXXXXXXX` || exit 1

function cleanup {
  rm $TOKENFILE
}
trap cleanup EXIT

echo " +++ getting request token.."
$OAUTHSIGN -X $OPT -f $TOKENFILE -w -e -c "$CONKEY" -C "$CONSEC" \
    "${BASEURL}${DOPARAM}${RQT}" \
    || ( echo " !!! no request token returned."; exit 1;) || exit 1;

if [ -n "$AUT" ]; then
  REQTOK=$(cat $TOKENFILE | awk '/oauth_token_key=(.*)/{ print substr($1,17);}')
  echo " +++ Authorization."
  echo "visit: ${BASEURL}${DOPARAM}${AUT}&oauth_token=${REQTOK}"
  echo -n "to authorize this request token and press enter.."
  read
  echo
fi

echo " +++ exchanging request token for access token"
$OAUTHSIGN -X $OPT -f $TOKENFILE -w --quiet "${BASEURL}${DOPARAM}${ACT}" \
    || ( echo " !!! token exchange failed"; exit 1;) || exit 1;

echo " +++ making test request.."
$OAUTHSIGN -x $OPT -f $TOKENFILE "${BASEURL}${TST}${TSQ}" \
    || ( echo " !!! test request failed"; exit 1;) || exit 1

#echo " +++ and another one with parameter-arrays"
#$OAUTHSIGN -x -f $TOKENFILE -d "foo=bar bar" \
#    -d 'bar[1]=foo&%bar' -d 'bar[0]=bar#+b a r' --post \
#    "${BASEURL}${TST}" \
#    || ( echo " !!! test request failed"; exit 1;) || exit 1

exit 0

Note: As shown in above example RSA-keys can currently be given instead of a consumer-secret (public-key for oauthsign, private-key for oauthverify). This is going to change. Future versions may use –rsa-private, –rsa-public and also provide for reading the key from file.

oauthverify usage and example

oauthverify is the counter-part and very similar to oauthsign: It parses all request-parameters (those appended to the URL after a '?' and the ones given to oauthverify with -d command line option) one of which must be the oauth_signature to verify.

To recalculate the signature the consumer (and token) secrets must be specified (fi. -C and -T) or read from file. If a consumer-key, token-key or signature-method is set (eg. -c or -t, -m), they're required to match the ones in the parsed request-parameters. You can use –erase-consumer-key etc. to relax such a requirement when reading tokens along with the secrets from a file.

If the signature is correct and if the consumer/token key matches the given parameters (if any) oauthverify exits with a status code indicating success and prints the parsed request-parameters formatted as POST parameters (more output options to come: –print0 or -0, JSON is the contender)

Note that oauthverify does not keep track of consumers, token-mappings, timestamps and nonce (never more than once) identifiers. If the signature matches it prints them for others to use.

oauthverify -C secret `oauthsign -c key -C secret http://example.org`

Resources

1) so far there's only oauthsign, oauthverify and an example shell script. other utils eg. oauthrawpost are in the making. see also mediamatic-picnic OAuth tools
 
oss/oauth/start.txt · Last modified: 23.12.2011 21:26 (external edit)