Apparently the problem is with the following LJ code:
# let's authenticate.
#
# if wsse information is supplied, use it.
# if not, fall back to digest.
my $wsse = $r->header_in('X-WSSE');
my $nonce_dup;
my $u = $wsse ? auth_wsse($wsse, \$nonce_dup) : LJ::auth_digest($r);
return respond( $r, 401, "Authentication failed for this AtomAPI request.")
unless $u;
return respond( $r, 401, "Authentication failed for this AtomAPI request.")
if $nonce_dup && $action && $action ne 'post';
I gather, last two lines causing my editing to fail autentication. What I don't understand, what makes auth_wsse set nonce_dup to 1. I'm sending completely different nonces and that should not trigger replay attack protection.
Am I missing something?
Included are HTTP headers from successful and unsuccessfull authentication. Sample perlcode is included too.
Works fine:
POST /interface/atom/post HTTP/1.1
TE: deflate,gzip;q=0.3
Connection: TE, close
Accept: application/x.atom+xml, application/xml, text/xml, */*
Authorization: WSSE profile="UsernameToken"
Host: www.livejournal.com
User-Agent: XML::Atom/0.25
Content-Length: 520
Content-Type: application/x.atom+xml
X-WSSE: UsernameToken Username="testtestdbg", PasswordDigest="cUmI/efFdXMuKYMWu7
W4z/XWOpQ=", Nonce="uNGamaE2eXMH/CDqZx0HC/5G2hU=", Created="2007-12-09T23:00:57Z
"
Fails:
GET /interface/atom/edit/20 HTTP/1.1
TE: deflate,gzip;q=0.3
Connection: TE, close
Accept: application/x.atom+xml, application/xml, text/xml, */*
Authorization: WSSE profile="UsernameToken"
Host: www.livejournal.com
User-Agent: XML::Atom/0.25
X-WSSE: UsernameToken Username="testtestdbg", PasswordDigest="Zqb83KaylsYLWTOe6V
Qci1gqgyg=", Nonce="SDzOEeOuTgXvb/lDfc/F1E7oHfY=", Created="2007-12-09T23:00:58Z
"
Perl code:
my $uname = 'testtestdbg';
my $pwd = 'XXXXXXXX'; # edited, the real password is actually used
my $puri = 'http://www.livejournal.com/interface/atom/post';
my $api = XML::Atom::Client->new;
$api->username($uname);
$api->password($pwd);
my $entry = XML::Atom::Entry->new;
$entry->title("have a nice day");
my $content = XML::Atom::Content->new(
Body => "lorem ipsum ...",
);
$entry->content($content);
my $euri = $api->createEntry($puri, $entry);
if ($euri) {
print "$euri\n";
} else {
print $api->errstr, "\n";
exit;
}
my $entry = $api->getEntry($euri);
if ($entry) {
print "$entry\n";
} else {
print $api->errstr, "\n";
}