JSON-RPC calls via the command line

6,731 views
Skip to first unread message

Conley Owens

unread,
Jan 11, 2012, 3:59:21 PM1/11/12
to repo-discuss
Hi all,

I'm trying to perform a simple query via the command line using JSON-RPC

Taking what I see being sent in chrome I've tried the following and
several variants:
wget https://gerrit-review.googlesource.com/gerrit/rpc/ChangeListService
--header='Content-Type: application/json'
--post-data='{"jsonrpc":"2.0","method":"allQueryNext","params":["status:open","z",25],"id":1}'
--no-check-certificate

but I keep getting a 400 error.

What else do I need to send/change in order to get this request to work?

Thanks,
~cco3

Shawn Pearce

unread,
Jan 12, 2012, 1:15:08 PM1/12/12
to Conley Owens, repo-discuss

You are missing header "Accept: application/json". The server refuses
to reply unless the client explicitly accepts application/json.

BTW, curl is better. It understands SNI like other modern browsers and
doesn't need to ignore the SSL certificate check:

$ curl -H 'Content-Type: application/json' -H 'Accept:
application/json' --data


'{"jsonrpc":"2.0","method":"allQueryNext","params":["status:open","z",25],"id":1}'

https://gerrit-review.googlesource.com/gerrit/rpc/ChangeListService
{"jsonrpc":"2.0","id":1,"result":{"accounts":{"accounts":[{"id":1003378},...

Conley Owens

unread,
Jan 12, 2012, 1:21:37 PM1/12/12
to Shawn Pearce, repo-discuss
Thanks! worked like a charm.

I'll probably be back here with questions about json-rpc and
authentication later.

Conley Owens

unread,
Jan 13, 2012, 4:59:05 PM1/13/12
to Shawn Pearce, repo-discuss
Indeed, I have returned with questions about authentication.

I am guessing that in order to make json-rpc calls that require
authentication, I have to first go through
UserPassAuthService.authentication.

The following gives me "400: Your client has issued a malformed or
illegal request":
curl https://gerrit-review.googlesource.com/gerrit/rpc/UserPassAuthService


-H "Content-Type: application/json" -H "Accept: application/json"

--data '{"jsonrpc": "2.0", "method": "authenticate", "params":
["myuser", "mypassword"]}' -G

I have tried visiting urls that require authentication and entering
the username and password directly. That works fine. (urls like
https://gerrit-review.googlesource.com/p/gerrit)

Does anyone know what's wrong/have suggestions?

Shawn Pearce

unread,
Jan 13, 2012, 5:47:15 PM1/13/12
to Conley Owens, repo-discuss
On Fri, Jan 13, 2012 at 13:59, Conley Owens <cc...@android.com> wrote:
> Indeed, I have returned with questions about authentication.
>
> I am guessing that in order to make json-rpc calls that require
> authentication, I have to first go through
> UserPassAuthService.authentication.

It depends on the Gerrit Code Review server as to whether or not this
works. The auth.type has to be set to certain values for this service
to be enabled in the web URL space.

> The following gives me "400: Your client has issued a malformed or
> illegal request":
> curl https://gerrit-review.googlesource.com/gerrit/rpc/UserPassAuthService
> -H "Content-Type: application/json" -H "Accept: application/json"
> --data '{"jsonrpc": "2.0", "method": "authenticate", "params":
> ["myuser", "mypassword"]}' -G

UserPassAuthService is not enabled on
{android,gerrit}-review.googlesource.com. To improve security and user
privacy, we don't accept passwords directly. Passwords for Google
Accounts are only accepted on a secure path of www.google.com, which
issues special cookies for the target URL.

Right now {android,gerrit}-review.googlesource.com can only be
authenticated to by a cookie, or one of the special "HTTP Passwords"
that are generated for you.

> I have tried visiting urls that require authentication and entering
> the username and password directly.  That works fine. (urls like
> https://gerrit-review.googlesource.com/p/gerrit)

Authentication for the /p/ subdirectory from a Git client is
different. JSON-RPC request handlers won't accept the same password as
an identifier, even though conceptually both the cookie and the
password identify the user in a secure way. This is currently a
security feature. It means a stolen password only provides access to
upload new changes for review and does not grant access to score +2 or
submit through the web UI (or JSON-RPC). And just for the archives,
lost/stolen passwords can be revoked at
https://www.google.com/accounts/IssuedAuthSubTokens (also reachable
from any Google property top right menu, Account Settings, Authorizing
applications & sites).


I have two answers for you since you are interested in the
{android,gerrit}-review.googlesource.com services.

First, the only current way to authenticate with JSON-RPC is to
emulate a browser and keep track of the cookies. Right now the service
issues three cookies for a signed-in user, "gc", "gi", and "S". You
would need to login in a normal web browser then "borrow" these from
the web browser's cookie store to supply to your JSON-RPC client. When
the cookie expires, you would need to regenerate them and get new
ones. The server may also issue new "gc", "gi" or "S" cookies at any
time, and your client should update itself to use the newly issued
cookies if this happens.

To make matters more difficult, you also need to load "/" while
signed-in with cookies and parse the main HTML page. There is a JSON
block in the HTML which defines a value for xsrfToken. You also need
this value from that page and must embed it in any JSON-RPC request
that includes the "gc", "gi" and "S" cookies. This is a standard
feature of Gerrit and is designed to stop some forms of malicious XSS
attacks.

Second, I know you are a Googler. We should talk about what you are
trying to do here. Clearly Gerrit is not meeting a need, and we may
need to build out additional functionality.

Shawn Pearce

unread,
Jan 13, 2012, 6:37:57 PM1/13/12
to Conley Owens, repo-discuss
On Fri, Jan 13, 2012 at 14:47, Shawn Pearce <s...@google.com> wrote:
> Second, I know you are a Googler. We should talk about what you are
> trying to do here. Clearly Gerrit is not meeting a need, and we may
> need to build out additional functionality.

Conley and I met offline. It turns out Conley needs a version of
`gerrit review` available over HTTP. Which we already knew was a
missing feature in Gerrit.

Next week he is going to try to refactor the existing SSH
implementation to a common base class in server, and make a JSON form
of review that is more compatible with a REST notion of calling a
service. This URL would then be able to be password protected, and we
will consider accepting authentication tokens like the Git password as
an HTTP Basic (only over SSL!) credential to access this new JSON
service. This is much cleaner to automate than scraping cookies and
dealing with XSRF tokens in the payload.

Ben M

unread,
Mar 13, 2012, 3:04:49 PM3/13/12
to repo-d...@googlegroups.com, Conley Owens
I'm very interested in being able to post line-by-line comments on a review via an API. My current plan is to (ab)use the JSON RPC API to send messages to the PatchDetailService, then follow up with a gerrit review over ssh to publish them. It would be nice to not worry about authentication/cookies/scraping to use the JSON API, and also to not use a mix of API's to pull it off.

-Ben

TJ Lee

unread,
Nov 15, 2013, 4:32:27 PM11/15/13
to repo-d...@googlegroups.com, Conley Owens
Hi Shawn,

Sorry to bring up a potentially dead thread. Our security team has requested that we turn off unauthenticated Gerrit RPC access, and our current libraries are tied to an older version of Gerrit that must use the RPC library in order to retrieve the data they need, and so I am trying to use this work-around with cookies in order to avoid having to rewrite our libraries and upgrade Gerrit for the short-term.

I tried making an RPC call, specifying the GerritAccount=<the value I found in the cookie on my browser>, but I continue to get "Invalid xsrfKey in request" in the response. I read your post (that I'm replying to) and saw that you mentioned something about these three cookie keys "gc", "gi", and "S" that should be present as a JSON blob on the 'main html page'. What is this page? Did you mean the gerrit homepage?

Shawn Pearce

unread,
Nov 16, 2013, 12:12:41 AM11/16/13
to TJ Lee, repo-discuss, Conley Owens
On Fri, Nov 15, 2013 at 1:32 PM, TJ Lee <tjle...@gmail.com> wrote:
> Sorry to bring up a potentially dead thread. Our security team has requested
> that we turn off unauthenticated Gerrit RPC access, and our current
> libraries are tied to an older version of Gerrit that must use the RPC
> library in order to retrieve the data they need, and so I am trying to use
> this work-around with cookies in order to avoid having to rewrite our
> libraries and upgrade Gerrit for the short-term.

Good luck. Not sure I can help.

> I tried making an RPC call, specifying the GerritAccount=<the value I found
> in the cookie on my browser>, but I continue to get "Invalid xsrfKey in
> request" in the response.

If you are on an old Gerrit and are using the old RPC system you need
to supply an xsrfKey in the JSON object that is in the POST request
body. You can get this value by fetching / on your server and parsing
out the JavaScript blob from the middle of the HTML. Its buried in
that blob.

> I read your post (that I'm replying to) and saw
> that you mentioned something about these three cookie keys "gc", "gi", and
> "S" that should be present as a JSON blob on the 'main html page'. What is
> this page? Did you mean the gerrit homepage?

These cookies only apply on the
{android,gerrit}-review.googlesource.com environment. And I think we
stopped using "S" a while ago.
Much of this is no longer true.

>> Second, I know you are a Googler. We should talk about what you are
>> trying to do here. Clearly Gerrit is not meeting a need, and we may
>> need to build out additional functionality.

And Conley and I worked together and got what he needed. Which partly
meant some of what I said above had changed. :-)
Reply all
Reply to author
Forward
0 new messages