1
0
mirror of https://github.com/falk-werner/webfuse synced 2026-03-02 03:40:24 +00:00

add in-protocol authentication mechanism

This commit is contained in:
Falk Werner
2023-01-22 20:53:50 +01:00
parent 9423d75021
commit 5db3b28b5a
18 changed files with 147 additions and 19 deletions

View File

@@ -418,6 +418,11 @@ public:
return (result == 0) ? 0 : -errno;
}
std::string get_credentials() override
{
return getpass("credentials: ");
}
private:
std::string get_full_path(std::string const & path)

View File

@@ -419,4 +419,11 @@ int filesystem::statfs(std::string const & path, struct statvfs * statistics)
}
}
// get credentials is handled internally
std::string filesystem::get_credentials()
{
throw std::runtime_error("not implemented");
}
}

View File

@@ -47,6 +47,7 @@ public:
int statfs(std::string const & path, struct statvfs * statistics) override;
std::string get_credentials() override;
private:
ws_server &proxy;

View File

@@ -131,5 +131,11 @@ int empty_filesystem::statfs(std::string const & path, struct statvfs * statisti
return -ENOSYS;
}
std::string empty_filesystem::get_credentials()
{
return "";
}
}

View File

@@ -39,6 +39,8 @@ public:
int rmdir(std::string const & path) override;
int statfs(std::string const & path, struct statvfs * statistics) override;
std::string get_credentials() override;
};
}

View File

@@ -48,6 +48,8 @@ public:
virtual int rmdir(std::string const & path) = 0;
virtual int statfs(std::string const & path, struct statvfs * statistics) = 0;
virtual std::string get_credentials() = 0;
};
}

View File

@@ -122,6 +122,9 @@ public:
case request_type::statfs:
fs_statfs(reader, writer);
break;
case request_type::getcreds:
fs_get_credentials(reader, writer);
break;
default:
std::cout << "unknown request: " << ((int) req_type) << std::endl;
break;
@@ -371,6 +374,13 @@ private:
}
}
void fs_get_credentials(messagereader & reader, messagewriter & writer)
{
std::string credentials = fs_.get_credentials();
writer.write_str(credentials);
}
filesystem_i & fs_;
ws_client client;
};

View File

@@ -29,6 +29,7 @@ request_type get_request_type(uint8_t value)
case static_cast<uint8_t>(request_type::rmdir): return request_type::rmdir;
case static_cast<uint8_t>(request_type::statfs): return request_type::statfs;
case static_cast<uint8_t>(request_type::utimens): return request_type::utimens;
case static_cast<uint8_t>(request_type::getcreds): return request_type::getcreds;
default:
return request_type::unknown;
}

View File

@@ -30,7 +30,8 @@ enum class request_type: uint8_t
readdir = 0x13,
rmdir = 0x14,
statfs = 0x15,
utimens = 0x16
utimens = 0x16,
getcreds =0x17
};
request_type get_request_type(uint8_t value);

View File

@@ -29,6 +29,7 @@ response_type get_response_type(request_type value)
case request_type::rmdir: return response_type::rmdir;
case request_type::statfs: return response_type::statfs;
case request_type::utimens: return response_type::utimens;
case request_type::getcreds: return response_type::getcreds;
default:
return response_type::unknown;
}

View File

@@ -31,7 +31,8 @@ enum class response_type: uint8_t
readdir = 0x93,
rmdir = 0x94,
statfs = 0x95,
utimens = 0x96
utimens = 0x96,
getcreds = 0x97
};
response_type get_response_type(request_type value);

View File

@@ -54,7 +54,7 @@ static int ws_server_callback(struct lws *wsi, enum lws_callback_reasons reason,
handler->on_receive(wsi, in, len);
break;
case LWS_CALLBACK_SERVER_WRITEABLE:
handler->on_writable();
result = handler->on_writable();
break;
default:
break;

View File

@@ -51,6 +51,7 @@ namespace webfuse
server_handler::server_handler(std::string const & auth_app, std::string const & auth_hdr)
: connection(nullptr)
, id(0)
, shutdown_requested(false)
, is_authenticated(false)
, authenticator(auth_app)
, auth_header(auth_hdr)
@@ -69,9 +70,26 @@ int server_handler::on_established(lws * wsi)
if (nullptr == connection)
{
connection = wsi;
id = 0;
if ((!is_authenticated) && (!authenticator.empty()))
{
{
messagewriter writer(request_type::getcreds);
std::lock_guard<std::mutex> lock(mut);
uint32_t id = next_id();
writer.set_id(id);
requests.emplace(std::move(writer));
}
lws_callback_on_writable(wsi);
}
return 0;
}
// already connected: refuse
return -1;
}
@@ -86,22 +104,29 @@ void server_handler::on_receive(lws * wsi, void* in, int len)
{
webfuse::messagereader reader(current_message);
uint32_t id = reader.read_u32();
reader.read_u8(); // read message type: ToDo: use it
auto const message_type = reader.read_u8(); // read message type: ToDo: use it
std::lock_guard<std::mutex> lock(mut);
auto it = pending_responses.find(id);
if (it != pending_responses.end())
if (static_cast<response_type>(message_type) == response_type::getcreds)
{
it->second.set_value(std::move(reader));
pending_responses.erase(it);
finish_authentication(wsi, std::move(reader));
}
else
{
// ToDo: log request not found
std::cout << "warning: request not found: id=" << id << std::endl;
for(auto const & entry: pending_responses)
std::lock_guard<std::mutex> lock(mut);
auto it = pending_responses.find(id);
if (it != pending_responses.end())
{
std::cout << "\t" << entry.first << std::endl;
it->second.set_value(std::move(reader));
pending_responses.erase(it);
}
else
{
// ToDo: log request not found
std::cout << "warning: request not found: id=" << id << std::endl;
for(auto const & entry: pending_responses)
{
std::cout << "\t" << entry.first << std::endl;
}
}
}
}
@@ -113,8 +138,10 @@ void server_handler::on_receive(lws * wsi, void* in, int len)
}
}
void server_handler::on_writable()
int server_handler::on_writable()
{
if (shutdown_requested) { return -1; }
webfuse::messagewriter writer(webfuse::request_type::unknown);
bool has_msg = false;
bool has_more = false;
@@ -143,6 +170,8 @@ void server_handler::on_writable()
{
lws_callback_on_writable(connection);
}
return 0;
}
void server_handler::on_closed(lws * wsi)
@@ -258,5 +287,22 @@ uint32_t server_handler::next_id()
return id;
}
void server_handler::finish_authentication(lws * wsi, messagereader reader)
{
auto const credentials = reader.read_str();
webfuse::authenticator auth(authenticator);
auto const result = auth.authenticate(credentials);
if (result)
{
is_authenticated = true;
}
else
{
shutdown_requested = true;
lws_callback_on_writable(wsi);
}
}
}

View File

@@ -25,7 +25,7 @@ public:
int on_established(lws* wsi);
void on_receive(lws * wsi, void* in, int len);
void on_writable();
int on_writable();
void on_closed(lws * wsi);
std::future<messagereader> perform(messagewriter writer);
@@ -35,9 +35,11 @@ private:
int authenticate_via_header(lws * wsi);
std::string get_auth_token(lws * wsi) const;
uint32_t next_id();
void finish_authentication(lws * wsi, messagereader reader);
struct lws * connection;
uint32_t id;
bool shutdown_requested;
std::atomic<bool> is_authenticated;
std::string authenticator;