p12 files can now be provided to the bot to authenticate as a registered user

This commit is contained in:
Matthieu Grieger 2016-07-10 20:41:51 -07:00
parent 5434077d73
commit 32167c1294
8 changed files with 89 additions and 23 deletions

View file

@ -1,6 +1,9 @@
MumbleDJ Changelog MumbleDJ Changelog
================== ==================
### July 10, 2016 -- `v3.1.0`
* File path for user `p12` certificate can now be provided for authenticating as a registered user via the `--p12` commandline flag or the `connection.user_p12` configuration value.
### July 1, 2016 -- `v3.0.11` ### July 1, 2016 -- `v3.0.11`
* Potential fix for an issue with IP SANs on PEM certs. * Potential fix for an issue with IP SANs on PEM certs.

View file

@ -116,16 +116,17 @@ USAGE:
mumbledj [global options] command [command options] [arguments...] mumbledj [global options] command [command options] [arguments...]
VERSION: VERSION:
3.0.0-alpha v3.1.0
COMMANDS: COMMANDS:
GLOBAL OPTIONS: GLOBAL OPTIONS:
--config value, -c value location of MumbleDJ configuration file (default: "$HOME/.config/mumbledj/mumbledj.yaml") --config value, -c value location of MumbleDJ configuration file (default: "/home/matthieu/.config/mumbledj/config.yaml")
--server value, -s value address of Mumble server to connect to (default: "127.0.0.1") --server value, -s value address of Mumble server to connect to (default: "127.0.0.1")
--port value, -o value port of Mumble server to connect to (default: "64738") --port value, -o value port of Mumble server to connect to (default: "64738")
--username value, -u value username for the bot (default: "MumbleDJ") --username value, -u value username for the bot (default: "MumbleDJ")
--password value, -p value password for the Mumble server --password value, -p value password for the Mumble server
--channel value, -n value channel the bot enters after connecting to the Mumble server --channel value, -n value channel the bot enters after connecting to the Mumble server
--p12 value path to user p12 file for authenticating as a registered user
--cert value, -e value path to PEM certificate --cert value, -e value path to PEM certificate
--key value, -k value path to PEM key --key value, -k value path to PEM key
--accesstokens value, -a value list of access tokens separated by spaces --accesstokens value, -a value list of access tokens separated by spaces

File diff suppressed because one or more lines are too long

View file

@ -40,6 +40,7 @@ func SetDefaultConfig() {
viper.SetDefault("connection.port", 64738) viper.SetDefault("connection.port", 64738)
viper.SetDefault("connection.password", "") viper.SetDefault("connection.password", "")
viper.SetDefault("connection.username", "MumbleDJ") viper.SetDefault("connection.username", "MumbleDJ")
viper.SetDefault("connection.user_p12", "")
viper.SetDefault("connection.insecure", false) viper.SetDefault("connection.insecure", false)
viper.SetDefault("connection.cert", "") viper.SetDefault("connection.cert", "")
viper.SetDefault("connection.key", "") viper.SetDefault("connection.key", "")

View file

@ -11,7 +11,10 @@ import (
"crypto/tls" "crypto/tls"
"errors" "errors"
"fmt" "fmt"
"io/ioutil"
"net" "net"
"os"
"os/exec"
"strings" "strings"
"time" "time"
@ -193,7 +196,7 @@ func (dj *MumbleDJ) Connect() error {
// Initialize key pair if needed. // Initialize key pair if needed.
if viper.GetBool("connection.insecure") { if viper.GetBool("connection.insecure") {
dj.TLSConfig.InsecureSkipVerify = true dj.TLSConfig.InsecureSkipVerify = true
} } else {
dj.TLSConfig.ServerName = viper.GetString("connection.address") dj.TLSConfig.ServerName = viper.GetString("connection.address")
if viper.GetString("connection.cert") != "" { if viper.GetString("connection.cert") != "" {
@ -207,6 +210,39 @@ func (dj *MumbleDJ) Connect() error {
return err return err
} }
} }
}
// Add user p12 cert if needed.
if viper.GetString("connection.user_p12") != "" {
if _, err := os.Stat(viper.GetString("connection.user_p12")); os.IsNotExist(err) {
return err
}
// Create temporary directory for converted p12 file.
dir, err := ioutil.TempDir("", "mumbledj")
if err != nil {
return err
}
defer os.RemoveAll(dir)
// Create temporary mumbledj.crt.pem from p12 file.
command := exec.Command("openssl", "pkcs12", "-password", "pass:", "-in", viper.GetString("connection.user_p12"), "-out", dir+"/mumbledj.crt.pem", "-clcerts", "-nokeys")
if err := command.Run(); err != nil {
return err
}
// Create temporary mumbledj.key.pem from p12 file.
command = exec.Command("openssl", "pkcs12", "-password", "pass:", "-in", viper.GetString("connection.user_p12"), "-out", dir+"/mumbledj.key.pem", "-nocerts", "-nodes")
if err := command.Run(); err != nil {
return err
}
if certificate, err := tls.LoadX509KeyPair(dir+"/mumbledj.crt.pem", dir+"/mumbledj.key.pem"); err == nil {
dj.TLSConfig.Certificates = append(dj.TLSConfig.Certificates, certificate)
} else {
return err
}
}
dj.GumbleConfig.Attach(gumbleutil.Listener{ dj.GumbleConfig.Attach(gumbleutil.Listener{
Connect: dj.OnConnect, Connect: dj.OnConnect,

View file

@ -58,6 +58,10 @@ func PerformStartupChecks() {
if err := checkAria2Installation(); err != nil { if err := checkAria2Installation(); err != nil {
logrus.Warnln("aria2 is not installed or is not discoverable in $PATH. The bot will still partially work, but some services will not work properly.") logrus.Warnln("aria2 is not installed or is not discoverable in $PATH. The bot will still partially work, but some services will not work properly.")
} }
if err := checkOpenSSLInstallation(); err != nil {
logrus.Warnln("openssl is not installed or is not discoverable in $PATH. p12 certificate files will not work.")
}
} }
func checkYouTubeDLInstallation() error { func checkYouTubeDLInstallation() error {
@ -95,3 +99,12 @@ func checkAria2Installation() error {
} }
return nil return nil
} }
func checkOpenSSLInstallation() error {
logrus.Infoln("Checking openssl installation...")
command := exec.Command("openssl", "version")
if err := command.Run(); err != nil {
return errors.New("openssl is not properly installed")
}
return nil
}

View file

@ -63,6 +63,10 @@ connection:
# Username for MumbleDJ. # Username for MumbleDJ.
username: "MumbleDJ" username: "MumbleDJ"
# Filepath to user p12 file for authenticating as a registered user.
# NOTE: If no p12 file is needed, set to empty string ("").
user_p12: ""
# Should the bot attempt an insecure connection? # Should the bot attempt an insecure connection?
# An insecure connection does not verify the certificate of the server for # An insecure connection does not verify the certificate of the server for
# consistency. It is best to leave this on, but disable it if you are having # consistency. It is best to leave this on, but disable it if you are having

10
main.go
View file

@ -32,7 +32,7 @@ func init() {
services.DJ = DJ services.DJ = DJ
bot.DJ = DJ bot.DJ = DJ
DJ.Version = "v3.0.11" DJ.Version = "v3.1.0"
logrus.SetLevel(logrus.WarnLevel) logrus.SetLevel(logrus.WarnLevel)
} }
@ -73,6 +73,11 @@ func main() {
Value: "", Value: "",
Usage: "channel the bot enters after connecting to the Mumble server", Usage: "channel the bot enters after connecting to the Mumble server",
}, },
cli.StringFlag{
Name: "p12",
Value: "",
Usage: "path to user p12 file for authenticating as a registered user",
},
cli.StringFlag{ cli.StringFlag{
Name: "cert, e", Name: "cert, e",
Value: "", Value: "",
@ -156,6 +161,9 @@ func main() {
if c.GlobalIsSet("channel") { if c.GlobalIsSet("channel") {
viper.Set("defaults.channel", c.String("channel")) viper.Set("defaults.channel", c.String("channel"))
} }
if c.GlobalIsSet("p12") {
viper.Set("connection.user_p12", c.String("p12"))
}
if c.GlobalIsSet("cert") { if c.GlobalIsSet("cert") {
viper.Set("connection.cert", c.String("cert")) viper.Set("connection.cert", c.String("cert"))
} }