|
@@ -20,6 +20,7 @@ internal class CapabilitiesHandler : EventHandler {
|
20
|
20
|
is ServerCapabilitiesFinished -> handleCapabilitiesFinished(client)
|
21
|
21
|
is ServerCapabilitiesAcknowledged -> handleCapabilitiesAcknowledged(client, event.capabilities)
|
22
|
22
|
is AuthenticationMessage -> handleAuthenticationMessage(client, event.argument)
|
|
23
|
+ is SaslMechanismNotAvailableError -> handleSaslMechanismChange(client, event.mechanisms)
|
23
|
24
|
is SaslFinished -> handleSaslFinished(client)
|
24
|
25
|
}
|
25
|
26
|
return emptyList()
|
|
@@ -32,7 +33,7 @@ internal class CapabilitiesHandler : EventHandler {
|
32
|
33
|
private fun handleCapabilitiesFinished(client: IrcClient) {
|
33
|
34
|
// TODO: We probably need to split the outgoing REQ lines if there are lots of caps
|
34
|
35
|
// TODO: For caps with values we may need to decide which value to use/whether to enable them/etc
|
35
|
|
- with (client.serverState.capabilities) {
|
|
36
|
+ with(client.serverState.capabilities) {
|
36
|
37
|
if (advertisedCapabilities.keys.isEmpty()) {
|
37
|
38
|
negotiationState = CapabilitiesNegotiationState.FINISHED
|
38
|
39
|
client.sendCapabilityEnd()
|
|
@@ -48,17 +49,15 @@ internal class CapabilitiesHandler : EventHandler {
|
48
|
49
|
|
49
|
50
|
private fun handleCapabilitiesAcknowledged(client: IrcClient, capabilities: Map<Capability, String>) {
|
50
|
51
|
// TODO: Check if everything we wanted is enabled
|
51
|
|
- with (client.serverState.capabilities) {
|
|
52
|
+ with(client.serverState.capabilities) {
|
52
|
53
|
log.info { "Acknowledged capabilities: ${capabilities.keys.map { it.name }.toList()}" }
|
53
|
54
|
enabledCapabilities.putAll(capabilities)
|
54
|
55
|
|
55
|
56
|
if (client.serverState.sasl.mechanisms.isNotEmpty()) {
|
56
|
|
- client.serverState.sasl.getPreferredSaslMechanism(enabledCapabilities[Capability.SaslAuthentication])?.let { mechanism ->
|
57
|
|
- log.info { "Attempting SASL authentication using ${mechanism.ircName}" }
|
58
|
|
- client.serverState.sasl.currentMechanism = mechanism
|
59
|
|
- negotiationState = CapabilitiesNegotiationState.AUTHENTICATING
|
60
|
|
- client.sendAuthenticationMessage(mechanism.ircName)
|
61
|
|
- return
|
|
57
|
+ enabledCapabilities[Capability.SaslAuthentication]?.let { serverCaps ->
|
|
58
|
+ if (startSaslAuth(client, serverCaps.split(','))) {
|
|
59
|
+ return
|
|
60
|
+ }
|
62
|
61
|
}
|
63
|
62
|
log.warning { "SASL is enabled but we couldn't negotiate a SASL mechanism with the server" }
|
64
|
63
|
}
|
|
@@ -67,6 +66,24 @@ internal class CapabilitiesHandler : EventHandler {
|
67
|
66
|
}
|
68
|
67
|
}
|
69
|
68
|
|
|
69
|
+ private fun handleSaslMechanismChange(client: IrcClient, mechanisms: Collection<String>) {
|
|
70
|
+ if (!startSaslAuth(client, mechanisms)) {
|
|
71
|
+ log.warning { "SASL is enabled but we couldn't negotiate a SASL mechanism with the server" }
|
|
72
|
+ client.endNegotiation()
|
|
73
|
+ }
|
|
74
|
+ }
|
|
75
|
+
|
|
76
|
+ private fun startSaslAuth(client: IrcClient, serverMechanisms: Collection<String>) =
|
|
77
|
+ with(client.serverState) {
|
|
78
|
+ sasl.getPreferredSaslMechanism(serverMechanisms)?.let { mechanism ->
|
|
79
|
+ log.info { "Attempting SASL authentication using ${mechanism.ircName}" }
|
|
80
|
+ sasl.currentMechanism = mechanism
|
|
81
|
+ capabilities.negotiationState = CapabilitiesNegotiationState.AUTHENTICATING
|
|
82
|
+ client.sendAuthenticationMessage(mechanism.ircName)
|
|
83
|
+ true
|
|
84
|
+ } ?: false
|
|
85
|
+ }
|
|
86
|
+
|
70
|
87
|
private fun handleAuthenticationMessage(client: IrcClient, argument: String?) {
|
71
|
88
|
if (argument?.length == 400) {
|
72
|
89
|
client.serverState.sasl.saslBuffer += argument
|
|
@@ -80,8 +97,8 @@ internal class CapabilitiesHandler : EventHandler {
|
80
|
97
|
}
|
81
|
98
|
}
|
82
|
99
|
|
83
|
|
- private fun handleSaslFinished(client: IrcClient) = with (client) {
|
84
|
|
- with (serverState.sasl) {
|
|
100
|
+ private fun handleSaslFinished(client: IrcClient) = with(client) {
|
|
101
|
+ with(serverState.sasl) {
|
85
|
102
|
saslBuffer = ""
|
86
|
103
|
mechanismState = null
|
87
|
104
|
currentMechanism = null
|