mirror of
https://github.com/clusterio/clusterio.git
synced 2026-11-11 23:04:52 +09:00
Add authentication plugin that does a simple challenge response protocol to verify that the player trying to log in is who they claim to be. The process goes as follows: 1. A player code is generated for a player that wants to log in and is displayed in-game. 2. The player code is input into the web interface and the master generates a verification code as a challenge back along with a token. 3. The player inputs the verification code in-game and is logged in to the web interface in doing so. To do the actual login the web interface polls a verify endpoint every 2 seconds until the code has either been verified or expired. The challenge comes from being unable to control the verification code and having to input it as a player logging into one of the servers in order to login. Some additional steps are taken in order to increase the difficulty for an attacker to subvert the challenge: - The login process must be started from in-game. - Generated codes are only valid for a limited timespan which is configurable and 2 minutes by default. - The verification code comes with a token that only works with one player code and verification code combo and must be provided to pass validation.
58 lines
1.5 KiB
JavaScript
58 lines
1.5 KiB
JavaScript
"use strict";
|
|
let libLink = require("@clusterio/lib/link");
|
|
let libConfig = require("@clusterio/lib/config");
|
|
|
|
|
|
class MasterConfigGroup extends libConfig.PluginConfigGroup {}
|
|
MasterConfigGroup.defaultAccess = ["master", "slave", "control"];
|
|
MasterConfigGroup.groupName = "player_auth";
|
|
MasterConfigGroup.define({
|
|
name: "code_length",
|
|
title: "Code Length",
|
|
description: "Length in characters of the generated codes.",
|
|
type: "number",
|
|
initial_value: 6,
|
|
});
|
|
MasterConfigGroup.define({
|
|
name: "code_timeout",
|
|
title: "Code Timeout",
|
|
description: "Time in seconds for the generated codes to stay valid.",
|
|
type: "number",
|
|
initial_value: 120,
|
|
});
|
|
MasterConfigGroup.finalize();
|
|
|
|
module.exports = {
|
|
name: "player_auth",
|
|
title: "Player Auth",
|
|
description: "Provides authentication to the cluster via logging into a Factorio server.",
|
|
masterEntrypoint: "master",
|
|
instanceEntrypoint: "instance",
|
|
webEntrypoint: "./web",
|
|
MasterConfigGroup,
|
|
|
|
messages: {
|
|
fetchPlayerCode: new libLink.Request({
|
|
type: "player_auth:fetch_player_code",
|
|
links: ["instance-slave", "slave-master"],
|
|
forwardTo: "master",
|
|
requestProperties: {
|
|
"player": { type: "string" },
|
|
},
|
|
responseProperties: {
|
|
"player_code": { type: "string" },
|
|
"master_url": { type: "string" },
|
|
},
|
|
}),
|
|
setVerifyCode: new libLink.Request({
|
|
type: "player_auth:set_verify_code",
|
|
links: ["instance-slave", "slave-master"],
|
|
forwardTo: "master",
|
|
requestProperties: {
|
|
"player": { type: "string" },
|
|
"verify_code": { type: "string" },
|
|
},
|
|
}),
|
|
},
|
|
};
|