- if(acceptedCap.count() >= 2)
- coreNet->addCap(acceptedCap.at(0), acceptedCap.at(1));
- else
- coreNet->addCap(acceptedCap.at(0));
-
- // Handle special cases
- if (acceptedCap.at(0).startsWith("sasl")) {
- // Freenode (at least) sends "sasl " with a trailing space for some reason!
- // if the current identity has a cert set, use SASL EXTERNAL
- // FIXME use event
- // TODO If value of sasl capability is not empty, limit to accepted
-#ifdef HAVE_SSL
- if (!coreNet->identityPtr()->sslCert().isNull()) {
- coreNet->putRawLine(coreNet->serverEncode("AUTHENTICATE EXTERNAL"));
- } else {
-#endif
- // Only working with PLAIN atm, blowfish later
- coreNet->putRawLine(coreNet->serverEncode("AUTHENTICATE PLAIN"));
-#ifdef HAVE_SSL
- }
-#endif
- } else {
- // Special handling not needed, move on to next cap
- sendNextCap(coreNet);
+ coreNet->acknowledgeCap(acceptedCap);
+
+ if (!coreNet->capsRequiringConfiguration.contains(acceptedCap)) {
+ // Some capabilities (e.g. SASL) require further messages to finish. If so, do NOT
+ // send the next capability; it will be handled elsewhere in CoreNetwork.
+ // Otherwise, move on to the next capability
+ coreNet->sendNextCap();
+ }
+ } else if (capCommand == "NAK" || capCommand == "DEL") {
+ // Either something went wrong with this capability, or it is no longer supported
+ // > For CAP NAK
+ // Server: CAP * NAK :multi-prefix sasl
+ // > For CAP DEL
+ // Server: :irc.example.com CAP modernclient DEL :multi-prefix sasl
+ // CAP NAK and CAP DEL replies are always single-line
+
+ QStringList removedCaps;
+ removedCaps = e->params().at(2).split(' ');
+
+ // Store what capability was denied or removed
+ QString removedCap;
+ for (int i = 0; i < removedCaps.count(); ++i) {
+ removedCap = removedCaps[i].trimmed().toLower();
+ // Mark this cap as removed
+ coreNet->removeCap(removedCap);
+ }
+
+ if (capCommand == "NAK") {
+ // Continue negotiation when capability listing complete only if this is the result
+ // of a denied cap, not a removed cap
+ coreNet->sendNextCap();