diff --git a/doc/reference.conf b/doc/reference.conf index 02a9ef07e..eae53c114 100755 --- a/doc/reference.conf +++ b/doc/reference.conf @@ -332,6 +332,7 @@ auth { * USE WITH CAUTION. * no_tilde (old - flag) | don't prefix ~ to username if no ident * need_ident (old + flag) | require ident for user in this class + * need_ssl | require SSL/TLS for user in this class * need_sasl | require SASL id for user in this class */ flags = kline_exempt, exceed_limit; @@ -407,6 +408,7 @@ operator "god" { * Available options: * * encrypted: the password above is encrypted [DEFAULT] + * need_ssl: must be using SSL/TLS to oper up * local_kill: allows local users to be /KILL'd * global_kill: allows local and remote users to be * /KILL'd (OLD 'O' flag) diff --git a/include/s_conf.h b/include/s_conf.h index b556ff087..bb2e162d7 100644 --- a/include/s_conf.h +++ b/include/s_conf.h @@ -89,6 +89,7 @@ struct ConfItem /* Generic flags... */ #define CONF_FLAGS_TEMPORARY 0x00800000 +#define CONF_FLAGS_NEED_SSL 0x00000002 /* auth{} flags... */ #define CONF_FLAGS_NO_TILDE 0x00000004 #define CONF_FLAGS_NEED_IDENTD 0x00000008 @@ -122,6 +123,7 @@ struct ConfItem #define IsConfEncrypted(x) ((x)->flags & CONF_FLAGS_ENCRYPTED) #define IsNeedSasl(x) ((x)->flags & CONF_FLAGS_NEED_SASL) #define IsConfExemptDNSBL(x) ((x)->flags & CONF_FLAGS_EXEMPTDNSBL) +#define IsConfSSLNeeded(x) ((x)->flags & CONF_FLAGS_NEED_SSL) /* flag definitions for opers now in client.h */ diff --git a/include/s_newconf.h b/include/s_newconf.h index d3f9b1f51..059834366 100644 --- a/include/s_newconf.h +++ b/include/s_newconf.h @@ -157,6 +157,7 @@ extern void cluster_generic(struct Client *, const char *, int cltype, #define OPER_SPY 0x10000 #define OPER_REMOTEBAN 0x20000 #define OPER_MASSNOTICE 0x40000 +#define OPER_NEEDSSL 0x80000 /* 0x400000 and above are in client.h */ #define OPER_FLAGS (OPER_KLINE|OPER_UNKLINE|OPER_LOCKILL|OPER_GLOBKILL|\ @@ -166,6 +167,7 @@ extern void cluster_generic(struct Client *, const char *, int cltype, OPER_REMOTEBAN|OPER_MASSNOTICE) #define IsOperConfEncrypted(x) ((x)->flags & OPER_ENCRYPTED) +#define IsOperConfNeedSSL(x) ((x)->flags & OPER_NEEDSSL) #define HasPrivilege(x, y) ((x)->localClient != NULL && (x)->localClient->privset != NULL && privilegeset_in_set((x)->localClient->privset, (y))) diff --git a/modules/m_challenge.c b/modules/m_challenge.c index ea7c1280e..e0b9dbe05 100644 --- a/modules/m_challenge.c +++ b/modules/m_challenge.c @@ -223,6 +223,22 @@ m_challenge(struct Client *client_p, struct Client *source_p, int parc, const ch return 0; } + if(IsOperConfNeedSSL(oper_p) && !IsSSLClient(source_p)) + { + sendto_one(source_p, form_str(ERR_NOOPERHOST), me.name, source_p->name); + ilog(L_FOPER, "FAILED CHALLENGE (%s) by (%s!%s@%s) (%s) -- requires SSL/TLS", + parv[1], source_p->name, source_p->username, source_p->host, + source_p->sockhost); + + if(ConfigFileEntry.failed_oper_notice) + { + sendto_realops_snomask(SNO_GENERAL, L_ALL, + "Failed CHALLENGE attempt - missing SSL/TLS by %s (%s@%s)", + source_p->name, source_p->username, source_p->host); + } + return 0; + } + if(!generate_challenge(&challenge, &(source_p->localClient->challenge), oper_p->rsa_pubkey)) { char *chal = challenge; diff --git a/modules/m_oper.c b/modules/m_oper.c index 2a8a2f0e7..1b0b7c928 100644 --- a/modules/m_oper.c +++ b/modules/m_oper.c @@ -100,6 +100,22 @@ m_oper(struct Client *client_p, struct Client *source_p, int parc, const char *p return 0; } + if(IsOperConfNeedSSL(oper_p) && !IsSSLClient(source_p)) + { + sendto_one(source_p, form_str(ERR_NOOPERHOST), me.name, source_p->name); + ilog(L_FOPER, "FAILED OPER (%s) by (%s!%s@%s) (%s) -- requires SSL/TLS", + name, source_p->name, + source_p->username, source_p->host, source_p->sockhost); + + if(ConfigFileEntry.failed_oper_notice) + { + sendto_realops_snomask(SNO_GENERAL, L_ALL, + "Failed OPER attempt - missing SSL/TLS by %s (%s@%s)", + source_p->name, source_p->username, source_p->host); + } + return 0; + } + if(match_oper_password(password, oper_p)) { oper_up(source_p, oper_p); diff --git a/src/newconf.c b/src/newconf.c index 33bd7e023..2cde3ad2c 100644 --- a/src/newconf.c +++ b/src/newconf.c @@ -325,6 +325,7 @@ static struct mode_table oper_table[] = { {"hidden_oper", OPER_INVIS }, {"remoteban", OPER_REMOTEBAN }, {"mass_notice", OPER_MASSNOTICE }, + {"need_ssl", OPER_NEEDSSL }, {NULL, 0} }; @@ -342,6 +343,7 @@ static struct mode_table auth_table[] = { {"no_tilde", CONF_FLAGS_NO_TILDE }, {"need_ident", CONF_FLAGS_NEED_IDENTD }, {"have_ident", CONF_FLAGS_NEED_IDENTD }, + {"need_ssl", CONF_FLAGS_NEED_SSL }, {"need_sasl", CONF_FLAGS_NEED_SASL }, {NULL, 0} }; diff --git a/src/s_user.c b/src/s_user.c index 6c81df8ea..740525605 100644 --- a/src/s_user.c +++ b/src/s_user.c @@ -314,6 +314,14 @@ register_local_user(struct Client *client_p, struct Client *source_p, const char return (CLIENT_EXITED); } + if(IsConfSSLNeeded(aconf) && !IsSSL(source_p)) + { + ServerStats.is_ref++; + sendto_one_notice(source_p, ":*** Notice -- You need to use SSL/TLS to use this server"); + exit_client(client_p, source_p, &me, "Use SSL/TLS"); + return (CLIENT_EXITED); + } + if(!IsGotId(source_p)) { const char *p;