Bug #72149 Empty Password in Configuration File leads to errors
Submitted: 27 Mar 2014 23:47 Modified: 23 May 2014 4:07
Reporter: Jess Balint Email Updates:
Status: Closed Impact on me:
None 
Category:MySQL Fabric Severity:S3 (Non-critical)
Version:1.4.2 OS:Any
Assigned to: CPU Architecture:Any

[27 Mar 2014 23:47] Jess Balint
Description:
Given the following configuration, with an empty password:
[protocol.xmlrpc]
address = localhost:32274
threads = 5
user = admin
password = 
disable_authentication = no
realm = MySQL Fabric

The `users` table has NULL for the password. When trying to authenticate, the following code is invoked:

            ha1 = user.password_hash                                                                                                                                                                                                           
            ha2 = hashfunc('POST' + ':' + self.rpc_paths[1]).hexdigest()                                                                                                                                                                       
            if 'qop' in attrs and attrs['qop'] in ('auth', 'auth-int'):                                                                                                                                                                        
                data = "{nonce}:{nc}:{cnonce}:{qop}:{ha2}".format(                                                                                                                                                                             
                    nonce=attrs['nonce'],                                                                                                                                                                                                      
                    nc=attrs['nc'],                                                                                                                                                                                                            
                    cnonce=attrs['cnonce'],                                                                                                                                                                                                    
                    qop=attrs['qop'],                                                                                                                                                                                                          
                    ha2=ha2)                                                                                                                                                                                                                   
                reqdigest = hashfunc(ha1 + ':' + data).hexdigest()                                                                                                                                                                             
            else:                                                                                                                                                                                                                              
                kd = hashfunc(ha1 + ':' + nonce + ':' + ha2).hexdigest()                                                                                                                                                                       

ha1 is null/None and causes on error when it's concat'd to ':'.

If I attempt to execute a command, the following error shows on the console:
----------------------------------------
Exception happened during processing of request from ('127.0.0.1', 45666)
Traceback (most recent call last):
  File "/usr/lib/python2.7/SocketServer.py", line 593, in process_request_thread
    self.finish_request(request, client_address)
  File "/home/jbalint/.local/lib/python2.7/site-packages/mysql/fabric/protocols/xmlrpc.py", line 510, in finish_request
    self.RequestHandlerClass(request, client_address, self)
  File "/home/jbalint/.local/lib/python2.7/site-packages/mysql/fabric/protocols/xmlrpc.py", line 137, in __init__
    client_address, server)
  File "/usr/lib/python2.7/SocketServer.py", line 649, in __init__
    self.handle()
  File "/usr/lib/python2.7/BaseHTTPServer.py", line 340, in handle
    self.handle_one_request()
  File "/usr/lib/python2.7/BaseHTTPServer.py", line 328, in handle_one_request
    method()
  File "/home/jbalint/.local/lib/python2.7/site-packages/mysql/fabric/protocols/xmlrpc.py", line 193, in do_POST
    reqdigest = hashfunc(ha1 + ':' + data).hexdigest()
TypeError: unsupported operand type(s) for +: 'NoneType' and 'str'
----------------------------------------

If I don't specify a password (hit enter at the prompt), I get an error back from the client:
~/sw/fabric-core-trunk% mysqlfabric manage stop
Password for admin: 
Traceback (most recent call last):
  File "/home/jbalint/.local/bin/mysqlfabric", line 427, in <module>
    main()
  File "/home/jbalint/.local/bin/mysqlfabric", line 410, in main
    fire_command(cmd, *cargs)
  File "/home/jbalint/.local/bin/mysqlfabric", line 343, in fire_command
    result = command.dispatch(*(command.append_options_to_args(args)))
  File "/home/jbalint/.local/lib/python2.7/site-packages/mysql/fabric/command.py", line 356, in dispatch
    status = self.client.dispatch(self, *args)
  File "/home/jbalint/.local/lib/python2.7/site-packages/mysql/fabric/protocols/xmlrpc.py", line 717, in dispatch
    return getattr(self, reference)(*args)
  File "/usr/lib/python2.7/xmlrpclib.py", line 1224, in __call__
    return self.__send(self.__name, args)
  File "/usr/lib/python2.7/xmlrpclib.py", line 1578, in __request
    verbose=self.__verbose
  File "/home/jbalint/.local/lib/python2.7/site-packages/mysql/fabric/protocols/xmlrpc.py", line 656, in request
    result = opener.open(req)
  File "/usr/lib/python2.7/urllib2.py", line 410, in open
    response = meth(req, response)
  File "/usr/lib/python2.7/urllib2.py", line 523, in http_response
    'http', request, response, code, msg, hdrs)
  File "/usr/lib/python2.7/urllib2.py", line 442, in error
    result = self._call_chain(*args)
  File "/usr/lib/python2.7/urllib2.py", line 382, in _call_chain
    result = func(*args)
  File "/usr/lib/python2.7/urllib2.py", line 1085, in http_error_401
    host, req, headers)
  File "/usr/lib/python2.7/urllib2.py", line 970, in http_error_auth_reqed
    return self.retry_http_digest_auth(req, authreq)
  File "/usr/lib/python2.7/urllib2.py", line 981, in retry_http_digest_auth
    resp = self.parent.open(req, timeout=req.timeout)
  File "/usr/lib/python2.7/urllib2.py", line 404, in open
    response = self._open(req, data)
  File "/usr/lib/python2.7/urllib2.py", line 422, in _open
    '_open', req)
  File "/usr/lib/python2.7/urllib2.py", line 382, in _call_chain
    result = func(*args)
  File "/usr/lib/python2.7/urllib2.py", line 1214, in http_open
    return self.do_open(httplib.HTTPConnection, req)
  File "/usr/lib/python2.7/urllib2.py", line 1187, in do_open
    r = h.getresponse(buffering=True)
  File "/usr/lib/python2.7/httplib.py", line 1045, in getresponse
    response.begin()
  File "/usr/lib/python2.7/httplib.py", line 409, in begin
    version, status, reason = self._read_status()
  File "/usr/lib/python2.7/httplib.py", line 373, in _read_status
    raise BadStatusLine(line)
httplib.BadStatusLine: ''

Wireshark shows the connection is closed after the request is sent. The client should receive an error and the server shouldn't trip over this. The server should initialize with '' as the password or error during `setup` or something else.

How to repeat:
use an empty password in the configuration
[6 Apr 2014 19:17] Mats Kindahl
Thank you for the bug report! Verified as described.
[23 May 2014 4:07] Philip Olson
Fixed as of the upcoming MySQL Utilities 1.4.3 release, and here's the changelog entry:

Any empty password definition ("password = ") in the configuration file
would emit errors.

Thank you for the bug report.