Bitcoin Forum
December 11, 2017, 12:47:19 AM *
News: Latest stable version of Bitcoin Core: 0.15.1  [Torrent].
 
   Home   Help Search Donate Login Register  
Pages: 1 2 3 4 [All]
  Print  
Author Topic: JSON-RPC password  (Read 26322 times)
satoshi
Founder
Sr. Member
*
qt
Offline Offline

Activity: 364


View Profile
July 18, 2010, 08:49:22 PM
 #1

I uploaded to SVN my changes to add a password to JSON-RPC.  If you're set up to build, please test it.

The -server switch is replaced with -rpcpw=<password>, which is also used with bitcoind.
bitcoin -rpcpw=<password>    -- runs with JSON-RPC port open
bitcoind -rpcpw=<password>   -- daemon with password

If you have a better idea for the switch name, let me know, but keep in mind there will eventually be a password for encrypting the database too.  I'm not sure but I think they may want to use different passwords for the two.

It gives a warning if you don't set a password.

All commands now require the password as the first parameter.  It'll tell you that if you run "bitcoind help".

The central code:

  // Check password
  if (params.size() < 1 || params[0].type() != str_type)
      throw runtime_error("First parameter must be the password.");
  if (params[0].get_str() != strRPCPassword)
  {
      if (strRPCPassword.size() < 15)
          Sleep(50);
      begin = strRequest.end();
      printf("ThreadRPCServer incorrect password attempt\n");
      throw runtime_error("Incorrect password.");
  }

Any comments on these decisions?

1) if (strRPCPassword.size() < 15) Sleep(50);  -- this means if it's a short password, it'll wait 50ms after each attempt.  This might be used as a DoS attack, but I figured if it's a short password, it's more important to protect against brute force password scan.  This may tell outsiders whether the password is less than 15 characters, but less than 15 isn't all that noteworthy, most passwords are less than 15.  If you want to close the DoS possibility, just use a password 15 characters or longer.

2) begin = strRequest.end();  -- if it's a single request with multiple invocations, I throw away the rest if one has a bad password.  This is so you can't stuff it with millions of password attempts in one packet.  What do you think, is this the right thing to do?  (multiple invocation is probably almost never used anyway)

I also fixed the two duplicated commands listed in the help:

getaddressesbylabel <pw> <label>
getbalance <pw>
getblockcount <pw>
getblocknumber <pw>
getconnectioncount <pw>
getdifficulty <pw>
getgenerate <pw>
getinfo <pw>
getlabel <pw> <bitcoinaddress>
getnewaddress <pw> [label]
getreceivedbyaddress <pw> <bitcoinaddress> [minconf=1]
getreceivedbylabel <pw> <label> [minconf=1]
help <pw>
listreceivedbyaddress <pw> [minconf=1] [includeempty=false]
listreceivedbylabel <pw> [minconf=1] [includeempty=false]
sendtoaddress <pw> <bitcoinaddress> <amount> [comment] [comment-to]
setgenerate <pw> <generate> [genproclimit]
setlabel <pw> <bitcoinaddress> <label>
stop <pw>
1512953239
Hero Member
*
Offline Offline

Posts: 1512953239

View Profile Personal Message (Offline)

Ignore
1512953239
Reply with quote  #2

1512953239
Report to moderator
Advertised sites are not endorsed by the Bitcoin Forum. They may be unsafe, untrustworthy, or illegal in your jurisdiction. Advertise here.
1512953239
Hero Member
*
Offline Offline

Posts: 1512953239

View Profile Personal Message (Offline)

Ignore
1512953239
Reply with quote  #2

1512953239
Report to moderator
laszlo
Full Member
***
Offline Offline

Activity: 199


View Profile
July 19, 2010, 12:44:52 AM
 #2

I guess it's ok for remotely doing it but if your concern is that someone else on the same unix machine can steal your bitcoins this still doesn't help because they can see your command line in /proc, top, ps etc.  It could read the password on stdin or use readline or something, to guard against that particular thing at least.  Allowing it to be passed on the command line is not good, in my opinion.

Even better might be to use a key file, then you can use unix permissions to make it readable to only that user, kind of like ssh does.. then the bitcoind could have an 'authorized_keys' file with the public keys.  Anyway I don't mean to be an ass but the command line thing is just a false sense of security.

BC: 157fRrqAKrDyGHr1Bx3yDxeMv8Rh45aUet
martin
Full Member
***
Offline Offline

Activity: 150



View Profile WWW
July 19, 2010, 01:25:12 AM
 #3

I'm afraid I have to agree with laszlo here, using a certificate/keyfile would be far more secure. Saying that, thanks for adding some security to the JSON api Cheesy

satoshi
Founder
Sr. Member
*
qt
Offline Offline

Activity: 364


View Profile
July 19, 2010, 04:43:13 AM
 #4

Right, that is quite a bit better. 

Can you give me any examples of other stuff that does it that way?  (and what the command line looks like)

The main change you're talking about here is instead of -rpcpw= when you start bitcoind, you'd use a switch that specifies a text file to go and read it from, right?  (any ideas what I should name the switch?)
Gavin Andresen
Legendary
*
qt
Offline Offline

Activity: 1652


Chief Scientist


View Profile WWW
July 19, 2010, 12:02:39 PM
 #5

The Bitcoin Faucets (production and TEST) are now running with this change.

I was confused for a bit because the password is given LAST on the command line, but FIRST in the JSON-RPC params list.  I agree that reading the command-line password from a file would be more convenient and more secure.

I'll try to do some research on how other projects tackle JSON-RPC authentication.

How often do you get the chance to work on a potentially world-changing project?
Gavin Andresen
Legendary
*
qt
Offline Offline

Activity: 1652


Chief Scientist


View Profile WWW
July 19, 2010, 12:30:03 PM
 #6

The Transmission BitTorrent client does authenticated JSON-RPC; see "Remote Control" section of:
 https://trac.transmissionbt.com/wiki/ConfigurationParameters

E.g. setting.json file might look like:
Code:
{
    "rpc-enabled":1
    "rpc-authentication-required": 1,
    "rpc-password": "xxxxxxxxxx",
    "rpc-port": 9091,
    "rpc-username": "xxxxxxxxxx",
    "rpc-whitelist-enabled":1
    "rpc-whitelist":"127.0.0.1,192.168.*.*"
}

It uses HTTP 'basic' authentication (Authorization: basic base64(username:password) in the HTTP headers).


How often do you get the chance to work on a potentially world-changing project?
Gavin Andresen
Legendary
*
qt
Offline Offline

Activity: 1652


Chief Scientist


View Profile WWW
July 19, 2010, 03:20:35 PM
 #7

After further research...  I think the Transmission approach, combined with the existing "only allow connections from 127.0.0.1" is a good short/medium-term solution.

Putting the username:password in a settings.json file in the Bitcoin directory aught to work nicely (since Bitcoin can already parse JSON).  And keeping the authentication stuff off the command line and in the HTTP headers instead of the JSON request params is nice and clean.

Long term, the "right" way to do authenticated, secure JSON-RPC is with client-side certificates and https.    But that looks like it would be a lot of work to implement and a big learning curve for users to figure out how to generate client-side certificates and how to get both sides of the JSON-RPC connection using them.   And I'm not even certain a full-blown client certificate solution would solve the problem of malicious Javascript making JSON-RPC requests via XMLHttpRequests to localhost; if the user installed the client certificate in the browser (because maybe there was a nifty JSON-RPC-powered web front-end to controlling Bitcoin), would the browser automatically send the client certificate if a malicious website made requests?

How often do you get the chance to work on a potentially world-changing project?
satoshi
Founder
Sr. Member
*
qt
Offline Offline

Activity: 364


View Profile
July 19, 2010, 04:20:50 PM
 #8

So you drop a settings file in the ~/.bitcoin directory, that sounds better.  In the "no password is set" warning, it could tell you where the file is and what to do.

What is the most popular and common settings file format?

HTTP basic authentication should be considered.  In actual practice though, it's more work for web developers to figure out how to specify the password through some extra parameter in the HTTP or JSON-RPC wrapper than to just stick an extra parameter at the beginning of the parameter list.  What do you think?  Does HTTP basic authentication get us any additional benefits?  Moving it off the parameter list but then you still have to specific it in a more esoteric place I'm not sure is a net win.

I was confused for a bit because the password is given LAST on the command line, but FIRST in the JSON-RPC params list.  I agree that reading the command-line password from a file would be more convenient and more secure.
You're also confusing me, what do you mean?  Did I do something unintended?
Gavin Andresen
Legendary
*
qt
Offline Offline

Activity: 1652


Chief Scientist


View Profile WWW
July 19, 2010, 04:58:48 PM
 #9

So you drop a settings file in the ~/.bitcoin directory, that sounds better.  In the "no password is set" warning, it could tell you where the file is and what to do.
What is the most popular and common settings file format?
You ask hard questions!  Most common: probably Windows INI files, because Windows is most common OS.

I'd lobby for using JSON; it's (mostly) a subset of YAML (which is a common choice for config files), so any JSON or YAML parser will read it.
Quote
HTTP basic authentication should be considered.  In actual practice though, it's more work for web developers to figure out how to specify the password through some extra parameter in the HTTP or JSON-RPC wrapper than to just stick an extra parameter at the beginning of the parameter list.  What do you think?  Does HTTP basic authentication get us any additional benefits?
I think the only big advantage is that it keeps authentication where it belongs in the transport layer, so if, in the future, you do want to go with full-fledged HTTPS with certificates the API doesn't have to change.
Quote
I was confused for a bit because the password is given LAST on the command line, but FIRST in the JSON-RPC params list.  I agree that reading the command-line password from a file would be more convenient and more secure.
You're also confusing me, what do you mean?  Did I do something unintended?
No, I just confused "command" with "parameter", and did this:

Code:
> bitcoind help
error: First parameter must be the password.
> bitcoind <my password> help
error: unknown command: <my password>
>bitcoind help <my password>
 ... that works.


How often do you get the chance to work on a potentially world-changing project?
Vasili Sviridov
Member
**
Offline Offline

Activity: 104


View Profile WWW
July 19, 2010, 05:23:28 PM
 #10

Should bitcoind be more of a system-wide daemon? With PAM authentication and support for all system users, not just the one running it?
Like scanning /home/*/.bitcoin folders for a wallet file and provide access by both username and system password...

1JHYtsmsGq2McwGHmWayVjVtHds8rp1R5
laszlo
Full Member
***
Offline Offline

Activity: 199


View Profile
July 19, 2010, 10:53:12 PM
 #11

If you're using another JSON-RPC client that you wrote you can take care to protect the password, but using the bitcoin binary as the client and passing the password on the command line has the same issue as starting the daemon with it.  It's still visible to every user that way.

So both the server and the client mode invocation need to use the file and not accept the password on the command line.  Generally programs like this refuse to start if the mode on the file isn't 600 or something like that, because that means other users can read it.

BC: 157fRrqAKrDyGHr1Bx3yDxeMv8Rh45aUet
satoshi
Founder
Sr. Member
*
qt
Offline Offline

Activity: 364


View Profile
July 21, 2010, 12:05:20 AM
 #12

Still need to know what's the most typical settings file format on Linux.  Is there a standard file extension?  I've never seen a settings file using JSON, and it doesn't look very human friendly with everything required to be in quotes.  I think what I usually see is like:
# comment
setting=value

Is there a settings file thing in Boost?

When you're using bitcoind to issue commands from the command line as a client, can we have it get the password from the settings file then too?

Gavin pointed out I forgot to increment the column of numbers in CommandLineRPC, so the current -rpcpw= implementation doesn't work right from the command line with non-string parameters.  (JSON-RPC is fine)  Still under construction.
martin
Full Member
***
Offline Offline

Activity: 150



View Profile WWW
July 21, 2010, 12:30:26 AM
 #13

You could do worse than using yaml for the settings

satoshi
Founder
Sr. Member
*
qt
Offline Offline

Activity: 364


View Profile
July 21, 2010, 05:51:34 AM
 #14

I was researching config file formats, here's a comparison.

YAML is massive.  I'm not sure there's a lightweight easy to build library we can integrate into our project.  Seems overkill.

JSON is tempting and I'm inclined to like it, but two main sticking points:
1) No comments!  How can you have a config file where you can't comment out a line to disable it?
2) Not very user friendly to have to "quote" all the strings, including the keys, and also have to remember the comma at the end of lines.
{
    "key" : "value",
}

I suppose we could easily preprocess JSON reading the config file one line at a time, truncate the lines at any # character (and/or "//"?), concatenate them into a string and pass it to JSON, so you could go:
# comment
"key" : "value",   # still have to remember the comma
"key2" : "value",   // comment like this or both

Boost has boost::program_options.

We could read lines ourselves and feed them into a map<string, string> mapConfig.

while (!eof)
  read line
  if '#' found, truncate line
  split line at first ':' -> key, value
  mapConfig.insert(key, value)

If we use the syntax:
# comment
key : value

...and don't allow whitespace indenting before the keys, I guess we would be a subset of YAML and could switch to YAML someday if we need more complexity.

If we go with self parsed, that doesn't mean we can't use JSON on particular parameter values as needed.  If an option needs a list or more structured data, it could always parse its value as json:
key : ["item1", "item2", "item3"]

Although it has to be all on one line then.

I guess I'm leaning towards self parsed mapConfig:
# comment
key : value
lachesis
Full Member
***
Offline Offline

Activity: 210


View Profile
July 21, 2010, 06:52:43 AM
 #15

The simplest Linux config files typically have formats that look something like this:
Code:
# how often (in minutes) data is saved when all interface are offline
OfflineSaveInterval 30

# force data save when interface status changes (1 = enabled, 0 = disabled)
SaveOnStatusChange 1

# file used for logging if UseLogging is set to 1
LogFile "/var/log/vnstat.log"

# file used as daemon pid / lock file
PidFile "/var/run/vnstat.pid"
The standard extension, if there is one, is .conf. Hash (#) is the most common comment character by far. Semicolon (Wink and C-style comments crop up too.

I think a good, human-manipulatable config file that ISN'T part of the wallet would be a big step forward. There are a lot of options that are currently specified on the command line (noirc, for example, or -minimizetotray) which might be better specified in a config file.

Bitcoin Calculator | Scallion | GPG Key | WoT Rating | 1QGacAtYA7E8V3BAiM7sgvLg7PZHk5WnYc
martin
Full Member
***
Offline Offline

Activity: 150



View Profile WWW
July 21, 2010, 08:50:40 AM
 #16

Out of those options Satoshi presented, I'd go with the self parsed file with the key/value separator character being a space like lachesis suggested, especially if that's the typical format for at least one OS.

Gavin Andresen
Legendary
*
qt
Offline Offline

Activity: 1652


Chief Scientist


View Profile WWW
July 21, 2010, 12:11:10 PM
 #17

I think there's no such thing a a "typical" settings file on Linux!

I just did a quick survey of 20 .conf files in /etc on my debian system, and found:
 1 file used "key value"
 5 used "key=value"  (actually, a couple were  "key = value", allowing whitespace around the "=")
 14 did their own thing.

The 14 that did their own thing were all over the map; from one-value-per-line to "key:value" to full-blown XML.  # is
the universal comment character in the Linux world.

My vote would be for:

# comment
key1=value1


How often do you get the chance to work on a potentially world-changing project?
satoshi
Founder
Sr. Member
*
qt
Offline Offline

Activity: 364


View Profile
July 21, 2010, 04:07:57 PM
 #18

I just did a quick survey of 20 .conf files in /etc on my debian system, and found:
 1 file used "key value"
 5 used "key=value" 
Thanks for that survey!

I find "key value" a little unnatural.  There ought to be a more definite separator between key and value that suggests assignment.  The space people may just be getting lazy using their language's split function.
key=some full sentence with spaces in it.  # seems more clear
key some full sentence with spaces in it.  # than this

Allright then, lets go with self-parsed mapConfig, syntax:
# comment
key=value

file extension .conf.  What's the filename, is it ~/.bitcoin/settings.conf or ~/.bitcoin/bitcoin.conf or what?   

I think we better strip whitespace at the beginning and end of the key and the value.
# user who likes column formatted
k            = value
key         = value
longerkey =   this sentence would be this    # "this sentence would be this"
        key = value   # guess this is ok too
  nextkey = value
      right = justified

The normal syntax should be "key=value", but you can't blame people for the occasional "key = value".
satoshi
Founder
Sr. Member
*
qt
Offline Offline

Activity: 364


View Profile
July 21, 2010, 05:31:09 PM
 #19

boost::program_options has the same "key=value" format.  Gavin pointed out we can use it in a simple way as a parser without getting into all the esoteric c++ syntax like typed value extraction.  We can use more features if we want later.

Lets go ahead with HTTP basic authentication instead of password as a parameter.
Gavin Andresen
Legendary
*
qt
Offline Offline

Activity: 1652


Chief Scientist


View Profile WWW
July 22, 2010, 01:11:26 AM
 #20

I volunteered to implement this, and made good progress today.  Satoshi: I should have patches for you tomorrow.

Done: teach Bitcoin to read settings from {BITCOIN_DIR}/bitcoin.conf file, and added -conf=path_to_config_file.conf command-line option. 
Done: teach Bitcoin RPC to require HTTP Basic authentication, and reject requests with the wrong username/password.

TODO: teach Bitcoin command-line RPC to add the Authorization: header.  You won't have to give the username/password when controlling bitcoin from the command line, it'll read them from the bitcoin.conf file and Do the Right Thing.
TODO: dialog box or debug.log warning if no rpc.user/rpc.password is set, explaining how to set.
TODO: limit password guessing attempts if the rpc.password is < 15 characters long.
TODO: update the JSON-RPC wiki page

After all that is done and I've sent patches to Satoshi, I'm going to add a couple more things to bitcoin.conf :

port=   # to set the listen port (override default 8333)
rpc.port= # to set the JSON-RPC port (override default 8332)

With the existing -datadir option, that'll make it easier for me to run multiple bitcoins on one box.

How often do you get the chance to work on a potentially world-changing project?
lachesis
Full Member
***
Offline Offline

Activity: 210


View Profile
July 22, 2010, 01:27:46 AM
 #21

Excellent Gavin. We should start a list of proposed config file options in this thread.

I, for one, suggest a noirc (off by default) option and a minimizetotray option, both of which would do the same thing as the command-line switches by the same name. That'll stop the hackery of launching my Bitcoin with -minimizetotray each time. Also, maybe -server and -daemon should get similar options?

Bitcoin Calculator | Scallion | GPG Key | WoT Rating | 1QGacAtYA7E8V3BAiM7sgvLg7PZHk5WnYc
Gavin Andresen
Legendary
*
qt
Offline Offline

Activity: 1652


Chief Scientist


View Profile WWW
July 22, 2010, 01:51:40 AM
 #22

I've implemented it so that all the command-line options can also be specified in the bitcoin.conf file.

Options given on the command line override options in the conf file.  But I need to do more testing, especially with the "multiargs" options like "addnode".

How often do you get the chance to work on a potentially world-changing project?
satoshi
Founder
Sr. Member
*
qt
Offline Offline

Activity: 364


View Profile
July 22, 2010, 02:34:23 AM
 #23

TODO: dialog box or debug.log warning if no rpc.user/rpc.password is set, explaining how to set.
In many of the contexts of this RPC stuff, you can print to the console with fprintf(stdout, like this:
#if defined(__WXMSW__) && wxUSE_GUI
        MyMessageBox("Warning: rpc password is blank, use -rpcpw=<password>\n", "Bitcoin", wxOK | wxICON_EXCLAMATION);
#else
        fprintf(stdout, "Warning: rpc password is blank, use -rpcpw=<password>\n");
#endif
Gavin Andresen
Legendary
*
qt
Offline Offline

Activity: 1652


Chief Scientist


View Profile WWW
July 23, 2010, 03:11:45 PM
 #24

I've updated the RPC wiki page for how the password stuff will work in Bitcoin 0.3.3.

One nice side effect: you can prepare for the changes now; create a bitcoin.conf file with a username and password and modify your JSON-RPC code to do the HTTP Basic Authentication thing.  Old code will just ignore the .conf file and the Authorization: HTTP header.

Question for everybody:  should I add a section to the wiki page describing, in detail, how to do HTTP Basic authentication?  PHP and Python make is really easy-- just use the http://user:pass@host:port/ URL syntax.  I don't want to just duplicate the HTTP Basic authentication Wikipedia page.

How often do you get the chance to work on a potentially world-changing project?
satoshi
Founder
Sr. Member
*
qt
Offline Offline

Activity: 364


View Profile
July 23, 2010, 05:07:40 PM
 #25

Question for everybody:  should I add a section to the wiki page describing, in detail, how to do HTTP Basic authentication?  PHP and Python make is really easy-- just use the http://user:pass@host:port/ URL syntax.
Yes, I think that would be really good so each dev doesn't have to figure it out themselves.  We need a simple example for each of Python, PHP and Java importing the json-rpc library and using it to do a getinfo or something, including doing the http authentication part.
satoshi
Founder
Sr. Member
*
qt
Offline Offline

Activity: 364


View Profile
July 23, 2010, 05:14:31 PM
 #26

Gavin's changes look good.  I think everything is complete.  Here's a test build, please test it!

http://www.bitcoin.org/download/bitcoin-0.3.2.5-win32.zip
http://www.bitcoin.org/download/bitcoin-0.3.2.5-linux.tar.gz
Gavin Andresen
Legendary
*
qt
Offline Offline

Activity: 1652


Chief Scientist


View Profile WWW
July 23, 2010, 05:56:33 PM
 #27

Yes, I think that would be really good so each dev doesn't have to figure it out themselves.  We need a simple example for each of Python, PHP and Java importing the json-rpc library and using it to do a getinfo or something, including doing the http authentication part.
OK, I did Python and PHP, and I added what I know about Java.  Can somebody who has used Java JSON-RPC update the wiki page with a working example?

How often do you get the chance to work on a potentially world-changing project?
lachesis
Full Member
***
Offline Offline

Activity: 210


View Profile
July 23, 2010, 06:22:08 PM
 #28

The password definitely shouldn't be required. Also, the new code chokes on "rpcpassword=". If there's no config file, the config file doesn't contain an rpcpassword line, or it contains "rpcpassword=", the password should be disabled.

Bitcoin Calculator | Scallion | GPG Key | WoT Rating | 1QGacAtYA7E8V3BAiM7sgvLg7PZHk5WnYc
Gavin Andresen
Legendary
*
qt
Offline Offline

Activity: 1652


Chief Scientist


View Profile WWW
July 23, 2010, 06:51:34 PM
 #29

The password definitely shouldn't be required.
I strongly disagree; software should be secure by default, and running bitcoind without a password (or bitcoin -server) is definitely NOT secure.

I just don't see somebody saying "Man, Bitcoin sucks because I have to add a password to a configuration file before running it as a daemon."  I can see somebody saying "Man, Bitcoin sucks because I accidently ran it with the -server switch and somebody stole all my money."

How often do you get the chance to work on a potentially world-changing project?
satoshi
Founder
Sr. Member
*
qt
Offline Offline

Activity: 364


View Profile
July 23, 2010, 08:39:03 PM
 #30

I don't think authentication should be disabled by default if there's no conf file or the config file doesn't contain "rpcpassword", but what if it contains "rpcpassword="?

I can see both points.

What if the programmer can't figure out how to do HTTP authentication in their language (Fortran or whatever) or it's not even supported by their JSON-RPC library?  Should they be able to explicitly disable the password requirement?

OTOH, what if there's a template conf file, with
rpcpassword=  # fill in a password here

There are many systems that don't allow you to log in without a password.  This forum, for instance.  Gavin's point seems stronger.

BTW, I haven't tested it, but I hope having rpcpassword=  in the conf file is valid.  It's only if you use -server or -daemon or bitcoind that it should fail with a warning.  If it doesn't need the password, it should be fine.  Is that right?
Gavin Andresen
Legendary
*
qt
Offline Offline

Activity: 1652


Chief Scientist


View Profile WWW
July 23, 2010, 09:18:05 PM
 #31

BTW, I haven't tested it, but I hope having rpcpassword=  in the conf file is valid.  It's only if you use -server or -daemon or bitcoind that it should fail with a warning.  If it doesn't need the password, it should be fine.  Is that right?
Yes, that's right, rpcpassword is only required if you use -server or -daemon or bitcoind (I just tested to be sure).

RE: what if the programmer can't figure out how to make their legacy COBOL code do HTTP authentication?
Then I think another config file setting to explicitly turn off RPC authentication would be better than a magical "if you set a blank rpcpassword then that turns off authentication."   But I wouldn't implement that until somebody really does have a problem or until we have more than one way of doing the authentication (maybe https someday...).

lachesis: is supporting HTTP Basic Authentication a problem for you?

How often do you get the chance to work on a potentially world-changing project?
lachesis
Full Member
***
Offline Offline

Activity: 210


View Profile
July 24, 2010, 02:46:23 AM
 #32

Gavin, no. I know my way around urllib2 so that's not a problem. I would like to see the option to disable password authentication in the bitcoin.conf. We really shouldn't be protecting (advanced) users from themselves.

I was just annoyed that to even start -server (albeit on my test client), I had to edit the config file and insert a password. I can always hack my version of Bitcoin to not require a password by default if that's what I want, but I don't like the fact that bitcoin completely fails to start when I put in "rpcpassword=" with -server. I think the right way to do it would be to warn users (perhaps with a popup box if the GUI is starting) but still start the other stuff, even if the RPC server won't start.

Running with a password only marginally improves the security for a lot of applications anyway, since that password will have to sit in an httpd-readable file for my web server to execute JSON-RPC commands. The only user that's ever been hacked on my server? httpd. It is an important step for machines with multiple users, though, as is allowing the port number to be changed.

Bitcoin Calculator | Scallion | GPG Key | WoT Rating | 1QGacAtYA7E8V3BAiM7sgvLg7PZHk5WnYc
lachesis
Full Member
***
Offline Offline

Activity: 210


View Profile
July 25, 2010, 07:52:35 PM
 #33

I found what appears to be a bug: with a long enough username and password combination, the base64 encoder in bitcoind produces authorization headers that look like this:
Code:
POST / HTTP/1.1
User-Agent: json-rpc/1.0
Host: 127.0.0.1
Content-Type: application/json
Content-Length: 40
Accept: application/json
Authorization: Basic YWJiYWJiYWFiYmE6aGVsbG93b3JsZGhlbGxvd29ybGRoZWxsb3dvcmxkaGVsbG93
b3JsZGhlbGxvd29ybGRoZWxsb3dvcmxk
It inserts a newline every 64 characters, which obviously breaks the Authorization header, so commands like "bitcoin getinfo" fail. The server still works fine with properly behaving clients.

This can be solved by removing the newlines (and maybe '\r's) from result at the end of the Base64Encode function:
Code:
result.erase(std::remove(result.begin(), result.end(), '\n'), result.end());
result.erase(std::remove(result.begin(), result.end(), '\r'), result.end());
There's probably a more elegant solution, but that works for me. Here's a patch:
http://www.alloscomp.com/bitcoin/patches/bitcoin-svn-109-rpcbug-2010-07-25.patch

Bitcoin Calculator | Scallion | GPG Key | WoT Rating | 1QGacAtYA7E8V3BAiM7sgvLg7PZHk5WnYc
gazoakley
Newbie
*
Offline Offline

Activity: 12


View Profile WWW
July 25, 2010, 08:08:02 PM
 #34

Whilst putting some security in is a good idea, it appears the JSON-RPC PHP doesn't support basic HTTP authentication right now. It'd have to be hacked in. Is anyone else using similar libraries going to encounter the same problem?

Also, whilst we're on the subject is bitcoind only binding to the loopback interface?
lachesis
Full Member
***
Offline Offline

Activity: 210


View Profile
July 25, 2010, 08:30:16 PM
 #35

Whilst putting some security in is a good idea, it appears the JSON-RPC PHP doesn't support basic HTTP authentication right now. It'd have to be hacked in. Is anyone else using similar libraries going to encounter the same problem?

Also, whilst we're on the subject is bitcoind only binding to the loopback interface?
The PHP library I'm using definitely supports HTTP Basic authentication. You just have to craft the URL right:
http://username:password@localhost:8332/

Bitcoin Calculator | Scallion | GPG Key | WoT Rating | 1QGacAtYA7E8V3BAiM7sgvLg7PZHk5WnYc
gazoakley
Newbie
*
Offline Offline

Activity: 12


View Profile WWW
July 25, 2010, 08:34:53 PM
 #36

Whilst putting some security in is a good idea, it appears the JSON-RPC PHP doesn't support basic HTTP authentication right now. It'd have to be hacked in. Is anyone else using similar libraries going to encounter the same problem?

Also, whilst we're on the subject is bitcoind only binding to the loopback interface?
The PHP library I'm using definitely supports HTTP Basic authentication. You just have to craft the URL right:
http://username:password@localhost:8332/

Of course, you can specify the username and password as part of the URL Cheesy. Think a BC or two is deserved for that one Smiley - sent.
lachesis
Full Member
***
Offline Offline

Activity: 210


View Profile
July 25, 2010, 08:39:51 PM
 #37

Think a BC or two is deserved for that one Smiley - sent.
Thank you sir. Smiley

Bitcoin Calculator | Scallion | GPG Key | WoT Rating | 1QGacAtYA7E8V3BAiM7sgvLg7PZHk5WnYc
The Madhatter
Hero Member
*****
Offline Offline

Activity: 490


My avatar pic says it all


View Profile
July 25, 2010, 08:40:32 PM
 #38

If you are using PHP+JSON+CURL you can easily specify the user/pass with a curl_setopt() line. The parameter is "CURLOPT_USERPWD".

Thanks for the basic auth patch. Before the patch I was using uid/gid firewall lines to limit the bitcoind to only my special users/IPs that ran various scraps of code on crontabs. I'll likely still leave those protections in and just add in the basic http auth as well. Smiley

BitLex
Hero Member
*****
Offline Offline

Activity: 588


View Profile
July 25, 2010, 08:45:38 PM
 #39

i got some problems here too trying to get this run on PHP.
so far i had no luck, neither the wiki-sample (jsonRPCClient trying to fopen(http://username:password@localhost:8332/)), nor my curl-sample (using setopt CURLOPT_HTTPAUTH, CURLAUTH_BASIC) seem to work.

The Madhatter
Hero Member
*****
Offline Offline

Activity: 490


My avatar pic says it all


View Profile
July 25, 2010, 08:54:38 PM
 #40

Hmm.. shouldn't it be using digest auth instead of basic auth?

I usually wrap everything into SSL or IPSec anyway, but digest auth might keep noobs from getting pwned so easily. Tongue


lachesis
Full Member
***
Offline Offline

Activity: 210


View Profile
July 25, 2010, 09:00:05 PM
 #41

Digest auth is a fair bit harder to implement on both the client and the server side. It _should_ be using SSL and client certificates, but that's just a major PITA. Either that, or unix sockets.

Bitcoin Calculator | Scallion | GPG Key | WoT Rating | 1QGacAtYA7E8V3BAiM7sgvLg7PZHk5WnYc
The Madhatter
Hero Member
*****
Offline Offline

Activity: 490


My avatar pic says it all


View Profile
July 25, 2010, 09:05:43 PM
 #42

Hmm... I implemented digest auth into a custom webserver I wrote a decade ago. From what I remember, it was fairly easy. However, client support back then was rather shoddy. It has improved a lot since then. Smiley

Perhaps we could document a simple stunnel + bitcoin configuration on the wiki then? Under a section called "Securely using bitcoind from remote"?

Just offering my 2c as usual. Tongue

satoshi
Founder
Sr. Member
*
qt
Offline Offline

Activity: 364


View Profile
July 25, 2010, 09:34:29 PM
 #43

I found what appears to be a bug: with a long enough username and password combination, the base64 encoder in bitcoind produces authorization headers that look like this:
Code:
...
Authorization: Basic YWJiYWJiYWFiYmE6aGVsbG93b3JsZGhlbGxvd29ybGRoZWxsb3dvcmxkaGVsbG93
b3JsZGhlbGxvd29ybGRoZWxsb3dvcmxk
It inserts a newline every 64 characters, which obviously breaks the Authorization header, so commands like "bitcoin getinfo" fail. The server still works fine with properly behaving clients.

This can be solved by removing the newlines (and maybe '\r's) from result at the end of the Base64Encode function:
Code:
result.erase(std::remove(result.begin(), result.end(), '\n'), result.end());
result.erase(std::remove(result.begin(), result.end(), '\r'), result.end());
+1 to you for having such a long password that you found this bug.

Uploaded to SVN as rev 110.
Gavin Andresen
Legendary
*
qt
Offline Offline

Activity: 1652


Chief Scientist


View Profile WWW
July 25, 2010, 09:38:19 PM
 #44

I found what appears to be a bug: with a long enough username and password combination, the base64 encoder in bitcoind ... inserts a newline every 64 characters

Great catch!  Simpler fix is to specify the BIO_FLAGS_BASE64_NO_NL in the rpc.cpp/EncodeBase64 function:
Code:
diff --git a/rpc.cpp b/rpc.cpp
index 72bdc50..703b757 100644
--- a/rpc.cpp
+++ b/rpc.cpp
@@ -765,13 +765,14 @@ string EncodeBase64(string s)
     BUF_MEM *bptr;
 
     b64 = BIO_new(BIO_f_base64());
+    BIO_set_flags(b64, BIO_FLAGS_BASE64_NO_NL);
     bmem = BIO_new(BIO_s_mem());
     b64 = BIO_push(b64, bmem);
     BIO_write(b64, s.c_str(), s.size());
     BIO_flush(b64);
     BIO_get_mem_ptr(b64, &bptr);
 
-    string result(bptr->data, bptr->length-1);
+    string result(bptr->data, bptr->length);
     BIO_free_all(b64);
 
     return result;

How often do you get the chance to work on a potentially world-changing project?
satoshi
Founder
Sr. Member
*
qt
Offline Offline

Activity: 364


View Profile
July 25, 2010, 09:44:16 PM
 #45

i got some problems here too trying to get this run on PHP.
so far i had no luck, neither the wiki-sample (jsonRPCClient trying to fopen(http://username:password@localhost:8332/)), nor my curl-sample (using setopt CURLOPT_HTTPAUTH, CURLAUTH_BASIC) seem to work.
That's strange, didn't someone just say that was supposed to work?  (what library was he using?)  Post if you figure out what wrong.

I hope it's not going to put up this much of a fight for all PHP users.

Looks like we've got the Fortran scenario already.
satoshi
Founder
Sr. Member
*
qt
Offline Offline

Activity: 364


View Profile
July 25, 2010, 09:51:31 PM
 #46

Great catch!  Simpler fix is to specify the BIO_FLAGS_BASE64_NO_NL in the rpc.cpp/EncodeBase64 function
SVN rev 111
lachesis
Full Member
***
Offline Offline

Activity: 210


View Profile
July 25, 2010, 10:15:15 PM
 #47

That's strange, didn't someone just say that was supposed to work?  (what library was he using?)  Post if you figure out what wrong.
That was me; I'm using the library at http://jsonrpcphp.org/ (download at http://jsonrpcphp.org/download.php?file=tgz&package=light), and I can confirm that this works:
Code:
<?php
require_once 'jsonRPCClient.php';
$bitcoin = new jsonRPCClient('http://username:password@localhost:8332/');
echo 
$bitcoin->getblockcount();
?>


Thanks to gavinandresen and satoshi for fixing that bug so fast.

Bitcoin Calculator | Scallion | GPG Key | WoT Rating | 1QGacAtYA7E8V3BAiM7sgvLg7PZHk5WnYc
BitLex
Hero Member
*****
Offline Offline

Activity: 588


View Profile
July 25, 2010, 10:41:42 PM
 #48

That's strange, didn't someone just say that was supposed to work?  (what library was he using?)  Post if you figure out what wrong.
That was me; I'm using the library at http://jsonrpcphp.org/ (download at http://jsonrpcphp.org/download.php?file=tgz&package=light), and I can confirm that this works:
Code:
<?php
require_once 'jsonRPCClient.php';
$bitcoin = new jsonRPCClient('http://username:password@localhost:8332/');
echo 
$bitcoin->getblockcount();
?>


not for me, that's what i tried first, cuz it's on the wiki.
this is all i get from jsonRPCClient:
Warning: fopen(http://...@localhost:8332/) [function.fopen]: failed to open stream: HTTP request failed! HTTP/1.0 401 Authorization Required in ...\jsonRPCClient.php on line 132


also couldn't get curl to authorize yet, all i get is
..curl_error():transfer closed with 15 bytes remaining to read..
which results in a "bad json-syntax" of course

testing on php5.3.0 curl7.19.4.
and open for ideas.

lachesis
Full Member
***
Offline Offline

Activity: 210


View Profile
July 26, 2010, 12:26:27 AM
 #49

First of all, does "bitcoind getinfo" work?

Second, try to grab the attempt that jsonrpcclient.php makes with netcat (might have to install it first):

1) Stop bitcoind
2) netcat -l 8332
3) Run your client code with a modified (insecure) username and password
4) Ctrl-C netcat and post the output


Bitcoin Calculator | Scallion | GPG Key | WoT Rating | 1QGacAtYA7E8V3BAiM7sgvLg7PZHk5WnYc
BitLex
Hero Member
*****
Offline Offline

Activity: 588


View Profile
July 26, 2010, 01:13:43 AM
 #50

I'm on XP here, not sure if theres a netcat-clone available.

commandline works fine and does what it's supposed to

this works fine using <=0.3.2
Code:
require_once 'jsonRPCClient.php';
$bitcoin = new jsonRPCClient('http://localhost:8332/');
echo $bitcoin->getblockcount();


but this doesnt work using 0.3.3
Code:
require_once 'jsonRPCClient.php';
$bitcoin = new jsonRPCClient('http://username:password@localhost:8332/');
echo $bitcoin->getblockcount();


BitLex
Hero Member
*****
Offline Offline

Activity: 588


View Profile
July 26, 2010, 01:38:57 AM
 #51

Ok, i found it.  Cheesy

wiki says, create a bitcoin.conf like this:
Code:
rpcuser=anything; does not have to be a 'real' user
rpcpassword=anything
but that won't work (at least for some people, maybe windows?)

removing the ; did the job,
using # as seperator/commentor works fine.


lachesis
Full Member
***
Offline Offline

Activity: 210


View Profile
July 26, 2010, 02:27:38 AM
 #52

Ah alright. In that case, your username was actually "anything; does not have to be a 'real' user". That's why using the Bitcoin command line client worked - it used the full field for a username. I updated the wiki to remove the "; does not have to be a 'real' user" comment.

Bitcoin Calculator | Scallion | GPG Key | WoT Rating | 1QGacAtYA7E8V3BAiM7sgvLg7PZHk5WnYc
theymos
Administrator
Legendary
*
expert
Offline Offline

Activity: 2870


View Profile
July 30, 2010, 05:54:36 AM
 #53

When I upgraded from a version with switch-based passwords to the latest SVN, I ran into a problem: Bitcoin looks for the configuration file in the default "~/.bitcoin/bitcoin.conf" unless I point to any non-existent file. Example:
Code:
$ ls /home/theymos/bitcoin
addr.dat      blkindex.dat  debug.log          status.sh
bitcoin.conf  command.sh    debug.log.old.bz2  stop.sh
bitcoind      database      makefile           transfer.sh
blk0001.dat   db.log        start.sh           wallet.dat

$ ./bitcoind -datadir=/home/theymos/bitcoin -conf=/home/theymos/bitcoin/bitcoin.conf && ./bitcoind getinfo
error: You must set rpcpassword=<password> in the configuration file:
/home/theymos/.bitcoin/bitcoin.conf
If the file does not exist, create it with owner-readable-only file permissions.

$ killall bitcoind

$ ./bitcoind -datadir=/home/theymos/bitcoin -conf=/home/theymos/bitcoin/asdf.conf && ./bitcoind getinfo
bitcoin server starting
error: You must set rpcpassword=<password> in the configuration file:
/home/theymos/.bitcoin/bitcoin.conf
If the file does not exist, create it with owner-readable-only file permissions.

Warning: To use bitcoind, you must set rpcpassword=<password>
in the configuration file: /home/theymos/bitcoin/asdf.conf
If the file does not exist, create it with owner-readable-only file permissions.

Bitcoin is using the correct datadir. Hardcoding the path in util.cpp just gives me "error:getinfo" (though maybe I'm not doing it correctly). Removing the "pathConfig.is_complete()" if statement does the same thing.

I'm on Linux with glibc 2.10.1. I'm using all of the recommended dependency versions. The only dependency I changed during the upgrade was Boost, which I had to recompile to get the additional libraries that Bitcoin now uses.

1NXYoJ5xU91Jp83XfVMHwwTUyZFK64BoAD
Gavin Andresen
Legendary
*
qt
Offline Offline

Activity: 1652


Chief Scientist


View Profile WWW
July 30, 2010, 12:53:40 PM
 #54

$ ./bitcoind -datadir=/home/theymos/bitcoin -conf=/home/theymos/bitcoin/bitcoin.conf && ./bitcoind getinfo
error: You must set rpcpassword=<password> in the configuration file:
That second ./bitcoind getinfo has to be:
Code:
./bitcoind -datadir=/home/theymos/bitcoin -conf=/home/theymos/bitcoin/bitcoin.conf getinfo
... otherwise it will use the default config file and datadir.

How often do you get the chance to work on a potentially world-changing project?
fetokun
Full Member
***
Offline Offline

Activity: 126



View Profile
April 10, 2011, 12:24:15 PM
 #55

I'm getting the same error that was posted here about 1 year ago:

Quote
Warning: fopen(http://...@localhost:8332/): failed to open stream: HTTP request failed! HTTP/1.0 401 Authorization Required in /var/www/meubitcoin/src/classes/jsonRPCClient.php...

the php code:

Code:
  $bitcoind = new jsonRPCClient("http://fetokun:rcpass123@localhost:8332/", true);
  echo($bitcoind->listaccounts());

Does it mean that I'm using an outdated version of bitcoind? ( I installed from this package: http://packages.debian.org/sid/i386/bitcoind/download )

I'm starting bitcoind this way:

Code:
bitcoind -server -testnet -rpcport=8332 -rcpuser=fetokun -rcppassword=rcpass123

when I run getinfo, bitcoind returns me this:

Code:
{
    "version" : 32002,
    "balance" : 0.00000000,
    "blocks" : 13312,
    "connections" : 8,
    "proxy" : "",
    "generate" : false,
    "genproclimit" : -1,
    "difficulty" : 17.09748611,
    "hashespersec" : 0,
    "testnet" : true,
    "keypoololdest" : 1302337673,
    "paytxfee" : 0.00000000,
    "errors" : ""
}


First of all, does "bitcoind getinfo" work?

Second, try to grab the attempt that jsonrpcclient.php makes with netcat (might have to install it first):

1) Stop bitcoind
2) netcat -l 8332
3) Run your client code with a modified (insecure) username and password
4) Ctrl-C netcat and post the output



when I do what lachesis mentioned above, netcat shows me:

Code:
{"method":"listaccounts","params":[],"id":1}

Its probably something very simple that I'm forgetting about... does anyone know what?
fetokun
Full Member
***
Offline Offline

Activity: 126



View Profile
April 10, 2011, 01:29:32 PM
 #56

found the problem

All I had to do was RTFM properly =D
fetokun
Full Member
***
Offline Offline

Activity: 126



View Profile
April 15, 2011, 05:40:39 AM
 #57

Alright, this thing I'm having a problem with:

Code:
       $result1 = $rpc->getbalance($fromAccount);
    $result2 = $rpc->sendfrom($fromAccount, $toAccount, $amount);

The first line works fine and gets me:

Code:
1***** Request *****
{"method":"getbalance","params":["fetokun"],"id":1}
***** End Of request *****

***** Server response *****
{"result":3639.00000000,"error":null,"id":1}
***** End of server response *****

But the second line gets me:
Code:
Warning: fopen(http://...@localhost:8332/): failed to open stream: HTTP request failed! HTTP/1.1 500 Internal Server Error in /var/www/meubitcoin/src/classes/jsonRPCClient.php on line 132 Fatal error: Uncaught exception 'Exception' with message 'Unable to connect...

Anybody knows why?

my bitcoin.conf:

Code:
rcpallowip=127.0.0.1
rpcuser=fetokun
rpcpassword=rcpass123
rpcport=8332
server=1
testnet=1
NghtRppr
Sr. Member
****
Offline Offline

Activity: 476


View Profile
April 15, 2011, 01:50:18 PM
 #58

Code:
$result2 = $rpc->sendfrom($fromAccount, $toAccount, (float) $amount);

See if this works.
fetokun
Full Member
***
Offline Offline

Activity: 126



View Profile
April 15, 2011, 02:08:12 PM
 #59

I'll arrive home in a few hours then I'll check if that's the problem

Thanx a lot dude
fetokun
Full Member
***
Offline Offline

Activity: 126



View Profile
April 16, 2011, 11:17:52 AM
 #60

Code:
$result2 = $rpc->sendfrom($fromAccount, $toAccount, (float) $amount);

See if this works.

Now it worked! Thanx!
NghtRppr
Sr. Member
****
Offline Offline

Activity: 476


View Profile
April 16, 2011, 05:32:51 PM
 #61

Code:
$result2 = $rpc->sendfrom($fromAccount, $toAccount, (float) $amount);

See if this works.

Now it worked! Thanx!

You're welcome. The problem was that you were trying to pass $amount as a string.
Pages: 1 2 3 4 [All]
  Print  
 
Jump to:  

Sponsored by , a Bitcoin-accepting VPN.
Powered by MySQL Powered by PHP Powered by SMF 1.1.19 | SMF © 2006-2009, Simple Machines Valid XHTML 1.0! Valid CSS!