فهرست منبع

Only validate hosts for the linking bot, not all

This fixes the previous code causing the first user to have the matching
host to be returned, thus causing a non-match on the user handle and
then denying the link. This change now allows multiple users/bots
to have the same hostname, but requires that the linking bot
matches its own hosts
Bryan Drewery 13 سال پیش
والد
کامیت
6ca9a01f40
3فایلهای تغییر یافته به همراه47 افزوده شده و 9 حذف شده
  1. 9 9
      src/dcc.c
  2. 37 0
      src/userrec.c
  3. 1 0
      src/users.h

+ 9 - 9
src/dcc.c

@@ -1803,20 +1803,20 @@ dcc_telnet_id(int idx, char *buf, int atr)
     char *p = strchr(dcc[idx].host, '@');
     strlcpy(user, dcc[idx].host, p - dcc[idx].host + 1);
     simple_snprintf(sip, sizeof(sip), "-telnet!%s@%s", user, iptostr(htonl(dcc[idx].addr)));
+    struct userrec *u = get_user_by_handle(userlist, nick);
 
-    struct userrec *u = NULL;
     ok = 1;
 
-    if (!u)
-      u = get_user_by_host(sip);			/* Check for -telnet!ident@ip */
-    if (!u)
-      u = get_user_by_host(shost);		/* Check for -telnet!ident@host */
-    if (!u)
-      ok = 0;
+    // Require that the linking bot has a matching host
 
-    // Restrict connect to matching the user who they claim to be
-    if (u && strcasecmp(nick, u->handle))
+    if (u) {
+      /* Check for -telnet!ident@ip or -telnet!ident@host */
+      if (!user_has_matching_host(nick, u, sip) && !user_has_matching_host(nick, u, shost)) {
+	ok = 0;
+      }
+    } else {
       ok = 0;
+    }
 
     if (!ok) {
       putlog(LOG_BOTS, "*", "Denied link to '%s': Host not recognized: %s", nick, dcc[idx].host);

+ 37 - 0
src/userrec.c

@@ -292,6 +292,43 @@ bool user_has_host(const char *handle, struct userrec *u, char *host)
   return 0;
 }
 
+bool user_has_matching_host(const char *handle, struct userrec *u, char *host)
+{
+  if (host == NULL) {
+    return false;
+  }
+  rmspace(host);
+  if (!host[0]) {
+    return false;
+  }
+
+  if (!u && handle) {
+    u = get_user_by_handle(userlist, (char *) handle);
+  }
+
+  if (!u) {
+    return false;
+  }
+
+  /* do CIDR matching if given host is an ip */
+  char *p = NULL;
+  bool do_cidr = 0;
+  struct list_type *q = NULL;
+
+  do_cidr = ((p = strchr(host, '@')) && is_dotted_ip(++p));
+
+  for (q = (struct list_type *) get_user(&USERENTRY_HOSTS, u); q; q = q->next) {
+      if (do_cidr && match_cidr(q->extra, host)) {
+	  return true;
+      }
+      if (wild_match(q->extra, host)) {
+	return true;
+      }
+  }
+
+  return false;
+}
+
 void convert_password(struct userrec *u)
 {
   char *oldpass = (char *) get_user(&USERENTRY_PASS1, u);

+ 1 - 0
src/users.h

@@ -96,6 +96,7 @@ struct user_entry_type *find_entry_type(char *);
 struct user_entry *find_user_entry(struct user_entry_type *, struct userrec *);
 void *get_user(struct user_entry_type *, struct userrec *);
 bool user_has_host(const char *, struct userrec *, char *);
+bool user_has_matching_host(const char *handle, struct userrec *u, char *host);
 bool set_user(struct user_entry_type *, struct userrec *, void *);
 
 #define is_bot(u)	((u) && (u)->bot)