From 75e9476026949455c0cd384ae7ea192502af957b Mon Sep 17 00:00:00 2001 From: Shivaram Lingamneni Date: Thu, 4 Jun 2020 02:03:15 -0400 Subject: [PATCH] review fix --- docs/MANUAL.md | 19 ++++++++++--------- irc/accounts.go | 5 +++-- irc/authscript.go | 13 +++++++------ 3 files changed, 20 insertions(+), 17 deletions(-) diff --git a/docs/MANUAL.md b/docs/MANUAL.md index 17682274..7eb8f7a4 100644 --- a/docs/MANUAL.md +++ b/docs/MANUAL.md @@ -851,15 +851,16 @@ Oragono can emulate certain capabilities of the ZNC bouncer for the benefit of c Oragono can be configured to call arbitrary scripts to authenticate users; see the `auth-script` section of the config. The API for these scripts is as follows: Oragono will invoke the script with a configurable set of arguments, then send it the authentication data as JSON on the first line (`\n`-terminated) of stdin. The input is a JSON-encoded dictionary with the following keys: -* `AccountName`: this is a string during passphrase-based authentication, otherwise the empty string -* `Passphrase`: this is a string during passphrase-based authentication, otherwise the empty string -* `Certfp`: this is a string during certfp-based authentication, otherwise the empty string +* `accountName`: during passphrase-based authentication, this is a string, otherwise omitted +* `passphrase`: during passphrase-based authentication, this is a string, otherwise omitted +* `certfp`: during certfp-based authentication, this is a string, otherwise omitted +* `ip`: a string representation of the client's IP address The script must print a single line (`\n`-terminated) to its output and exit. This line must be a JSON-encoded dictionary with the following keys: -* `Success`, a boolean indicating whether the authentication was successful -* `AccountName`, a string containing the normalized account name (in the case of passphrase-based authentication, it is permissible to return the empty string or omit the value) -* `Error`, containing a human-readable description of the authentication error to be logged if applicable +* `success`, a boolean indicating whether the authentication was successful +* `accountName`, a string containing the normalized account name (in the case of passphrase-based authentication, it is permissible to return the empty string or omit the value) +* `error`, containing a human-readable description of the authentication error to be logged if applicable Here is a toy example of an authentication script in Python that checks that the account name and the password are equal (and rejects any attempts to authenticate via certfp): @@ -870,10 +871,10 @@ import sys, json raw_input = sys.stdin.readline() input = json.loads(b) -account_name = input.get("AccountName") -passphrase = input.get("Passphrase") +account_name = input.get("accountName") +passphrase = input.get("passphrase") success = bool(account_name) and bool(passphrase) and account_name == passphrase -print(json.dumps({"Success": success}) +print(json.dumps({"success": success}) ``` Note that after a failed script invocation, Oragono will proceed to check the credentials against its local database. diff --git a/irc/accounts.go b/irc/accounts.go index 08f37cfc..271dc04e 100644 --- a/irc/accounts.go +++ b/irc/accounts.go @@ -1073,7 +1073,7 @@ func (am *AccountManager) AuthenticateByPassphrase(client *Client, accountName s if config.Accounts.AuthScript.Enabled { var output AuthScriptOutput output, err = CheckAuthScript(config.Accounts.AuthScript, - AuthScriptInput{AccountName: accountName, Passphrase: passphrase}) + AuthScriptInput{AccountName: accountName, Passphrase: passphrase, IP: client.IP().String()}) if err != nil { am.server.logger.Error("internal", "failed shell auth invocation", err.Error()) return err @@ -1411,7 +1411,8 @@ func (am *AccountManager) AuthenticateByCertFP(client *Client, certfp, authzid s config := am.server.Config() if config.Accounts.AuthScript.Enabled { var output AuthScriptOutput - output, err = CheckAuthScript(config.Accounts.AuthScript, AuthScriptInput{Certfp: certfp}) + output, err = CheckAuthScript(config.Accounts.AuthScript, + AuthScriptInput{Certfp: certfp, IP: client.IP().String()}) if err != nil { am.server.logger.Error("internal", "failed shell auth invocation", err.Error()) return err diff --git a/irc/authscript.go b/irc/authscript.go index 479fbe40..4bf6bb1e 100644 --- a/irc/authscript.go +++ b/irc/authscript.go @@ -15,15 +15,16 @@ import ( // JSON-serializable input and output types for the script type AuthScriptInput struct { - AccountName string - Passphrase string - Certfp string + AccountName string `json:"accountName,omitempty"` + Passphrase string `json:"passphrase,omitempty"` + Certfp string `json:"certfp,omitempty"` + IP string `json:"ip,omitempty"` } type AuthScriptOutput struct { - AccountName string - Success bool - Error string + AccountName string `json:"accountName"` + Success bool `json:"success"` + Error string `json:"error"` } // internal tupling of output and error for passing over a channel