Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Getting ServerDownOrUnreachableError with error code 401 for the password containing "$Password" #157

Open
khaderbmc opened this issue Feb 29, 2024 · 5 comments

Comments

@khaderbmc
Copy link

khaderbmc commented Feb 29, 2024

Hi Team,

I am getting serverDown or UnreachableError : Server not reachable with return code 401" for the password="$password" containing "$" .

Here is my code:

import redfish

login_host = "https://XX.XXX.XXX.XX"
login_account = "root"
login_password = "$password"

REDFISH_OBJ = redfish.redfish_client(base_url=login_host, username=login_account,
password=login_password, default_prefix='/redfish/v1')

Is there any step needed to handle passwords with "$" special character.

@mraineri
Copy link
Contributor

Not from the library's perspective. That exception occurs when the library accesses the service root to probe it prior to authenticating, so the username and password aren't even sent yet. What happens when you do this?

curl -k https://xx.xxx.xxx.xx/redfish/v1 -v

@khaderbmc
Copy link
Author

khaderbmc commented Feb 29, 2024

HI,

I am getting 401 unauthorized error. Please find the response below:

GET /2/hmc/redfish/v1/ HTTP/1.1
Host: XX.XXX.XXX.XX:8080
User-Agent: curl/7.68.0
Accept: /

  • Mark bundle as not supporting multiuse
    < HTTP/1.1 401 Unauthorized
    < Content-Length: 446
    < Content-Type: application/json
    < Www-Authenticate: Basic realm="private"
    < Date: Thu, 29 Feb 2024 17:16:42 GMT
    < Server: ocs-am437x
    <
    {
    "error": {
    "@Message.ExtendedInfo": [
    {
    "@odata.type": "/redfish/v1/$metadata#Message.v1_0_0.Message",
    "Oem": {
    "Microsoft": {
    "@odata.type": "#Ocs.v1_0_0.Message",
    "CompletionCode": "Failure",
    "Description": "Access denied"
    }
    }
    }
    ]
    }
  • Connection #0 to host XX.XXX.XX.XX left intact

But when I provide the "curl -u 'root:$password' -k -s https://XX.XXX.XXX.XX:8080/2/hmc/redfish/v1/" command with -u option I am getting the response data successfully.

@mraineri
Copy link
Contributor

Issue #152 was also root caused to be the same thing. The problem is there's a requirement in the Redfish specification that states the service root needs to be accessible without credentials. There is a patch attached in the issue to help work around it, but at this time we'd like to avoid encouraging non-conformant behaviors natively in the library. It would be good to provide this feedback to the service vendor so they can fix it.

@khaderbmc
Copy link
Author

khaderbmc commented Mar 5, 2024

Hi @mraineri ,

Thanks a lot for the response.

The workaround patch did not help as it is failing in the check for "
if resp.status != 200:
raise ServerDownOrUnreachableError("Server not reachable, "
"return code: %d" % resp.status,response=resp)
" inside the get_root_object. Since it is unthrowing unauth error 401 . I made the below changes which will create the basic auth if the response error is 401:

Please find the updated code below:

def get_root_object(self):
    """Perform an initial get and store the result"""
    try:
        resp = self.get(self.default_prefix)
    except Exception as excp:
        raise excp


   # changes to create using basic authentication Begins
    if resp.status == 401:
        auth_key = base64.b64encode(('%s:%s' % (self.get_username(), self.get_password())).encode('utf-8')).decode('utf-8')
        self.__authorization_key = 'Basic %s' % auth_key
        headers = dict()
        headers['Authorization'] = self.__authorization_key
        resp = self.get(self.default_prefix, headers)
     # changes ends

    if resp.status != 200:
        raise ServerDownOrUnreachableError("Server not reachable, " \
                                           "return code: %d" % resp.status,response=resp)

    content = resp.text

    try:
        root_data = json.loads(content)
    except:
        str = 'Service responded with invalid JSON at URI {}\n{}'.format(
            self.default_prefix, content)
        LOGGER.error(str)
        raise JsonDecodingError(str) from None

    self.root = RisObject.parse(root_data)
    self.root_resp = resp
    
    Please let me know ur thoughts or suggestions for workaround. With the above changes I am able to eshtablish the connection or fetch /redfish/v1 data.
    
    Thanks & Regards,
    Khader B Shaik 

@mraineri
Copy link
Contributor

mraineri commented Mar 5, 2024

If that works for you, great! But at this time we're not comfortable introducing this type of change in the mainline library code. The Redfish specification is very clear about the fact the service root is required to be accessible without any authorization headers. It's fairly crucial for initial discovery purposes.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants