Selaa lähdekoodia

fix #1020

tags/v2.1.0-rc1
Shivaram Lingamneni 4 vuotta sitten
vanhempi
commit
67150bc8f7
5 muutettua tiedostoa jossa 63 lisäystä ja 13 poistoa
  1. 4
    0
      conventional.yaml
  2. 13
    4
      irc/client.go
  3. 10
    6
      irc/config.go
  4. 32
    3
      irc/handlers.go
  5. 4
    0
      oragono.yaml

+ 4
- 0
conventional.yaml Näytä tiedosto

@@ -330,6 +330,10 @@ accounts:
330 330
     # PASS as well, so it can be configured to authenticate with SASL only.
331 331
     skip-server-password: false
332 332
 
333
+    # enable login to accounts via the PASS command, e.g., PASS account:password
334
+    # this is sometimes useful for compatibility with old clients that don't support SASL
335
+    login-via-pass-command: false
336
+
333 337
     # require-sasl controls whether clients are required to have accounts
334 338
     # (and sign into them using SASL) to connect to the server
335 339
     require-sasl:

+ 13
- 4
irc/client.go Näytä tiedosto

@@ -97,6 +97,15 @@ func (s *saslStatus) Clear() {
97 97
 	*s = saslStatus{}
98 98
 }
99 99
 
100
+// what stage the client is at w.r.t. the PASS command:
101
+type serverPassStatus uint
102
+
103
+const (
104
+	serverPassUnsent serverPassStatus = iota
105
+	serverPassSuccessful
106
+	serverPassFailed
107
+)
108
+
100 109
 // Session is an individual client connection to the server (TCP connection
101 110
 // and associated per-connection data, such as capabilities). There is a
102 111
 // many-one relationship between sessions and clients.
@@ -117,9 +126,9 @@ type Session struct {
117 126
 	deferredFakelagCount int
118 127
 	destroyed            uint32
119 128
 
120
-	certfp          string
121
-	sasl            saslStatus
122
-	sentPassCommand bool
129
+	certfp     string
130
+	sasl       saslStatus
131
+	passStatus serverPassStatus
123 132
 
124 133
 	batchCounter uint32
125 134
 
@@ -510,7 +519,7 @@ const (
510 519
 func (client *Client) isAuthorized(config *Config, session *Session) AuthOutcome {
511 520
 	saslSent := client.account != ""
512 521
 	// PASS requirement
513
-	if (config.Server.passwordBytes != nil) && !session.sentPassCommand && !(config.Accounts.SkipServerPassword && saslSent) {
522
+	if (config.Server.passwordBytes != nil) && session.passStatus != serverPassSuccessful && !(config.Accounts.SkipServerPassword && saslSent) {
514 523
 		return authFailPass
515 524
 	}
516 525
 	// Tor connections may be required to authenticate with SASL

+ 10
- 6
irc/config.go Näytä tiedosto

@@ -254,12 +254,13 @@ type AccountConfig struct {
254 254
 		Exempted     []string
255 255
 		exemptedNets []net.IPNet
256 256
 	} `yaml:"require-sasl"`
257
-	DefaultUserModes   *string `yaml:"default-user-modes"`
258
-	defaultUserModes   modes.ModeChanges
259
-	LDAP               ldap.ServerConfig
260
-	LoginThrottling    ThrottleConfig `yaml:"login-throttling"`
261
-	SkipServerPassword bool           `yaml:"skip-server-password"`
262
-	NickReservation    struct {
257
+	DefaultUserModes    *string `yaml:"default-user-modes"`
258
+	defaultUserModes    modes.ModeChanges
259
+	LDAP                ldap.ServerConfig
260
+	LoginThrottling     ThrottleConfig `yaml:"login-throttling"`
261
+	SkipServerPassword  bool           `yaml:"skip-server-password"`
262
+	LoginViaPassCommand bool           `yaml:"login-via-pass-command"`
263
+	NickReservation     struct {
263 264
 		Enabled                bool
264 265
 		AdditionalNickLimit    int `yaml:"additional-nick-limit"`
265 266
 		Method                 NickEnforcementMethod
@@ -1078,6 +1079,9 @@ func LoadConfig(filename string) (config *Config, err error) {
1078 1079
 		if err != nil {
1079 1080
 			return nil, err
1080 1081
 		}
1082
+		if config.Accounts.LoginViaPassCommand && !config.Accounts.SkipServerPassword {
1083
+			return nil, errors.New("Using a server password and login-via-pass-command requires skip-server-password as well")
1084
+		}
1081 1085
 	}
1082 1086
 
1083 1087
 	if config.Accounts.Registration.BcryptCost == 0 {

+ 32
- 3
irc/handlers.go Näytä tiedosto

@@ -2159,16 +2159,45 @@ func passHandler(server *Server, client *Client, msg ircmsg.IrcMessage, rb *Resp
2159 2159
 		rb.Add(nil, server.name, ERR_ALREADYREGISTRED, client.nick, client.t("You may not reregister"))
2160 2160
 		return false
2161 2161
 	}
2162
+	if rb.session.passStatus != serverPassUnsent {
2163
+		return false
2164
+	}
2165
+
2166
+	password := msg.Params[0]
2167
+	config := server.Config()
2168
+
2169
+	if config.Accounts.LoginViaPassCommand {
2170
+		colonIndex := strings.IndexByte(password, ':')
2171
+		if colonIndex != -1 && client.Account() == "" {
2172
+			// TODO consolidate all login throttle checks into AccountManager
2173
+			throttled, _ := client.loginThrottle.Touch()
2174
+			if !throttled {
2175
+				account, accountPass := password[:colonIndex], password[colonIndex+1:]
2176
+				err := server.accounts.AuthenticateByPassphrase(client, account, accountPass)
2177
+				if err == nil {
2178
+					sendSuccessfulAccountAuth(client, rb, false, true)
2179
+					// login-via-pass-command entails that we do not need to check
2180
+					// an actual server password (either no password or skip-server-password)
2181
+					rb.session.passStatus = serverPassSuccessful
2182
+					return false
2183
+				}
2184
+			}
2185
+		}
2186
+	}
2187
+
2188
+	serverPassword := config.Server.passwordBytes
2162 2189
 
2163 2190
 	// if no password exists, skip checking
2164
-	serverPassword := server.Config().Server.passwordBytes
2165 2191
 	if serverPassword == nil {
2166 2192
 		return false
2167 2193
 	}
2168 2194
 
2169 2195
 	// check the provided password
2170
-	password := []byte(msg.Params[0])
2171
-	rb.session.sentPassCommand = bcrypt.CompareHashAndPassword(serverPassword, password) == nil
2196
+	if bcrypt.CompareHashAndPassword(serverPassword, []byte(password)) == nil {
2197
+		rb.session.passStatus = serverPassSuccessful
2198
+	} else {
2199
+		rb.session.passStatus = serverPassFailed
2200
+	}
2172 2201
 
2173 2202
 	// if they failed the check, we'll bounce them later when they try to complete registration
2174 2203
 	return false

+ 4
- 0
oragono.yaml Näytä tiedosto

@@ -351,6 +351,10 @@ accounts:
351 351
     # PASS as well, so it can be configured to authenticate with SASL only.
352 352
     skip-server-password: false
353 353
 
354
+    # enable login to accounts via the PASS command, e.g., PASS account:password
355
+    # this is sometimes useful for compatibility with old clients that don't support SASL
356
+    login-via-pass-command: false
357
+
354 358
     # require-sasl controls whether clients are required to have accounts
355 359
     # (and sign into them using SASL) to connect to the server
356 360
     require-sasl:

Loading…
Peruuta
Tallenna