From 40c1fd479952f47b9f3f5c4de660cd94ddd1a89a Mon Sep 17 00:00:00 2001 From: Valery V Yatsko Date: Thu, 26 Jun 2008 10:18:58 +0400 Subject: [PATCH] PASS selector:password for auth{}, based on spb's patch for ircd-seven --- extensions/m_webirc.c | 2 +- include/client.h | 1 + include/hostmask.h | 10 ++++---- modules/m_dline.c | 2 +- modules/m_kline.c | 4 ++-- modules/m_pass.c | 19 ++++++++++++++++ modules/m_stats.c | 18 ++++++++------- modules/m_testline.c | 2 +- src/hostmask.c | 53 +++++++++++++++++++++++++++---------------- src/kdparse.c | 2 +- src/messages.tab | 2 +- src/newconf.c | 19 +++++++++++++--- src/s_conf.c | 12 ++++++---- 13 files changed, 99 insertions(+), 47 deletions(-) diff --git a/extensions/m_webirc.c b/extensions/m_webirc.c index 8d2f2390..735be1ed 100644 --- a/extensions/m_webirc.c +++ b/extensions/m_webirc.c @@ -89,7 +89,7 @@ mr_webirc(struct Client *client_p, struct Client *source_p, int parc, const char IsGotId(client_p) ? client_p->username : "webirc", IsGotId(client_p) ? client_p->username : "webirc", (struct sockaddr *) &client_p->localClient->ip, - client_p->localClient->ip.ss_family); + client_p->localClient->ip.ss_family, NULL); if (aconf == NULL || !(aconf->status & CONF_CLIENT)) return 0; if (!IsConfDoSpoofIp(aconf) || irccmp(aconf->name, "webirc.")) diff --git a/include/client.h b/include/client.h index 4190c779..aad68a6d 100644 --- a/include/client.h +++ b/include/client.h @@ -230,6 +230,7 @@ struct LocalUser * agreed. lets get rid of it someday! --nenolod */ char *passwd; + char *auth_user; char *opername; /* name of operator{} block being used or tried (challenge) */ char *challenge; char *fullcaps; diff --git a/include/hostmask.h b/include/hostmask.h index ee49dda4..fa219ad3 100644 --- a/include/hostmask.h +++ b/include/hostmask.h @@ -39,24 +39,24 @@ enum int parse_netmask(const char *, struct sockaddr *, int *); struct ConfItem *find_conf_by_address(const char *host, const char *sockhost, const char *orighost, struct sockaddr *, - int, int, const char *); + int, int, const char *, const char *); struct ConfItem *find_exact_conf_by_address(const char *address, int type, const char *username); -void add_conf_by_address(const char *, int, const char *, struct ConfItem *); +void add_conf_by_address(const char *, int, const char *, const char *, struct ConfItem *); void delete_one_address_conf(const char *, struct ConfItem *); void clear_out_address_conf(void); void clear_out_address_conf_bans(void); void init_host_hash(void); struct ConfItem *find_address_conf(const char *host, const char *sockhost, const char *, const char *, struct sockaddr *, - int); + int, char *); struct ConfItem *find_dline(struct sockaddr *, int); #define find_kline(x) (find_conf_by_address((x)->host, (x)->sockhost, \ (x)->orighost, \ (struct sockaddr *)&(x)->localClient->ip, CONF_KILL,\ - (x)->localClient->ip.ss_family, (x)->username)) + (x)->localClient->ip.ss_family, (x)->username, NULL)) void report_Klines(struct Client *); void report_auth(struct Client *); @@ -99,6 +99,8 @@ struct AddressRec /* Only checked if !(type & 1)... */ const char *username; + /* Only checked if type == CONF_CLIENT */ + const char *auth_user; struct ConfItem *aconf; /* The next record in this hash bucket. */ diff --git a/modules/m_dline.c b/modules/m_dline.c index ef7c1cdc..213a0456 100644 --- a/modules/m_dline.c +++ b/modules/m_dline.c @@ -339,7 +339,7 @@ apply_dline(struct Client *source_p, const char *dlhost, int tdline_time, char * { rb_snprintf(dlbuffer, sizeof(dlbuffer), "%s (%s)", reason, current_date); aconf->passwd = rb_strdup(dlbuffer); - add_conf_by_address(aconf->host, CONF_DLINE, NULL, aconf); + add_conf_by_address(aconf->host, CONF_DLINE, NULL, NULL, aconf); write_confitem(DLINE_TYPE, source_p, NULL, aconf->host, reason, oper_reason, current_date, 0); } diff --git a/modules/m_kline.c b/modules/m_kline.c index fd9a2059..2f888237 100644 --- a/modules/m_kline.c +++ b/modules/m_kline.c @@ -492,7 +492,7 @@ static void apply_kline(struct Client *source_p, struct ConfItem *aconf, const char *reason, const char *oper_reason, const char *current_date) { - add_conf_by_address(aconf->host, CONF_KILL, aconf->user, aconf); + add_conf_by_address(aconf->host, CONF_KILL, aconf->user, NULL, aconf); write_confitem(KLINE_TYPE, source_p, aconf->user, aconf->host, reason, oper_reason, current_date, 0); } @@ -716,7 +716,7 @@ already_placed_kline(struct Client *source_p, const char *luser, const char *lho else piphost = NULL; - aconf = find_conf_by_address(lhost, NULL, NULL, (struct sockaddr *)piphost, CONF_KILL, t, luser); + aconf = find_conf_by_address(lhost, NULL, NULL, (struct sockaddr *)piphost, CONF_KILL, t, luser, NULL); if (aconf != NULL) { /* The above was really a lookup of a single IP, diff --git a/modules/m_pass.c b/modules/m_pass.c index 1f4255e2..0cc0747b 100644 --- a/modules/m_pass.c +++ b/modules/m_pass.c @@ -60,6 +60,9 @@ DECLARE_MODULE_AV1(pass, NULL, NULL, pass_clist, NULL, NULL, "$Revision: 3550 $" static int mr_pass(struct Client *client_p, struct Client *source_p, int parc, const char *parv[]) { + char *auth_user, *pass, *buf; + buf = LOCAL_COPY(parv[1]); + if(client_p->localClient->passwd) { memset(client_p->localClient->passwd, 0, @@ -68,6 +71,22 @@ mr_pass(struct Client *client_p, struct Client *source_p, int parc, const char * } client_p->localClient->passwd = rb_strndup(parv[1], PASSWDLEN); + + if ((pass = strchr(buf, ':')) != NULL) + { + *pass++ = '\0'; + auth_user = buf; + } + else + { + pass = buf; + auth_user = NULL; + } + + client_p->localClient->passwd = rb_strndup(pass, PASSWDLEN); + + if(auth_user) + client_p->localClient->auth_user = rb_strndup(auth_user, PASSWDLEN); /* These are for servers only */ if(parc > 2 && client_p->user == NULL) diff --git a/modules/m_stats.c b/modules/m_stats.c index c013c992..e63c0de6 100644 --- a/modules/m_stats.c +++ b/modules/m_stats.c @@ -497,7 +497,7 @@ stats_auth (struct Client *source_p) else if((ConfigFileEntry.stats_i_oper_only == 1) && !IsOper (source_p)) { struct ConfItem *aconf; - char *name, *host, *pass, *user, *classname; + char *name, *host, *pass = "*", *user, *classname; int port; if(MyConnect (source_p)) @@ -505,18 +505,20 @@ stats_auth (struct Client *source_p) (struct sockaddr *)&source_p->localClient->ip, CONF_CLIENT, source_p->localClient->ip.ss_family, - source_p->username); + source_p->username, NULL); else aconf = find_conf_by_address (source_p->host, NULL, NULL, NULL, CONF_CLIENT, - 0, source_p->username); + 0, source_p->username, NULL); if(aconf == NULL) return; get_printable_conf (aconf, &name, &host, &pass, &user, &port, &classname); + if(!EmptyString(aconf->spasswd)) + pass = aconf->spasswd; sendto_one_numeric(source_p, RPL_STATSILINE, form_str(RPL_STATSILINE), - name, show_iline_prefix(source_p, aconf, user), + name, pass, show_iline_prefix(source_p, aconf, user), host, port, classname); } @@ -545,10 +547,10 @@ stats_tklines(struct Client *source_p) (struct sockaddr *)&source_p->localClient->ip, CONF_KILL, source_p->localClient->ip.ss_family, - source_p->username); + source_p->username, NULL); else aconf = find_conf_by_address (source_p->host, NULL, NULL, NULL, CONF_KILL, - 0, source_p->username); + 0, source_p->username, NULL); if(aconf == NULL) return; @@ -611,10 +613,10 @@ stats_klines(struct Client *source_p) (struct sockaddr *)&source_p->localClient->ip, CONF_KILL, source_p->localClient->ip.ss_family, - source_p->username); + source_p->username, NULL); else aconf = find_conf_by_address (source_p->host, NULL, NULL, NULL, CONF_KILL, - 0, source_p->username); + 0, source_p->username, NULL); if(aconf == NULL) return; diff --git a/modules/m_testline.c b/modules/m_testline.c index 63f99af0..993e995d 100644 --- a/modules/m_testline.c +++ b/modules/m_testline.c @@ -155,7 +155,7 @@ mo_testline(struct Client *client_p, struct Client *source_p, int parc, const ch #ifdef RB_IPV6 (type == HM_IPV6) ? AF_INET6 : #endif - AF_INET) : 0))) + AF_INET) : 0, NULL))) { static char buf[HOSTLEN+USERLEN+2]; diff --git a/src/hostmask.c b/src/hostmask.c index e322e861..a0a193d5 100644 --- a/src/hostmask.c +++ b/src/hostmask.c @@ -208,7 +208,7 @@ struct ConfItem * find_conf_by_address(const char *name, const char *sockhost, const char *orighost, struct sockaddr *addr, int type, int fam, - const char *username) + const char *username, const char *auth_user) { unsigned long hprecv = 0; struct ConfItem *hprec = NULL; @@ -231,12 +231,11 @@ find_conf_by_address(const char *name, const char *sockhost, if(arec->type == (type & ~0x1) && arec->masktype == HM_IPV6 && comp_with_mask_sock(addr, (struct sockaddr *)&arec->Mask.ipa.addr, - arec->Mask.ipa.bits) && (type & 0x1 - || - match(arec-> - username, - username)) - && arec->precedence > hprecv) + arec->Mask.ipa.bits) && + (type & 0x1 || match(arec-> username, username)) && + (type != CONF_CLIENT || !arec->auth_user || + (auth_user && match(arec->auth_user, auth_user))) && + arec->precedence > hprecv) { hprecv = arec->precedence; hprec = arec->aconf; @@ -252,10 +251,12 @@ find_conf_by_address(const char *name, const char *sockhost, for (arec = atable[hash_ipv4(addr, b)]; arec; arec = arec->next) if(arec->type == (type & ~0x1) && arec->masktype == HM_IPV4 && - arec->precedence > hprecv && comp_with_mask_sock(addr, (struct sockaddr *)&arec->Mask.ipa.addr, arec->Mask.ipa.bits) && - (type & 0x1 || match(arec->username, username))) + (type & 0x1 || match(arec->username, username)) && + (type != CONF_CLIENT || !arec->auth_user || + (auth_user && match(arec->auth_user, auth_user))) && + arec->precedence > hprecv) { hprecv = arec->precedence; hprec = arec->aconf; @@ -276,6 +277,8 @@ find_conf_by_address(const char *name, const char *sockhost, (arec->masktype == HM_HOST) && arec->precedence > hprecv && match(arec->Mask.hostname, orighost) && + (type != CONF_CLIENT || !arec->auth_user || + (auth_user && match(arec->auth_user, auth_user))) && (type & 0x1 || match(arec->username, username))) { hprecv = arec->precedence; @@ -294,6 +297,8 @@ find_conf_by_address(const char *name, const char *sockhost, arec->precedence > hprecv && (match(arec->Mask.hostname, orighost) || (sockhost && match(arec->Mask.hostname, sockhost))) && + (type != CONF_CLIENT || !arec->auth_user || + (auth_user && match(arec->auth_user, auth_user))) && (type & 0x1 || match(arec->username, username))) { hprecv = arec->precedence; @@ -314,6 +319,8 @@ find_conf_by_address(const char *name, const char *sockhost, (arec->masktype == HM_HOST) && arec->precedence > hprecv && match(arec->Mask.hostname, name) && + (type != CONF_CLIENT || !arec->auth_user || + (auth_user && match(arec->auth_user, auth_user))) && (type & 0x1 || match(arec->username, username))) { hprecv = arec->precedence; @@ -332,6 +339,8 @@ find_conf_by_address(const char *name, const char *sockhost, arec->precedence > hprecv && (match(arec->Mask.hostname, name) || (sockhost && match(arec->Mask.hostname, sockhost))) && + (type != CONF_CLIENT || !arec->auth_user || + (auth_user && match(arec->auth_user, auth_user))) && (type & 0x1 || match(arec->username, username))) { hprecv = arec->precedence; @@ -350,13 +359,13 @@ find_conf_by_address(const char *name, const char *sockhost, */ struct ConfItem * find_address_conf(const char *host, const char *sockhost, const char *user, - const char *notildeuser, struct sockaddr *ip, int aftype) + const char *notildeuser, struct sockaddr *ip, int aftype, char *auth_user) { struct ConfItem *iconf, *kconf; const char *vuser; /* Find the best I-line... If none, return NULL -A1kmm */ - if(!(iconf = find_conf_by_address(host, sockhost, NULL, ip, CONF_CLIENT, aftype, user))) + if(!(iconf = find_conf_by_address(host, sockhost, NULL, ip, CONF_CLIENT, aftype, user, auth_user))) return NULL; /* Find what their visible username will be. * Note that the username without tilde may contain one char more. @@ -368,7 +377,7 @@ find_address_conf(const char *host, const char *sockhost, const char *user, return iconf; /* Find the best K-line... -A1kmm */ - kconf = find_conf_by_address(host, sockhost, NULL, ip, CONF_KILL, aftype, user); + kconf = find_conf_by_address(host, sockhost, NULL, ip, CONF_KILL, aftype, user, NULL); /* If they are K-lined, return the K-line */ if(kconf) @@ -385,11 +394,11 @@ find_address_conf(const char *host, const char *sockhost, const char *user, if(p) { *p = '\0'; - kconf = find_conf_by_address(p+1, NULL, NULL, ip, CONF_KILL, aftype, iconf->name); + kconf = find_conf_by_address(p+1, NULL, NULL, ip, CONF_KILL, aftype, iconf->name, NULL); *p = '@'; } else - kconf = find_conf_by_address(iconf->name, NULL, NULL, ip, CONF_KILL, aftype, vuser); + kconf = find_conf_by_address(iconf->name, NULL, NULL, ip, CONF_KILL, aftype, vuser, NULL); if(kconf) return kconf; @@ -399,7 +408,7 @@ find_address_conf(const char *host, const char *sockhost, const char *user, * -- jilles */ if(user != vuser) { - kconf = find_conf_by_address(host, sockhost, NULL, ip, CONF_KILL, aftype, vuser); + kconf = find_conf_by_address(host, sockhost, NULL, ip, CONF_KILL, aftype, vuser, NULL); if(kconf) return kconf; } @@ -416,10 +425,10 @@ struct ConfItem * find_dline(struct sockaddr *addr, int aftype) { struct ConfItem *eline; - eline = find_conf_by_address(NULL, NULL, NULL, addr, CONF_EXEMPTDLINE | 1, aftype, NULL); + eline = find_conf_by_address(NULL, NULL, NULL, addr, CONF_EXEMPTDLINE | 1, aftype, NULL, NULL); if(eline) return eline; - return find_conf_by_address(NULL, NULL, NULL, addr, CONF_DLINE | 1, aftype, NULL); + return find_conf_by_address(NULL, NULL, NULL, addr, CONF_DLINE | 1, aftype, NULL, NULL); } /* void find_exact_conf_by_address(const char*, int, const char *) @@ -485,7 +494,7 @@ find_exact_conf_by_address(const char *address, int type, const char *username) * Side-effects: Adds this entry to the hash table. */ void -add_conf_by_address(const char *address, int type, const char *username, struct ConfItem *aconf) +add_conf_by_address(const char *address, int type, const char *username, const char *auth_user, struct ConfItem *aconf) { static unsigned long prec_value = 0xFFFFFFFF; int masktype, bits; @@ -522,6 +531,7 @@ add_conf_by_address(const char *address, int type, const char *username, struct atable[hv] = arec; } arec->username = username; + arec->auth_user = auth_user; arec->aconf = aconf; arec->precedence = prec_value--; arec->type = type; @@ -694,7 +704,7 @@ show_iline_prefix(struct Client *sptr, struct ConfItem *aconf, char *name) void report_auth(struct Client *client_p) { - char *name, *host, *pass, *user, *classname; + char *name, *host, *pass = "*", *user, *classname; struct AddressRec *arec; struct ConfItem *aconf; int i, port; @@ -710,10 +720,13 @@ report_auth(struct Client *client_p) get_printable_conf(aconf, &name, &host, &pass, &user, &port, &classname); + + if(!EmptyString(aconf->spasswd)) + pass = aconf->spasswd; sendto_one_numeric(client_p, RPL_STATSILINE, form_str(RPL_STATSILINE), - name, show_iline_prefix(client_p, aconf, user), + name, pass, show_iline_prefix(client_p, aconf, user), show_ip_conf(aconf, client_p) ? host : "255.255.255.255", port, classname); } diff --git a/src/kdparse.c b/src/kdparse.c index 69a0c568..3d82b718 100644 --- a/src/kdparse.c +++ b/src/kdparse.c @@ -110,7 +110,7 @@ parse_k_file(FILE * file) user_field, operreason_field, date_field); if(aconf->host != NULL) - add_conf_by_address(aconf->host, CONF_KILL, aconf->user, aconf); + add_conf_by_address(aconf->host, CONF_KILL, aconf->user, NULL, aconf); } } diff --git a/src/messages.tab b/src/messages.tab index 99947739..2166b646 100644 --- a/src/messages.tab +++ b/src/messages.tab @@ -235,7 +235,7 @@ static const char * replies[] = { /* 212 RPL_STATSCOMMANDS, */ "%s %u %u :%u", /* 213 RPL_STATSCLINE, */ "C %s %s %s %d %s", /* 214 RPL_STATSNLINE, */ NULL, -/* 215 RPL_STATSILINE, */ "I %s * %s@%s %d %s", +/* 215 RPL_STATSILINE, */ "I %s %s %s@%s %d %s", /* 216 RPL_STATSKLINE, */ "%c %s * %s :%s%s%s", /* 217 RPL_STATSQLINE, */ "%c %d %s :%s", /* 218 RPL_STATSYLINE, */ "Y %s %d %d %d %u %d.%d %d.%d %u", diff --git a/src/newconf.c b/src/newconf.c index 47f95690..92671f39 100644 --- a/src/newconf.c +++ b/src/newconf.c @@ -846,7 +846,7 @@ conf_end_auth(struct TopConf *tc) collapse(yy_aconf->user); collapse(yy_aconf->host); conf_add_class_to_conf(yy_aconf); - add_conf_by_address(yy_aconf->host, CONF_CLIENT, yy_aconf->user, yy_aconf); + add_conf_by_address(yy_aconf->host, CONF_CLIENT, yy_aconf->user, yy_aconf->spasswd, yy_aconf); RB_DLINK_FOREACH_SAFE(ptr, next_ptr, yy_aconf_list.head) { @@ -855,6 +855,9 @@ conf_end_auth(struct TopConf *tc) if(yy_aconf->passwd) yy_tmp->passwd = rb_strdup(yy_aconf->passwd); + if(yy_aconf->spasswd) + yy_tmp->spasswd = rb_strdup(yy_aconf->spasswd); + /* this will always exist.. */ yy_tmp->name = rb_strdup(yy_aconf->name); @@ -869,7 +872,7 @@ conf_end_auth(struct TopConf *tc) conf_add_class_to_conf(yy_tmp); - add_conf_by_address(yy_tmp->host, CONF_CLIENT, yy_tmp->user, yy_tmp); + add_conf_by_address(yy_tmp->host, CONF_CLIENT, yy_tmp->user, yy_tmp->spasswd, yy_tmp); rb_dlinkDestroy(ptr, &yy_aconf_list); } @@ -909,6 +912,15 @@ conf_set_auth_user(void *data) rb_dlinkAddAlloc(yy_tmp, &yy_aconf_list); } +static void +conf_set_auth_auth_user(void *data) +{ + if(yy_aconf->spasswd) + memset(yy_aconf->spasswd, 0, strlen(yy_aconf->spasswd)); + rb_free(yy_aconf->spasswd); + yy_aconf->spasswd = rb_strdup(data); +} + static void conf_set_auth_passwd(void *data) { @@ -1318,7 +1330,7 @@ conf_set_exempt_ip(void *data) yy_tmp->passwd = rb_strdup("*"); yy_tmp->host = rb_strdup(data); yy_tmp->status = CONF_EXEMPTDLINE; - add_conf_by_address(yy_tmp->host, CONF_EXEMPTDLINE, NULL, yy_tmp); + add_conf_by_address(yy_tmp->host, CONF_EXEMPTDLINE, NULL, NULL, yy_tmp); } static int @@ -1978,6 +1990,7 @@ static struct ConfEntry conf_class_table[] = static struct ConfEntry conf_auth_table[] = { { "user", CF_QSTRING, conf_set_auth_user, 0, NULL }, + { "auth_user", CF_QSTRING, conf_set_auth_auth_user, 0, NULL }, { "password", CF_QSTRING, conf_set_auth_passwd, 0, NULL }, { "class", CF_QSTRING, conf_set_auth_class, 0, NULL }, { "spoof", CF_QSTRING, conf_set_auth_spoof, 0, NULL }, diff --git a/src/s_conf.c b/src/s_conf.c index a0060d21..f27c6aba 100644 --- a/src/s_conf.c +++ b/src/s_conf.c @@ -308,7 +308,8 @@ verify_access(struct Client *client_p, const char *username) aconf = find_address_conf(client_p->host, client_p->sockhost, client_p->username, client_p->username, (struct sockaddr *) &client_p->localClient->ip, - client_p->localClient->ip.ss_family); + client_p->localClient->ip.ss_family, + client_p->localClient->auth_user); } else { @@ -317,7 +318,8 @@ verify_access(struct Client *client_p, const char *username) aconf = find_address_conf(client_p->host, client_p->sockhost, non_ident, client_p->username, (struct sockaddr *) &client_p->localClient->ip, - client_p->localClient->ip.ss_family); + client_p->localClient->ip.ss_family, + client_p->localClient->auth_user); } if(aconf == NULL) @@ -930,7 +932,7 @@ add_temp_kline(struct ConfItem *aconf) } aconf->flags |= CONF_FLAGS_TEMPORARY; - add_conf_by_address(aconf->host, CONF_KILL, aconf->user, aconf); + add_conf_by_address(aconf->host, CONF_KILL, aconf->user, NULL, aconf); } /* add_temp_dline() @@ -964,7 +966,7 @@ add_temp_dline(struct ConfItem *aconf) } aconf->flags |= CONF_FLAGS_TEMPORARY; - add_conf_by_address(aconf->host, CONF_DLINE, aconf->user, aconf); + add_conf_by_address(aconf->host, CONF_DLINE, aconf->user, NULL, aconf); } /* expire_tkline() @@ -1474,7 +1476,7 @@ conf_add_d_conf(struct ConfItem *aconf) } else { - add_conf_by_address(aconf->host, CONF_DLINE, NULL, aconf); + add_conf_by_address(aconf->host, CONF_DLINE, NULL, NULL, aconf); } }