Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add authtoservices module, replacing sasl/nickserv (#1494) #1496

Open
wants to merge 7 commits into
base: master
Choose a base branch
from

Conversation

an-empty-string
Copy link
Contributor

@an-empty-string an-empty-string commented Feb 18, 2018

The authtoservices module is an amalgamation of the nickserv and sasl modules. In short, it:

  • Tries SASL authentication, if available on the network (this can be disabled with /msg *authtoservices TrySasl no)
  • If that fails, it'll respond to NickServ prompts to identify, like the nickserv module would (this can be disabled with /msg *authtoservices RequireSasl yes)

The first time it is loaded, it will automatically migrate configuration from the sasl module or the nickserv module (precedence is given to sasl), if available. This ensures there's an upgrade path, if we decide the best way forward is to remove the sasl/nickserv modules from the tree and have them load authtoservices instead.

Aside from a few name changes and what's described above, it functions identically to the nickserv and sasl modules.

This PR fixes #1494. This module could in theory be an external module, however, as the original issue was that nickserv and sasl have similar functionality and users often choose the wrong one, it makes sense to combine this PR with removal/redirection of those modules (so this would have to be in core).

@an-empty-string an-empty-string changed the title Add authtoservices module, replacing sasl/nickserv (#1494) (WIP) Add authtoservices module, replacing sasl/nickserv (#1494) Feb 18, 2018
@codecov
Copy link

codecov bot commented Feb 19, 2018

Codecov Report

Merging #1496 into master will decrease coverage by 0.03%.
The diff coverage is 2.93%.

Impacted file tree graph

@@            Coverage Diff             @@
##           master    #1496      +/-   ##
==========================================
- Coverage   36.87%   36.84%   -0.04%     
==========================================
  Files         126      125       -1     
  Lines       30823    30875      +52     
  Branches       93       93              
==========================================
+ Hits        11367    11376       +9     
- Misses      19415    19458      +43     
  Partials       41       41
Impacted Files Coverage Δ
include/znc/IRCNetwork.h 31.16% <ø> (ø) ⬆️
modules/authtoservices.cpp 1.67% <1.67%> (ø)
src/IRCNetwork.cpp 65.33% <11.9%> (-2.23%) ⬇️
include/znc/Csocket.h 62.09% <0%> (-0.66%) ⬇️
src/FileUtils.cpp 48.28% <0%> (-0.5%) ⬇️
src/Utils.cpp 66.61% <0%> (+2.03%) ⬆️

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 15ccaca...596dd30. Read the comment docs.

@@ -0,0 +1,83 @@
<? I18N znc-sasl ?>
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nope

SetArgs("<hidden>");
}

if(!GetNV("NotFirstLoad").ToBool()) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This module should be automatically loaded if sasl and/or nickserv was loaded before. That can be done in IRCNetwork.cpp (search for "legacy crap"). Also the migrated settings can mimic the previous settings more closely if you take into account which of those modules were loaded.

Also that could help getting rid of "NotFirstLoad" hack.

@an-empty-string
Copy link
Contributor Author

The most recent commits likely still have a few bugs... expect updates, but I'm about to start another busy week so it might be a while before I can get them in.

@an-empty-string
Copy link
Contributor Author

502d4dd fixes an issue where the account name wouldn't properly default to the nickname during SASL authentication. That's the only problem I observed when testing this.

@an-empty-string an-empty-string changed the title (WIP) Add authtoservices module, replacing sasl/nickserv (#1494) Add authtoservices module, replacing sasl/nickserv (#1494) Feb 25, 2018
@@ -369,6 +369,21 @@ struct TOption {
void (CIRCNetwork::*pSetter)(T);
};

bool CIRCNetwork::ModuleInConfig(CConfig* pConfig, const CString& sModule) const {
VCString vsList;
bool bFound;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is undefined behavior without = false
Compiler is free to optimize this whole function to return true;

VCString vsList;
bool bFound;

pConfig->FindStringVector("loadmodule", vsList);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It removes all "loadmodule"s from config.

"which will load using your [sasl] configuration. Not "
"loading [nickserv]");
continue;
} else if (ModuleInConfig(pConfig, "authtoservices")) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How did you test this?

if (sModName == "nickserv") {
if (ModuleInConfig(pConfig, "sasl")) {
CUtils::PrintAction(
"NOTICE: [nickserv] was merged into [authtoservices], "
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What if sasl module was loaded, but not configured - e.g. user never told sasl the password.

PutIRC(CString::NamedFormat(GetNV("IdentifyCmd"), msValues));
}

void HandleMessage(CNick& Nick, const CString& sMessage) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Need a way to disable this, e.g. via additional "mechanism"

Copy link
Member

@kylef kylef Nov 17, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍, this can also be a security flaw on sasl only networks where there isn't a NickServ nick. It might be possible for a user to get sasl passwords for ZNC users (and other clients that have similar logic) because they can change their nick to NickServ and send one of messages below to get clients to send passwords to them. Some servers can offer blocking nick names out from use like NickServ and common typos, but that is relying on the server being configured correctly.

I think the spirit of what we're trying to do with #1494 / #1230 is to encourage users to use sasl over nickserv (instead of, not with) because it has many benefits, including the decrease in risks where passwords can be erroneously taken. If its not by automated tooling, even there are known impersonation attacks in the wild with bots using nicknames similar to nickserv such as nicksarv and others to trick users into sending them their passwords.

If a network offers SASL I don't think users should consider using nickserv to idenify. Even if the sasl capability is currently missing or unavailable during connection, there can be room for more sophisticated attacks where you can abuse this feature of clients while services may be offline or down for maintenance. I'd avoid the room for downgrade attacks from sasl to nickserv auth. The original sasl module also has requireauth option to disconnect if we can't authenticate before registration (providing upstream server supports capabilities).


The problem right now is that some users do not know what sasl is, and they are already familiar with nickserv and thus would setup the nickserv module instead. I would suggest that we go with an approach that allows the module to be configured to only allow sasl authentication, and if at any time the module determines it can "upgrade" from from nickserv to sasl auth, it should then set this flag so it would never downgrade without user consent. Or even as alternative to merging the modules together, make the current NickServ module fail if it detects the server supports sasl and facilitate the user on switching to the sasl module instead (and some way to continue with nickserv if the user really knows what they are doing and understands the risks). However this approach may be a bit more user hostile than people would like.

@Zarthus
Copy link
Contributor

Zarthus commented May 6, 2018

it's bikesheddy, but I don't know if authtoservices is a good module name

(1) sasl doesn't depend on services, it's an ircd feature
(2) ircds are working to get rid of services support and integrate authentication directly

I have no really good name proposals, but i think just authentication or auth (already taken i think?) might suit better.


public:
MODCONSTRUCTOR(CAuthToServices) {
AddCommand("Help", t_d("search"), t_d("Generate this output"),
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Isn't there a AddHelpCommand(); function?

true}};

public:
MODCONSTRUCTOR(CAuthToServices) {
Copy link
Contributor

@Zarthus Zarthus May 6, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What about refactoring the command names to directly indicate what type of authentication it is, normally I would suggest a subcommand structure but I don't know if ZNC is capable of it

e.g.

sasl account zarthus
sasl require true
sasl password hunter2

nickserv account zarthus
nickserv password hunter2
nickserv name Themis

instead however maybe something like this makes sense

SASLAccount zarthus
SASLRequire true
SASLPassword hunter2

NSAccount zarthus
NSPassword hunter2
NSName Themis

at the moment it's not clear to me what I need to provide to configure e.g. SASL, Do I need an account? a password? How do I set a certificate path? It's also inconsistent in e.g. SaslMechanism and RequireSasl

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What's the point of unifying sasl and nickserv if all settings stay separate?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The settings can use the same variables, but if I want to configure SASL I just want to know what I need to configure SASL, introducing more ("redundant") options for a nicer to use "API" is, to me, more beneficial than keeping it a confusing mess with 50 commands that don't follow any kind of unified pattern.

}

const CString GetAccount() {
if(GetNV("Account").empty()) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not a fan, I'd rather it just aborts and tells the user to set an account name.

@Zarthus
Copy link
Contributor

Zarthus commented May 6, 2018

I realize the PR feedback here is perhaps better suited for improvement tickets in the future; I just gave thoughts where I thought they fit, in the end it's remants from the old code.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Combine nickserv and sasl modules
4 participants