1*** Settings ***
2Documentation    Test Redfish service root login security.
3
4Resource         ../../lib/resource.robot
5Resource         ../../lib/bmc_redfish_resource.robot
6Resource         ../../lib/openbmc_ffdc.robot
7
8Test Teardown    FFDC On Test Case Fail
9Test Setup       Printn
10
11*** Variables ***
12
13${LOGIN_SESSION_COUNT}   ${50}
14
15&{header_requirements}  Strict-Transport-Security=max-age=31536000; includeSubdomains; preload
16...                     X-Frame-Options=DENY
17...                     Pragma=no-cache
18...                     Cache-Control=no-Store,no-Cache
19...                     Content-Security-Policy=default-src 'none'; img-src 'self' data:; font-src 'self'; style-src 'self'; script-src 'self'; connect-src 'self' wss:; form-action 'none'; frame-ancestors 'none'; object-src 'none'; base-uri 'none'
20...                     X-XSS-Protection=1; mode=block
21...                     X-Content-Type-Options=nosniff
22
23*** Test Cases ***
24
25Redfish Login With Invalid Credentials
26    [Documentation]  Login to BMC web using invalid credential.
27    [Tags]  Redfish_Login_With_Invalid_Credentials
28    [Template]  Login And Verify Redfish Response
29
30    # Username                Password               Expect status
31    ${OPENBMC_USERNAME}       deadpassword           InvalidCredentialsError
32    groot                     ${OPENBMC_PASSWORD}    InvalidCredentialsError
33    ${EMPTY}                  ${OPENBMC_PASSWORD}    SessionCreationError
34    ${OPENBMC_USERNAME}       ${EMPTY}               SessionCreationError
35    ${EMPTY}                  ${EMPTY}               SessionCreationError
36
37
38Redfish Login Using Unsecured HTTP
39    [Documentation]  Login to BMC web through http unsecured.
40    [Tags]  Redfish_Login_Using_Unsecured_HTTP
41
42    Create Session  openbmc  http://${OPENBMC_HOST}
43    ${data}=  Create Dictionary
44    ...  UserName=${OPENBMC_USERNAME}  Password=${OPENBMC_PASSWORD}
45
46    ${headers}=  Create Dictionary  Content-Type=application/json
47
48    Run Keyword And Expect Error  *Connection refused*
49    ...  POST On Session  openbmc  /redfish/v1/SessionService/Sessions
50    ...  data=${data}  headers=${headers}
51
52
53Redfish Login Using HTTPS Wrong Port 80 Protocol
54    [Documentation]  Login to BMC web through wrong protocol port 80.
55    [Tags]  Redfish_Login_Using_HTTPS_Wrong_Port_80_Protocol
56
57    Create Session  openbmc  https://${OPENBMC_HOST}:80
58    ${data}=  Create Dictionary
59    ...  UserName=${OPENBMC_USERNAME}  Password=${OPENBMC_PASSWORD}
60
61    ${headers}=  Create Dictionary  Content-Type=application/json
62
63    Run Keyword And Expect Error  *Connection refused*
64    ...  POST On Session  openbmc  /redfish/v1/SessionService/Sessions
65    ...  data=${data}  headers=${headers}
66
67
68Create Multiple Login Sessions And Verify
69    [Documentation]  Create 50 login instances and verify.
70    [Tags]  Create_Multiple_Login_Sessions_And_Verify
71    [Teardown]  Run Keyword And Ignore Error  Multiple Session Cleanup
72
73    Redfish.Login
74    # Example:
75    #    {
76    #      'key': 'L0XEsZAXpNdF147jJaOD',
77    #      'location': '/redfish/v1/SessionService/Sessions/qWn2JOJSOs'
78    #    }
79    ${saved_session_info}=  Get Redfish Session Info
80
81    # Sessions book keeping for cleanup once done.
82    ${session_list}=  Create List
83    Set Test Variable  ${session_list}
84
85    Repeat Keyword  ${LOGIN_SESSION_COUNT} times  Create New Login Session
86
87    # Update the redfish session object with the first login key and location
88    # and verify if it is still working.
89    Redfish.Set Session Key  ${saved_session_info["key"]}
90    Redfish.Set Session Location  ${saved_session_info["location"]}
91    Redfish.Get  ${saved_session_info["location"]}
92
93
94Attempt Login With Expired Session
95    [Documentation]  Authenticate to redfish, then log out and attempt to
96    ...   use the session.
97    [Tags]  Attempt_Login_With_Expired_Session
98
99    Redfish.Login
100    ${saved_session_info}=  Get Redfish Session Info
101    Redfish.Logout
102
103    # Attempt login with expired session.
104    # By default 60 minutes of inactivity closes the session.
105    Redfish.Set Session Key  ${saved_session_info["key"]}
106    Redfish.Set Session Location  ${saved_session_info["location"]}
107
108    Redfish.Get  ${saved_session_info["location"]}  valid_status_codes=[${HTTP_UNAUTHORIZED}]
109
110
111Login And Verify HTTP Response Header
112    [Documentation]  Login and verify redfish HTTP response header.
113    [Tags]  Login_And_Verify_HTTP_Response_Header
114
115    # Example of HTTP redfish response header.
116    # Strict-Transport-Security: max-age=31536000; includeSubdomains; preload
117    # X-Frame-Options: DENY
118    # Pragma: no-cache
119    # Cache-Control: no-Store,no-Cache
120    # Content-Security-Policy: default-src 'self'; img-src 'self' data:
121    # X-XSS-Protection: 1; mode=block
122    # X-Content-Type-Options: nosniff
123
124    Rprint Vars  header_requirements  fmt=1
125
126    Redfish.Login
127    ${resp}=  Redfish.Get  /redfish/v1/SessionService/Sessions
128
129    # The getheaders() method returns the headers as a list of tuples:
130    # headers:
131    #    [Strict-Transport-Security]:        max-age=31536000; includeSubdomains; preload
132    #    [X-Frame-Options]:                  DENY
133    #    [Pragma]:                           no-cache
134    #    [Cache-Control]:                    no-Store,no-Cache
135    #    [Content-Security-Policy]:          default-src 'self'; img-src 'self' data:
136    #    [X-XSS-Protection]:                 1; mode=block
137    #    [X-Content-Type-Options]:           nosniff
138    #    [X-UA-Compatible]:                  IE=11
139    #    [Content-Type]:                     application/json
140    #    [Server]:                           iBMC
141    #    [Date]:                             Tue, 16 Apr 2019 17:49:46 GMT
142    #    [Content-Length]:                   2177
143
144    ${headers}=  Key Value List To Dict  ${resp.getheaders()}
145    Rprint Vars  headers  fmt=1
146
147    Dictionary Should Contain Sub Dictionary   ${headers}  ${header_requirements}
148
149
150*** Keywords ***
151
152Login And Verify Redfish Response
153    [Documentation]  Login and verify redfish response.
154    [Arguments]   ${username}  ${password}  ${expected_response}
155
156    # Description of arguments:
157    # expected_response    Expected REST status.
158    # username             The username to be used to connect to the server.
159    # password             The password to be used to connect to the server.
160
161    # The redfish object may preserve a valid username or password from the
162    # last failed login attempt.  If we then try to login with a null username
163    # or password value, the redfish object may prefer the preserved value.
164    # Since we're testing bad path, we wish to avoid this scenario so we will
165    # clear these values.
166
167    Redfish.Set Username  ${EMPTY}
168    Redfish.Set Password  ${EMPTY}
169
170    ${msg}=  Run Keyword And Expect Error  *  Redfish.Login  ${username}  ${password}
171
172    # redfish package version <=3.1.6 default response is InvalidCredentialsError.
173    Should Contain Any   ${msg}  InvalidCredentialsError  ${expected_response}
174
175
176Create New Login Session
177    [Documentation]  Multiple login session keys.
178
179    Redfish.Login
180    ${session_info}=  Get Redfish Session Info
181
182    # Append the session location to the list.
183    # ['/redfish/v1/SessionService/Sessions/uDzihgDecs',
184    #  '/redfish/v1/SessionService/Sessions/PaHF5brPPd']
185    Append To List  ${session_list}  ${session_info["location"]}
186
187
188Multiple Session Cleanup
189    [Documentation]  Do the teardown for multiple sessions.
190
191    FFDC On Test Case Fail
192
193    FOR  ${item}  IN  @{session_list}
194      Redfish.Delete  ${item}
195    END
196