1717import cStringIO
1818import copy
1919import json
20+ import re
21+ import base64
2022from Crypto .Hash import SHA256
2123
2224import ChainDb
@@ -435,6 +437,13 @@ def __init__(self, mempool, chaindb):
435437 self .mempool = mempool
436438 self .chaindb = chaindb
437439
440+ def help (self , params ):
441+ l = []
442+ l .append ("Available RPC calls:" )
443+ l .append ("getrawmempool - list mempool contents" )
444+ l .append ("getinfo - misc. node info" )
445+ return (l , None )
446+
438447 def getrawmempool (self , params ):
439448 l = []
440449 for k in self .mempool .pool .iterkeys ():
@@ -458,11 +467,42 @@ def __init__(self, conn, addr, server, privdata):
458467 def do_GET (self ):
459468 self .send_error (501 , "Unsupported method (%s)" % self .command )
460469
470+ def check_auth (self ):
471+ hdr = self .headers .getheader ('authorization' )
472+ if hdr is None :
473+ return None
474+
475+ m = re .search ('\s*(\w+)\s+(\S+)' , hdr )
476+ if m is None or m .group (0 ) is None :
477+ return None
478+ if m .group (1 ) != 'Basic' :
479+ return None
480+
481+ unpw = base64 .b64decode (m .group (2 ))
482+ if unpw is None :
483+ return None
484+
485+ m = re .search ('^([^:]+):(.*)$' , unpw )
486+ if m is None :
487+ return None
488+
489+ un = m .group (1 )
490+ pw = m .group (2 )
491+ if (un != settings ['rpcuser' ] or
492+ pw != settings ['rpcpass' ]):
493+ return None
494+
495+ return un
496+
461497 def handle_data (self ):
462498 if self .path != '/' :
463499 self .send_error (404 , "Path not found" )
464500 return
465- print "BODY" , type (self .body ), self .body
501+ username = self .check_auth ()
502+ if username is None :
503+ self .send_error (401 , "Forbidden" )
504+ return
505+
466506 try :
467507 rpcreq = json .loads (self .body )
468508 except ValueError :
@@ -508,6 +548,8 @@ def jsonrpc(self, method, params):
508548 return self .rpc .getrawmempool (params )
509549 elif method == 'getinfo' :
510550 return self .rpc .getinfo (params )
551+ elif method == 'help' :
552+ return self .rpc .help (params )
511553 return (None , {"code" :- 32601 , "message" :"method not found" })
512554
513555if __name__ == '__main__' :
@@ -537,6 +579,11 @@ def jsonrpc(self, method, params):
537579 if 'log' not in settings or (settings ['log' ] == '-' ):
538580 settings ['log' ] = None
539581
582+ if ('rpcuser' not in settings or
583+ 'rpcpass' not in settings ):
584+ print "You must set the following in config: rpcuser, rpcpass"
585+ sys .exit (1 )
586+
540587 settings ['port' ] = int (settings ['port' ])
541588 settings ['rpcport' ] = int (settings ['rpcport' ])
542589
0 commit comments