Răsfoiți Sursa

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 ani în urmă
părinte
comite
6ca9a01f40
3 a modificat fișierele cu 47 adăugiri și 9 ștergeri
  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)