Merge pull request #1148 from slingamn/issue1050_fingerprint

fix #1050
This commit is contained in:
Shivaram Lingamneni 2020-06-22 20:23:05 -07:00 committed by GitHub
commit 1c3e40b358
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 45 additions and 32 deletions

@ -149,7 +149,7 @@ server:
- -
# SHA-256 fingerprint of the TLS certificate the gateway must use to connect # SHA-256 fingerprint of the TLS certificate the gateway must use to connect
# (comment this out to use passwords only) # (comment this out to use passwords only)
fingerprint: "abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789" certfp: "abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789"
# password the gateway uses to connect, made with oragono genpasswd # password the gateway uses to connect, made with oragono genpasswd
password: "$2a$04$abcdef0123456789abcdef0123456789abcdef0123456789abcde" password: "$2a$04$abcdef0123456789abcdef0123456789abcdef0123456789abcde"
@ -574,7 +574,7 @@ opers:
# if a SHA-256 certificate fingerprint is configured here, then it will be # if a SHA-256 certificate fingerprint is configured here, then it will be
# required to /OPER. if you comment out the password hash above, then you can # required to /OPER. if you comment out the password hash above, then you can
# /OPER without a password. # /OPER without a password.
#fingerprint: "abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789" #certfp: "abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789"
# if 'auto' is set (and no password hash is set), operator permissions will be # if 'auto' is set (and no password hash is set), operator permissions will be
# granted automatically as soon as you connect with the right fingerprint. # granted automatically as soon as you connect with the right fingerprint.
#auto: true #auto: true

@ -175,7 +175,7 @@ server:
- -
# SHA-256 fingerprint of the TLS certificate the gateway must use to connect # SHA-256 fingerprint of the TLS certificate the gateway must use to connect
# (comment this out to use passwords only) # (comment this out to use passwords only)
fingerprint: "abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789" certfp: "abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789"
# password the gateway uses to connect, made with oragono genpasswd # password the gateway uses to connect, made with oragono genpasswd
password: "$2a$04$abcdef0123456789abcdef0123456789abcdef0123456789abcde" password: "$2a$04$abcdef0123456789abcdef0123456789abcdef0123456789abcde"
@ -600,7 +600,7 @@ opers:
# if a SHA-256 certificate fingerprint is configured here, then it will be # if a SHA-256 certificate fingerprint is configured here, then it will be
# required to /OPER. if you comment out the password hash above, then you can # required to /OPER. if you comment out the password hash above, then you can
# /OPER without a password. # /OPER without a password.
#fingerprint: "abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789" #certfp: "abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789"
# if 'auto' is set (and no password hash is set), operator permissions will be # if 'auto' is set (and no password hash is set), operator permissions will be
# granted automatically as soon as you connect with the right fingerprint. # granted automatically as soon as you connect with the right fingerprint.
#auto: true #auto: true

@ -1646,7 +1646,7 @@ func (client *Client) attemptAutoOper(session *Session) {
return return
} }
for _, oper := range client.server.Config().operators { for _, oper := range client.server.Config().operators {
if oper.Auto && oper.Pass == nil && oper.Fingerprint != "" && oper.Fingerprint == session.certfp { if oper.Auto && oper.Pass == nil && oper.Certfp != "" && oper.Certfp == session.certfp {
rb := NewResponseBuffer(session) rb := NewResponseBuffer(session)
applyOper(client, oper, rb) applyOper(client, oper, rb)
rb.Send(true) rb.Send(true)

@ -408,7 +408,8 @@ type OperConfig struct {
Vhost string Vhost string
WhoisLine string `yaml:"whois-line"` WhoisLine string `yaml:"whois-line"`
Password string Password string
Fingerprint string Fingerprint *string // legacy name for certfp, #1050
Certfp string
Auto bool Auto bool
Modes string Modes string
} }
@ -695,14 +696,14 @@ func (conf *Config) OperatorClasses() (map[string]*OperClass, error) {
// Oper represents a single assembled operator's config. // Oper represents a single assembled operator's config.
type Oper struct { type Oper struct {
Name string Name string
Class *OperClass Class *OperClass
WhoisLine string WhoisLine string
Vhost string Vhost string
Pass []byte Pass []byte
Fingerprint string Certfp string
Auto bool Auto bool
Modes []modes.ModeChange Modes []modes.ModeChange
} }
// Operators returns a map of operator configs from the given OperClass and config. // Operators returns a map of operator configs from the given OperClass and config.
@ -724,15 +725,19 @@ func (conf *Config) Operators(oc map[string]*OperClass) (map[string]*Oper, error
return nil, fmt.Errorf("Oper %s has an invalid password hash: %s", oper.Name, err.Error()) return nil, fmt.Errorf("Oper %s has an invalid password hash: %s", oper.Name, err.Error())
} }
} }
if opConf.Fingerprint != "" { certfp := opConf.Certfp
oper.Fingerprint, err = utils.NormalizeCertfp(opConf.Fingerprint) if certfp == "" && opConf.Fingerprint != nil {
certfp = *opConf.Fingerprint
}
if certfp != "" {
oper.Certfp, err = utils.NormalizeCertfp(certfp)
if err != nil { if err != nil {
return nil, fmt.Errorf("Oper %s has an invalid fingerprint: %s", oper.Name, err.Error()) return nil, fmt.Errorf("Oper %s has an invalid fingerprint: %s", oper.Name, err.Error())
} }
} }
oper.Auto = opConf.Auto oper.Auto = opConf.Auto
if oper.Pass == nil && oper.Fingerprint == "" { if oper.Pass == nil && oper.Certfp == "" {
return nil, fmt.Errorf("Oper %s has neither a password nor a fingerprint", name) return nil, fmt.Errorf("Oper %s has neither a password nor a fingerprint", name)
} }

@ -26,31 +26,39 @@ const (
) )
type webircConfig struct { type webircConfig struct {
PasswordString string `yaml:"password"` PasswordString string `yaml:"password"`
Password []byte `yaml:"password-bytes"` Password []byte `yaml:"password-bytes"`
Fingerprint string Fingerprint *string // legacy name for certfp, #1050
Certfp string
Hosts []string Hosts []string
allowedNets []net.IPNet allowedNets []net.IPNet
} }
// Populate fills out our password or fingerprint. // Populate fills out our password or fingerprint.
func (wc *webircConfig) Populate() (err error) { func (wc *webircConfig) Populate() (err error) {
if wc.Fingerprint == "" && wc.PasswordString == "" { if wc.PasswordString != "" {
err = ErrNoFingerprintOrPassword
}
if err == nil && wc.PasswordString != "" {
wc.Password, err = decodeLegacyPasswordHash(wc.PasswordString) wc.Password, err = decodeLegacyPasswordHash(wc.PasswordString)
if err != nil {
return
}
} }
if err == nil && wc.Fingerprint != "" { certfp := wc.Certfp
wc.Fingerprint, err = utils.NormalizeCertfp(wc.Fingerprint) if certfp == "" && wc.Fingerprint != nil {
certfp = *wc.Fingerprint
}
if certfp != "" {
wc.Certfp, err = utils.NormalizeCertfp(certfp)
}
if err != nil {
return
} }
if err == nil { if wc.Certfp == "" && wc.PasswordString == "" {
wc.allowedNets, err = utils.ParseNetList(wc.Hosts) return ErrNoFingerprintOrPassword
} }
wc.allowedNets, err = utils.ParseNetList(wc.Hosts)
return err return err
} }

@ -2164,8 +2164,8 @@ func operHandler(server *Server, client *Client, msg ircmsg.IrcMessage, rb *Resp
var checkPassed, checkFailed, passwordFailed bool var checkPassed, checkFailed, passwordFailed bool
oper := server.GetOperator(msg.Params[0]) oper := server.GetOperator(msg.Params[0])
if oper != nil { if oper != nil {
if oper.Fingerprint != "" { if oper.Certfp != "" {
if oper.Fingerprint == rb.session.certfp { if oper.Certfp == rb.session.certfp {
checkPassed = true checkPassed = true
} else { } else {
checkFailed = true checkFailed = true
@ -2737,7 +2737,7 @@ func webircHandler(server *Server, client *Client, msg ircmsg.IrcMessage, rb *Re
if 0 < len(info.Password) && bcrypt.CompareHashAndPassword(info.Password, givenPassword) != nil { if 0 < len(info.Password) && bcrypt.CompareHashAndPassword(info.Password, givenPassword) != nil {
continue continue
} }
if info.Fingerprint != "" && info.Fingerprint != rb.session.certfp { if info.Certfp != "" && info.Certfp != rb.session.certfp {
continue continue
} }