service: switch to -network flag for certfp and sasl commands
Instead of always requiring users to explicitly specify the network name, guess it from the downstream connection. Network commands are left as-is because it's not yet clear how to handle them.
This commit is contained in:
parent
64ad2164de
commit
57715d8ce2
@ -325,7 +325,7 @@ abbreviated form, for instance *network* can be abbreviated as *net* or just
|
|||||||
*default*
|
*default*
|
||||||
Currently same as *message*. This is the default behaviour.
|
Currently same as *message*. This is the default behaviour.
|
||||||
|
|
||||||
*certfp generate* [options...] <network name>
|
*certfp generate* [options...]
|
||||||
Generate self-signed certificate and use it for authentication (via SASL
|
Generate self-signed certificate and use it for authentication (via SASL
|
||||||
EXTERNAL).
|
EXTERNAL).
|
||||||
|
|
||||||
@ -333,6 +333,9 @@ abbreviated form, for instance *network* can be abbreviated as *net* or just
|
|||||||
|
|
||||||
Options are:
|
Options are:
|
||||||
|
|
||||||
|
*-network* <name>
|
||||||
|
Select a network. By default, the current network is selected, if any.
|
||||||
|
|
||||||
*-key-type* <type>
|
*-key-type* <type>
|
||||||
Private key algorithm to use. Valid values are: _rsa_, _ecdsa_ and
|
Private key algorithm to use. Valid values are: _rsa_, _ecdsa_ and
|
||||||
_ed25519_. _ecdsa_ uses the NIST P-521 curve.
|
_ed25519_. _ecdsa_ uses the NIST P-521 curve.
|
||||||
@ -340,19 +343,39 @@ abbreviated form, for instance *network* can be abbreviated as *net* or just
|
|||||||
*-bits* <bits>
|
*-bits* <bits>
|
||||||
Size of RSA key to generate. Ignored for other key types.
|
Size of RSA key to generate. Ignored for other key types.
|
||||||
|
|
||||||
*certfp fingerprint* <network name>
|
*certfp fingerprint* [options...]
|
||||||
Show SHA-1 and SHA-256 fingerprints for the certificate
|
Show SHA-1 and SHA-256 fingerprints for the certificate
|
||||||
currently used with the network.
|
currently used with the network.
|
||||||
|
|
||||||
*sasl status* <network name>
|
Options are:
|
||||||
|
|
||||||
|
*-network* <name>
|
||||||
|
Select a network. By default, the current network is selected, if any.
|
||||||
|
|
||||||
|
*sasl status* [options...]
|
||||||
Show current SASL status.
|
Show current SASL status.
|
||||||
|
|
||||||
*sasl set-plain* <network name> <username> <password>
|
Options are:
|
||||||
|
|
||||||
|
*-network* <name>
|
||||||
|
Select a network. By default, the current network is selected, if any.
|
||||||
|
|
||||||
|
*sasl set-plain* [options...] <username> <password>
|
||||||
Set SASL PLAIN credentials.
|
Set SASL PLAIN credentials.
|
||||||
|
|
||||||
*sasl reset* <network name>
|
Options are:
|
||||||
|
|
||||||
|
*-network* <name>
|
||||||
|
Select a network. By default, the current network is selected, if any.
|
||||||
|
|
||||||
|
*sasl reset* [options...]
|
||||||
Disable SASL authentication and remove stored credentials.
|
Disable SASL authentication and remove stored credentials.
|
||||||
|
|
||||||
|
Options are:
|
||||||
|
|
||||||
|
*-network* <name>
|
||||||
|
Select a network. By default, the current network is selected, if any.
|
||||||
|
|
||||||
*user create* -username <username> -password <password> [options...]
|
*user create* -username <username> -password <password> [options...]
|
||||||
Create a new soju user. Only admin users can create new accounts.
|
Create a new soju user. Only admin users can create new accounts.
|
||||||
The _-username_ and _-password_ flags are mandatory.
|
The _-username_ and _-password_ flags are mandatory.
|
||||||
|
103
service.go
103
service.go
@ -6,7 +6,6 @@ import (
|
|||||||
"crypto/sha256"
|
"crypto/sha256"
|
||||||
"crypto/sha512"
|
"crypto/sha512"
|
||||||
"encoding/hex"
|
"encoding/hex"
|
||||||
"errors"
|
|
||||||
"flag"
|
"flag"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
@ -228,13 +227,13 @@ func init() {
|
|||||||
"certfp": {
|
"certfp": {
|
||||||
children: serviceCommandSet{
|
children: serviceCommandSet{
|
||||||
"generate": {
|
"generate": {
|
||||||
usage: "[-key-type rsa|ecdsa|ed25519] [-bits N] <network name>",
|
usage: "[-key-type rsa|ecdsa|ed25519] [-bits N] [-network name]",
|
||||||
desc: "generate a new self-signed certificate, defaults to using RSA-3072 key",
|
desc: "generate a new self-signed certificate, defaults to using RSA-3072 key",
|
||||||
handle: handleServiceCertFPGenerate,
|
handle: handleServiceCertFPGenerate,
|
||||||
},
|
},
|
||||||
"fingerprint": {
|
"fingerprint": {
|
||||||
usage: "<network name>",
|
usage: "[-network name]",
|
||||||
desc: "show fingerprints of certificate associated with the network",
|
desc: "show fingerprints of certificate",
|
||||||
handle: handleServiceCertFPFingerprints,
|
handle: handleServiceCertFPFingerprints,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -242,17 +241,17 @@ func init() {
|
|||||||
"sasl": {
|
"sasl": {
|
||||||
children: serviceCommandSet{
|
children: serviceCommandSet{
|
||||||
"status": {
|
"status": {
|
||||||
usage: "<network name>",
|
usage: "[-network name]",
|
||||||
desc: "show SASL status",
|
desc: "show SASL status",
|
||||||
handle: handleServiceSASLStatus,
|
handle: handleServiceSASLStatus,
|
||||||
},
|
},
|
||||||
"set-plain": {
|
"set-plain": {
|
||||||
usage: "<network name> <username> <password>",
|
usage: "[-network name] <username> <password>",
|
||||||
desc: "set SASL PLAIN credentials",
|
desc: "set SASL PLAIN credentials",
|
||||||
handle: handleServiceSASLSetPlain,
|
handle: handleServiceSASLSetPlain,
|
||||||
},
|
},
|
||||||
"reset": {
|
"reset": {
|
||||||
usage: "<network name>",
|
usage: "[-network name]",
|
||||||
desc: "disable SASL authentication and remove stored credentials",
|
desc: "disable SASL authentication and remove stored credentials",
|
||||||
handle: handleServiceSASLReset,
|
handle: handleServiceSASLReset,
|
||||||
},
|
},
|
||||||
@ -631,8 +630,24 @@ func sendCertfpFingerprints(dc *downstreamConn, cert []byte) {
|
|||||||
sendServicePRIVMSG(dc, "SHA-512 fingerprint: "+hex.EncodeToString(sha512Sum[:]))
|
sendServicePRIVMSG(dc, "SHA-512 fingerprint: "+hex.EncodeToString(sha512Sum[:]))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func getNetworkFromFlag(dc *downstreamConn, name string) (*network, error) {
|
||||||
|
if name == "" {
|
||||||
|
if dc.network == nil {
|
||||||
|
return nil, fmt.Errorf("no network selected, -network is required")
|
||||||
|
}
|
||||||
|
return dc.network, nil
|
||||||
|
} else {
|
||||||
|
net := dc.user.getNetwork(name)
|
||||||
|
if net == nil {
|
||||||
|
return nil, fmt.Errorf("unknown network %q", name)
|
||||||
|
}
|
||||||
|
return net, nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func handleServiceCertFPGenerate(ctx context.Context, dc *downstreamConn, params []string) error {
|
func handleServiceCertFPGenerate(ctx context.Context, dc *downstreamConn, params []string) error {
|
||||||
fs := newFlagSet()
|
fs := newFlagSet()
|
||||||
|
netName := fs.String("network", "", "select a network")
|
||||||
keyType := fs.String("key-type", "rsa", "key type to generate (rsa, ecdsa, ed25519)")
|
keyType := fs.String("key-type", "rsa", "key type to generate (rsa, ecdsa, ed25519)")
|
||||||
bits := fs.Int("bits", 3072, "size of key to generate, meaningful only for RSA")
|
bits := fs.Int("bits", 3072, "size of key to generate, meaningful only for RSA")
|
||||||
|
|
||||||
@ -640,19 +655,15 @@ func handleServiceCertFPGenerate(ctx context.Context, dc *downstreamConn, params
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(fs.Args()) != 1 {
|
|
||||||
return errors.New("exactly one argument is required")
|
|
||||||
}
|
|
||||||
|
|
||||||
net := dc.user.getNetwork(fs.Arg(0))
|
|
||||||
if net == nil {
|
|
||||||
return fmt.Errorf("unknown network %q", fs.Arg(0))
|
|
||||||
}
|
|
||||||
|
|
||||||
if *bits <= 0 || *bits > maxRSABits {
|
if *bits <= 0 || *bits > maxRSABits {
|
||||||
return fmt.Errorf("invalid value for -bits")
|
return fmt.Errorf("invalid value for -bits")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
net, err := getNetworkFromFlag(dc, *netName)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
privKey, cert, err := generateCertFP(*keyType, *bits)
|
privKey, cert, err := generateCertFP(*keyType, *bits)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
@ -672,13 +683,16 @@ func handleServiceCertFPGenerate(ctx context.Context, dc *downstreamConn, params
|
|||||||
}
|
}
|
||||||
|
|
||||||
func handleServiceCertFPFingerprints(ctx context.Context, dc *downstreamConn, params []string) error {
|
func handleServiceCertFPFingerprints(ctx context.Context, dc *downstreamConn, params []string) error {
|
||||||
if len(params) != 1 {
|
fs := newFlagSet()
|
||||||
return fmt.Errorf("expected exactly one argument")
|
netName := fs.String("network", "", "select a network")
|
||||||
|
|
||||||
|
if err := fs.Parse(params); err != nil {
|
||||||
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
net := dc.user.getNetwork(params[0])
|
net, err := getNetworkFromFlag(dc, *netName)
|
||||||
if net == nil {
|
if err != nil {
|
||||||
return fmt.Errorf("unknown network %q", params[0])
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
if net.SASL.Mechanism != "EXTERNAL" {
|
if net.SASL.Mechanism != "EXTERNAL" {
|
||||||
@ -690,13 +704,16 @@ func handleServiceCertFPFingerprints(ctx context.Context, dc *downstreamConn, pa
|
|||||||
}
|
}
|
||||||
|
|
||||||
func handleServiceSASLStatus(ctx context.Context, dc *downstreamConn, params []string) error {
|
func handleServiceSASLStatus(ctx context.Context, dc *downstreamConn, params []string) error {
|
||||||
if len(params) != 1 {
|
fs := newFlagSet()
|
||||||
return fmt.Errorf("expected exactly one argument")
|
netName := fs.String("network", "", "select a network")
|
||||||
|
|
||||||
|
if err := fs.Parse(params); err != nil {
|
||||||
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
net := dc.user.getNetwork(params[0])
|
net, err := getNetworkFromFlag(dc, *netName)
|
||||||
if net == nil {
|
if err != nil {
|
||||||
return fmt.Errorf("unknown network %q", params[0])
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
switch net.SASL.Mechanism {
|
switch net.SASL.Mechanism {
|
||||||
@ -722,17 +739,24 @@ func handleServiceSASLStatus(ctx context.Context, dc *downstreamConn, params []s
|
|||||||
}
|
}
|
||||||
|
|
||||||
func handleServiceSASLSetPlain(ctx context.Context, dc *downstreamConn, params []string) error {
|
func handleServiceSASLSetPlain(ctx context.Context, dc *downstreamConn, params []string) error {
|
||||||
if len(params) != 3 {
|
fs := newFlagSet()
|
||||||
return fmt.Errorf("expected exactly 3 arguments")
|
netName := fs.String("network", "", "select a network")
|
||||||
|
|
||||||
|
if err := fs.Parse(params); err != nil {
|
||||||
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
net := dc.user.getNetwork(params[0])
|
if len(fs.Args()) != 2 {
|
||||||
if net == nil {
|
return fmt.Errorf("expected exactly 2 arguments")
|
||||||
return fmt.Errorf("unknown network %q", params[0])
|
|
||||||
}
|
}
|
||||||
|
|
||||||
net.SASL.Plain.Username = params[1]
|
net, err := getNetworkFromFlag(dc, *netName)
|
||||||
net.SASL.Plain.Password = params[2]
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
net.SASL.Plain.Username = fs.Arg(0)
|
||||||
|
net.SASL.Plain.Password = fs.Arg(1)
|
||||||
net.SASL.Mechanism = "PLAIN"
|
net.SASL.Mechanism = "PLAIN"
|
||||||
|
|
||||||
if err := dc.srv.db.StoreNetwork(ctx, dc.user.ID, &net.Network); err != nil {
|
if err := dc.srv.db.StoreNetwork(ctx, dc.user.ID, &net.Network); err != nil {
|
||||||
@ -744,13 +768,16 @@ func handleServiceSASLSetPlain(ctx context.Context, dc *downstreamConn, params [
|
|||||||
}
|
}
|
||||||
|
|
||||||
func handleServiceSASLReset(ctx context.Context, dc *downstreamConn, params []string) error {
|
func handleServiceSASLReset(ctx context.Context, dc *downstreamConn, params []string) error {
|
||||||
if len(params) != 1 {
|
fs := newFlagSet()
|
||||||
return fmt.Errorf("expected exactly one argument")
|
netName := fs.String("network", "", "select a network")
|
||||||
|
|
||||||
|
if err := fs.Parse(params); err != nil {
|
||||||
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
net := dc.user.getNetwork(params[0])
|
net, err := getNetworkFromFlag(dc, *netName)
|
||||||
if net == nil {
|
if err != nil {
|
||||||
return fmt.Errorf("unknown network %q", params[0])
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
net.SASL.Plain.Username = ""
|
net.SASL.Plain.Username = ""
|
||||||
|
Loading…
Reference in New Issue
Block a user