View Issue Details

IDProjectCategoryView StatusLast Update
0002082unrealircdpublic2015-07-13 22:52
Reporteral5001 Assigned Tosyzop  
PrioritynormalSeverityfeatureReproducibilityN/A
Status closedResolutionno change required 
Summary0002082: Allow oper::password conf item to be blank
DescriptionI am currently creating a challenge/response authentication module, however, I had to edit s_conf.c to allow my module to work...

        if (!strcmp(cep->ce_varname, "password"))
        {
        /* if (Auth_CheckError(cep) < 0)
                errors++;
             should have some auth check if ok .. <-- not anymore :P... we want to be able to have blank passwords for RSA challenge/response module support...
            continue; */
        }

I'd be happier if passwords were allowed to be blank... It doesn't cause problems either, since people still can't /oper with a blank password (Remember parc? that's why :P).


    if (!config_find_entry(ce->ce_entries, "password"))
    {
        config_error("%s:%i: oper::password missing", ce->ce_fileptr->cf_filename,
            ce->ce_varlinenum);
        errors++;
    }

This one can probably stay here... I usually just do this in conf:

oper name {
  password "";
  rsa_public_key_file "/usr/home/pomme/Unreal3.2/pomme.pub";
};

That works just fine as it is. This way, /oper is sort of disabled because it won't work with a blank password, and my own challenge/response module will.
3rd party modules

Activities

aquanight

2004-09-20 06:08

reporter   ~0007733

And... SSL certificates can't do this?

codemastr

2004-09-20 18:37

reporter   ~0007736

Why not just have them specify the keyfile as the password? That's how we do it for the SSL keyfile stuff.

al5001

2004-09-20 18:41

reporter   ~0007737

Well, you're forgetting how SSL works. You can't use SSL for general cryptography. You can't just pick an algorithm and say "Ah, I'm secure now", because you're only making the job of a cracker easier. SSL x509 certificates work like this:

->Client connects to SSL enabled server.
<-Server sends the client its certificate.
->Client authenticates the server with its certificate for non-repudiation (only works for certain types of keys)
->Client encrypts data with the server's certificate and then sends the encrypted data to the server.
->Server uses its private key and decrypts the information. The data is now plain text. If the next client it sends the information to uses a secure tunnel with its own certificate, the server uses the client's certificate to encrypt the data before sending it. If the client does not have its own certificate, the server sends the data in _plain text_. This provides users with a false sense of security when using SSL.

UnrealIRCd uses the x509 certificate type. Sure, it's secure, but don't assume that it's perfect. You still need a client side certificate to receive encrypted data.

While the client first connects to the server, it uses massive amounts of bandwith to send the certificate to the client from the server (and if the client has its own certificate, it takes even more bandwith to send that certificate to the server). The certificates are then checked to make sure they are valid. This is called the handshake. Once this handshake has finished, the encryption/decryption actually uses much, much less bandwith.

With an RSA challenge/response system, the operator generates a key pair on his computer. Since IRC can only handle 510 chars + 3 chars (\r\n\0) per message, the private key cannot be any larger than 1024 bits. The private key is stored in a safe place on the operator's computer, or removeable media. The public key is stored on the server.

Let's use ircd-hybrid's m_challenge.so module to explain how this works.

/CHALLENGE <opername> /* challenges the oper block for opername */
/* Now, the server generates a 64-char + 1 (\0) random code and stores it in the user's information (I'm using sptr->passwd for this...). Just after this happens, the server encrypts that random code using the oper's public key, and then stores it temporarily. This code is now very long... about 256 chars */
:server.name 386 nickname :<encrypted response>
/* now, you have to use your private key to decrypt this code... once you decrypt it, you'll have an exact copy of the random code... */
/CHALLENGE +<decrypted code> /* ok, now is where the server takes parv[2] and matches it up with the 64 char random code... if the code matches, you get operator status... if it doesn't match, you've just sent a failed oper message to the fellow opers */


Now, you're thinking "why not just connect to IRC via SSL instead?". Heh, well, it's just not worth the bandwith. I can understand using x509 certificates for server<->services linking, but that's about it. The RSA challenge/response system uses virtually nil bandwith compared to x509 certificates...

al5001

2004-09-20 18:49

reporter   ~0007738

"Why not just have them specify the keyfile as the password? That's how we do it for the SSL keyfile stuff."


Well, I was going to do that, but I'd have to disable m_oper.c, or people could use /oper name <value of rsa_public_key_file>. With my way, with a blank password, /oper does not work at all. You either get ERR_NEEDMOREPARAMS, or ERR_PASSWDMISMATCH. This way, some opers can have passwords, and others can use the RSA challenge/response system. Perhaps access like network administrator should be secured from attackers, whereas a local operator does not need as much security.

codemastr

2004-09-20 18:56

reporter   ~0007739

[quote]Well, I was going to do that, but I'd have to disable m_oper.c, or people could use /oper name <value of rsa_public_key_file>.[/quote]
No. That's what the CommandOverride system is for.

Your way won't work anyway. You can't add a new config item into the oper {} from a module.

al5001

2004-09-20 18:59

reporter   ~0007740

Last edited: 2004-09-20 19:05

"You can't add a new config item into the oper {} from a module."

Yeah, I had to add that to s_conf.c as well.

I'll use the CommandOverride then instead.

edited on: 2004-09-20 19:05

aquanight

2004-09-20 19:39

reporter   ~0007741

Last edited: 2004-09-20 19:40

Hm... here's a thought to mull over:

We allow modules to add extended authtypes. For example, I could code a module to do XOR + base64 encrypytion (semiweak perhaps, but this might for example require the oper to know both the XOR key and the password itself :P ).

But for this particular feature, your module uses the extended authtypes to allow this:

oper opername {
    password "rsakeyfilehere" { challange; };
};

Someone types in /challange opername, the module's m_challange routine looks up that operblock, sees if it's password field is marked "challange" and if so, it sends the encrypted string as al5001 described. Once the oper decrypts that string, he uses:
/oper opername decryptedstring+encryptedstring
The password provided in the oper command (and probably the operblock pointer in question) would be passed to your authentication check routine, where we seperate the password into it's two parts, compare them as necessary, and return 1 if OK, 0 if not (or some other system). If we return 0, the IRCd triggers an "incorrect password" oper-up failure. If we return 1, the operblock is applied and "*** Notice - al5001 (*@*) [al5001] is now a Network Administrator (N)" :) . Of course, this callback stuff would probably happen after all the opername and from block checking :) . No sense checking the password if it's gonna fail anyway due to incorrect userhost.

*edit* Theoretically, this could allow someone to challange/response into a privileged allow {} block as well... */edit*

edited on: 2004-09-20 19:40

al5001

2004-09-20 20:01

reporter   ~0007745

Well, you only need to send the decrypted part back to the server, it uses strcmp to compare sptr->passwd (which would be the server's random 64+1-char string) with parv[1]+1...

Well, basically, the response is a temporary password (randomly generated by PRNG), and the challenge phrase is the encrypted response (encrypted with the public key)...

I agree, that would be a great idea to use this system in allow blocks.

Basically, for the module, I just replace line 214 with my RSA stuff, then rename the module to m_soper (command /soper [Secure Oper]):

i = Auth_Check(cptr, aconf->auth, password);

I use i= -1 for incorrect response, and i = 2 for a matched response. After the challenge gets sent to the user, I use return 0 so it won't go through the rest of the module. Right now, I'm having fun with gdb.

codemastr

2004-09-21 03:11

reporter   ~0007752

I would not be against allowing modules to create new authtypes. The thing is, I'd want to come up with some generic way to do this. The reason being, there are many things you might want a module to be able to add extended types for. To name a few, log flags, oper flags, /stats flags, etc. And I really don't want to develop new stuff each and everytime I add one of these extended features. So I'd want to come up with a generic method searching an array and if it's not found, then consult modules.

stskeeps

2007-04-19 04:42

reporter   ~0013595

Bump. Module support for adding auth methods?

syzop

2015-07-13 22:51

administrator   ~0018503

Not needed anymore. 3.4.x has cert fp auth and such.

auth methods in module api are not really on my list to be honest. (but are ok if implemented)

Issue History

Date Modified Username Field Change
2004-09-20 03:41 al5001 New Issue
2004-09-20 06:08 aquanight Note Added: 0007733
2004-09-20 18:37 codemastr Note Added: 0007736
2004-09-20 18:41 al5001 Note Added: 0007737
2004-09-20 18:49 al5001 Note Added: 0007738
2004-09-20 18:56 codemastr Note Added: 0007739
2004-09-20 18:59 al5001 Note Added: 0007740
2004-09-20 19:02 al5001 Note Edited: 0007740
2004-09-20 19:05 al5001 Note Edited: 0007740
2004-09-20 19:39 aquanight Note Added: 0007741
2004-09-20 19:40 aquanight Note Edited: 0007741
2004-09-20 20:01 al5001 Note Added: 0007745
2004-09-21 03:11 codemastr Note Added: 0007752
2007-04-19 04:42 stskeeps Note Added: 0013595
2007-04-27 02:54 stskeeps Status new => feedback
2015-07-13 22:51 syzop Note Added: 0018503
2015-07-13 22:51 syzop Status feedback => closed
2015-07-13 22:52 syzop Assigned To => syzop
2015-07-13 22:52 syzop Resolution open => no change required