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

Unable to use restore from backup due to missing authentication #15

Closed
dvzrv opened this issue May 4, 2024 · 5 comments · Fixed by #17
Closed

Unable to use restore from backup due to missing authentication #15

dvzrv opened this issue May 4, 2024 · 5 comments · Fixed by #17

Comments

@dvzrv
Copy link

dvzrv commented May 4, 2024

Hi! 👋

I'm using this crate in the nethsm crate and noticed that one of the endpoints that reliably fails for me is the one for restoring from backup (I always get a 400 response code).

I have already reported this in the nethsm repository, please see Nitrokey/nethsm#5 for further details.

In short, it appears as if authentication and authorization handling is missing in the relevant function:

pub fn system_restore_post(
configuration: &configuration::Configuration,
arguments: Option<crate::models::RestoreRequestArguments>,
backup_file: Option<std::vec::Vec<u8>>,
) -> Result<ResponseContent<()>, Error<SystemRestorePostError>> {
let local_var_configuration = configuration;
let local_var_client = &local_var_configuration.client;
let local_var_uri_str = format!("{}/system/restore", local_var_configuration.base_path);
let mut local_var_req_builder = local_var_client.request("POST", local_var_uri_str.as_str());
if let Some(ref local_var_user_agent) = local_var_configuration.user_agent {
local_var_req_builder = local_var_req_builder.set("user-agent", local_var_user_agent);
}
local_var_req_builder = local_var_req_builder.set("content-type", "multipart/form-data");
let local_var_resp = local_var_req_builder.call()?;
let local_var_headers = super::get_header_map(&local_var_resp);
let local_var_status = local_var_resp.status();
let mut local_var_content = vec![];
local_var_resp
.into_reader()
.read_to_end(&mut local_var_content)?;
let local_var_content_clone = local_var_content.clone();
if !local_var_status >= 400 {
let local_var_result = ResponseContent {
status: local_var_status,
content: local_var_content_clone,
entity: (),
headers: local_var_headers,
};
Ok(local_var_result)
} else {
let local_var_entity: SystemRestorePostError = serde_json::from_slice(&local_var_content)?;
let local_var_error = ResponseContent {
status: local_var_status,
content: local_var_content,
entity: local_var_entity,
headers: local_var_headers,
};
Err(Error::ResponseError(local_var_error))
}
}

Compare to:

pub fn system_reboot_post(
configuration: &configuration::Configuration,
) -> Result<ResponseContent<()>, Error<SystemRebootPostError>> {
let local_var_configuration = configuration;
let local_var_client = &local_var_configuration.client;
let local_var_uri_str = format!("{}/system/reboot", local_var_configuration.base_path);
let mut local_var_req_builder = local_var_client.request("POST", local_var_uri_str.as_str());
if let Some(ref local_var_user_agent) = local_var_configuration.user_agent {
local_var_req_builder = local_var_req_builder.set("user-agent", local_var_user_agent);
}
if let Some(ref local_var_auth_conf) = local_var_configuration.basic_auth {
let value = super::basic_auth(local_var_auth_conf);
local_var_req_builder = local_var_req_builder.set("authorization", &value);
};
let local_var_resp = local_var_req_builder.call()?;
let local_var_headers = super::get_header_map(&local_var_resp);
let local_var_status = local_var_resp.status();
let mut local_var_content = vec![];
local_var_resp
.into_reader()
.read_to_end(&mut local_var_content)?;
let local_var_content_clone = local_var_content.clone();
if !local_var_status >= 400 {
let local_var_result = ResponseContent {
status: local_var_status,
content: local_var_content_clone,
entity: (),
headers: local_var_headers,
};
Ok(local_var_result)
} else {
let local_var_entity: SystemRebootPostError = serde_json::from_slice(&local_var_content)?;
let local_var_error = ResponseContent {
status: local_var_status,
content: local_var_content,
entity: local_var_entity,
headers: local_var_headers,
};
Err(Error::ResponseError(local_var_error))
}
}

I am tracking this issue downstream in https://gitlab.archlinux.org/archlinux/signstar/-/issues/8

@robin-nitrokey
Copy link
Member

AFAIS this is caused by a missing security field for the restore endpoint in the API spec, so let’s continue the discussion in the NetHSM issue.

robin-nitrokey added a commit that referenced this issue May 6, 2024
This patch fixes the API spec to add authentication to the POST
/system/restore endpoint.

Fixes: #15
@robin-nitrokey
Copy link
Member

This should now work both for the unauthenticated/complete restore and the authenticated/partial restore. Please report back if there are still issues with it.

@dvzrv
Copy link
Author

dvzrv commented Jul 16, 2024

Oof, I was under the impression, that this has already been added in a released version of nethsm-sdk-rs.

I'm currently testing on the actual hardware but am still running into this issue unfortunately.

@dvzrv
Copy link
Author

dvzrv commented Jul 16, 2024

Alright, after using a88b461 I am now able to do restore from backup on an already provisioned system.
However, for an unprovisioned system it does not yet work (still status code 400).

(I have sent test cases, wireshark dumps and shell logs out of band).

@robin-nitrokey
Copy link
Member

AFAIS the unprovisioned case has now been fixed too so this is really resolved.

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

Successfully merging a pull request may close this issue.

2 participants