# Authentication in the Client Server Protocol

## Clear

Although this method is still supported, it is DEPRECATED and should not be used. Client authors SHOULD use another authentication method if it is available to them.

The default authentication method is known as clear, which refers to the fact that `password`s are being sent as plain-text (in the clear). Though clients have the ability to encrypt passwords in a one way hash function (MD5) and send them to the server (as `hpassword`), they are still vulnerable to replay attacks if the hashed password becomes known.

Clear authentication occurs when a `username` and either `password` or `hpassword` is passed to any client server protocol method.

## HTTP Cookies

If you specify `auth_method` with the value of cookie, you can use session cookies generated by the server in your client. To prevent against the usage of modified forms to perform actions without the consent of the user, we require the HTTP header `X-LJ-Auth` be set to cookie as well.

### Using Wget 1.9 with `auth_method=cookie` in flat protocol

    $ wget --post-data "mode=login&user=test&auth_method=cookie" --header "X-LJ-Auth: cookie" --header "Cookie: ljsession=cookieval &siteroot;/interface/flat

## Challenge / Response

Another way to authenticate your client is to build a hex digest consisting of the user's password and a challenge as issued by the server. This is currently known as `auth_method` challenge.

Essentially, you generate a challenge by issuing a blank request to the `getchallenge` method. If your method call is successful you're given:

string auth_scheme

  You can ignore this for now. By default this is the highest version of our authentication schemes, if in the future if we implement other auth schemes or change the default. In that case we'd add a new capabilities exchange: your client could say, "I know c0 and c1", and our server would then say, "Use c1, it's the best."

string challenge

  challenge is an opaque cookie, as generated by . Challenges may only be used once.

int expire_time

  expire_time is the expiration time for the challenge as measured in seconds since the Unix epoch.

int server_time

  servertime is the time of when the challenge was generated, as measured in seconds since the Unix epoch. The formula (server_time - expire_time) is the life span of the challenge, in seconds.

For your response, you then build a MD5 hex digest of the formula (challenge + MD5_hex(`password`)). To authenticate your client now, you simply send back the following 3 parameters, along with your username:

string `auth_method`

  Set to challenge

string `auth_challenge`

  The challenge issued by the server

string `auth_response`

  MD5_hex(challenge + MD5_hex(`password`))

### Sample Perl script using `getchallenge`

    use strict;
    use Fcntl;
    use XMLRPC::Lite;
    use Data::Dumper;
    use Digest::MD5 qw(md5_hex);

    my $xmlrpc = new XMLRPC::Lite;
    $xmlrpc->proxy("http://www.lj.com/interface/xmlrpc");
    my $get_chal = xmlrpc_call("LJ.XMLRPC.getchallenge");
    my $chal = $get_chal->{'challenge'};

    my $user = "test";
    my $pass = "pass";
    print "chal: $chal\n";

    my $response = md5_hex($chal . md5_hex($pass));

    my $login = xmlrpc_call('LJ.XMLRPC.login', {
            'username' => $user,
            'auth_method' => 'challenge',
            'auth_challenge' => $chal,
            'auth_response' => $response,
    });

    print Dumper($login);

    sub xmlrpc_call {
        my ($method, $req) = @_;
        my $res = $xmlrpc->call($method, $req);
        if ($res->fault) {
            print STDERR "Error:\n".
            " String: " . $res->faultstring . "\n" .
            " Code: " . $res->faultcode . "\n";
            exit 1;
        }
        return $res->result;
    }