bug-inetutils
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

inetutils


From: Sergey Poznyakoff
Subject: inetutils
Date: Sat, 02 Jun 2001 17:20:08 +0300

Bonjour, Alain

I've got some notices about talk/talkd in inetutils. Here they are:

ChangeLog
  * libinetutils/ttymsg.c: Simple check for '/' in the line name is
    way too week: it doesn't work for tty names like pts/2, which are
    perfectly OK. Changed to more sophisticated one: all "./", "../"
    references in the name are resolved and the resulting name is
    compared with PATH_TTY_PFX. If it lies under it, everything's
    Ok. Otherwise we just bail out and quit.
  * talk/display.c: Added check for *text == '\a' to produce audible
    bell. 
  * talk/io.c: changed \007's in initial message to beep() after
    message(). On solaris's AT386 those \007 just produce ^G on
    the screen.
    Changed read(0, buf, nb) to getch() in loop. Reason: read()
    returns raw data from console, thus pressing <enter> returns
    '\r' which gets displayed on console as ^M, because display.c
    is expecting to get '\n'. getch() returns '\n' and everything
    goes smooth.
  * talk/announce.c: syslog error message from ttymsg(). One never
    knows...
  * talkd/process.c: changed find_user(). Previous version returned
    first console the remote party was logged onto. This one returns
    the one where he currently is. This is a slightly modified version
    of berkeley's find_user() dated 1997/04/06. 

Index: libinetutils/ttymsg.c
===================================================================
RCS file: /cvs/inetutils/libinetutils/ttymsg.c,v
retrieving revision 1.11
diff -p -u -w -b -r1.11 ttymsg.c
--- libinetutils/ttymsg.c       2000/08/14 02:56:35     1.11
+++ libinetutils/ttymsg.c       2001/06/02 13:31:27
@@ -74,16 +74,6 @@ ttymsg (struct iovec *iov, int iovcnt, c
   if (iovcnt > (int)(sizeof (localiov) / sizeof (localiov[0])))
     return (char *)("too many iov's (change code in wall/ttymsg.c)");
 
-  /* we're watching for '/', ".", ".."  '/' --> somebody could specify
-     tty as ../etc/passwd ".", ".." those are not security related it's
-     just sanity checks.  */
-  if (strchr (line, '/'))
-    {
-      /* A slash is an attempt to break security... */
-      (void) snprintf (errbuf, sizeof(errbuf), "'/' in \"%s\"", line);
-      return (errbuf);
-    }
-
   device = malloc (sizeof PATH_TTY_PFX - 1 + strlen (line) + 1);
   if (! device)
     {
@@ -94,6 +84,13 @@ ttymsg (struct iovec *iov, int iovcnt, c
 
   strcpy (device, PATH_TTY_PFX);
   strcat (device, line);
+  normalize_path (device);
+  if (strncmp (device, PATH_TTY_PFX, strlen(PATH_TTY_PFX)))
+    {
+      /* An attempt to break security... */
+      snprintf (errbuf, sizeof(errbuf), "bad line name", line);
+      return (errbuf);
+    }
 
   /*
    * open will fail on slip lines or exclusive-use lines
@@ -244,3 +241,60 @@ fork2 (void)
 
   return -1;
 }
+
+char *
+normalize_path (char *path, const char *delim)
+{
+  int len;
+  char *p;
+  
+  if (!path)
+    return path;
+
+  len = strlen (path);
+
+  /* Empty string is returned as is */
+  if (len == 0)
+    return path;
+  
+  /* delete trailing delimiter if any */
+  if (len && path[len-1] == delim[0])
+    path[len-1] = 0;
+
+  /* Eliminate any /../ */
+  for (p = strchr (path, '.'); p; p = strchr (p, '.'))
+    {
+      if (p > path && p[-1] == delim[0])
+       {
+         if (p[1] == '.' && (p[2] == 0 || p[2] == delim[0]))
+           /* found */
+           {
+             char *q, *s;
+
+             /* Find previous delimiter */
+             for (q = p-2; *q != delim[0] && q >= path; q--)
+               ;
+
+             if (q < path)
+               break;
+             /* Copy stuff */
+             s = p + 2;
+             p = q;
+             while (*q++ = *s++)
+               ;
+             continue;
+           }
+       }
+
+      p++;
+    }
+
+  if (path[0] == 0)
+    {
+      path[0] = delim[0];
+      path[1] = 0;
+    }
+  
+  return path;
+}
+             
Index: talk/display.c
===================================================================
RCS file: /cvs/inetutils/talk/display.c,v
retrieving revision 1.4
diff -p -u -w -b -r1.4 display.c
--- talk/display.c      2000/07/19 04:08:38     1.4
+++ talk/display.c      2001/06/02 13:31:27
@@ -76,6 +76,12 @@ display(register xwin_t *win, register c
                        text++;
                        continue;
                }
+               if (*text == '\a') {
+                       beep();
+                       wrefresh(curscr);
+                       text++;
+                       continue;
+               }
                /* erase character */
                if (*text == win->cerase) {
                        wmove(win->x_win, win->x_line, max(--win->x_col, 0));
Index: talk/io.c
===================================================================
RCS file: /cvs/inetutils/talk/io.c,v
retrieving revision 1.6
diff -p -u -w -b -r1.6 io.c
--- talk/io.c   2000/07/19 04:08:38     1.6
+++ talk/io.c   2001/06/02 13:31:28
@@ -74,11 +74,12 @@ talk()
 {
        fd_set read_template, read_set;
        int stdin_fd = fileno (stdin);
-       int nb, num_fds;
+       int i, nb, num_fds;
        char buf[BUFSIZ];
        struct timeval wait;
 
-       message("Connection established\007\007\007");
+       message("Connection established");
+       beep();
        current_line = 0;
 
        /*
@@ -118,7 +119,8 @@ talk()
                         * curses's output routines would screw up
                         */
                        ioctl(0, FIONREAD, (struct sgttyb *) &nb);
-                       nb = read(0, buf, nb);
+                       for (i = 0; i < nb; i++)
+                               buf[i] = getch();
                        display(&my_win, buf, nb);
                        /* might lose data here because sockt is non-blocking */
                        write(sockt, buf, nb);
cvs server: Diffing talkd
Index: talkd/announce.c
===================================================================
RCS file: /cvs/inetutils/talkd/announce.c,v
retrieving revision 1.16
diff -p -u -w -b -r1.16 announce.c
--- talkd/announce.c    2000/08/09 05:44:24     1.16
+++ talkd/announce.c    2001/06/02 13:31:28
@@ -151,7 +151,7 @@ print_mesg(char *tty, CTL_MSG *request, 
        char line_buf[N_LINES][N_CHARS];
        int sizes[N_LINES];
        char big_buf[N_LINES*N_CHARS];
-       char *bptr, *lptr, *vis_user;
+       char *bptr, *lptr, *vis_user, *cp;
        int i, j, max_size;
 
        i = 0;
@@ -208,8 +208,11 @@ print_mesg(char *tty, CTL_MSG *request, 
         * stack up processes trying to write messages to a tty
         * that is permanently blocked.
         */
-       if (ttymsg(&iovec, 1, tty, RING_WAIT - 5) != NULL)
+       if ((cp = ttymsg(&iovec, 1, tty, RING_WAIT - 5)) != NULL)
+         {
+           syslog(LOG_CRIT, "%s", cp);
                return (FAILED);
+         }
 
        return (SUCCESS);
 }
Index: process.c
===================================================================
RCS file: /cvs/inetutils/talkd/process.c,v
retrieving revision 1.9
diff -p -u -w -b -r1.9 process.c
--- process.c   2000/07/19 04:08:38     1.9
+++ process.c   2001/06/02 14:03:08
@@ -179,42 +179,49 @@ do_announce(register CTL_MSG *mp, CTL_RE
 int
 find_user(char *name, char *tty)
 {
-       struct utmp ubuf;
+       struct utmp *uptr;
        int status;
-       FILE *fd;
        struct stat statb;
-       char line[sizeof(ubuf.ut_line) + 1];
-       char ftty[sizeof(PATH_DEV) - 1 + sizeof(line)];
+       char ftty[sizeof(PATH_DEV) + sizeof(uptr->ut_line)];
+       time_t last_time = 0;
+       int notty;
 
-       if ((fd = fopen(PATH_UTMP, "r")) == NULL) {
-               fprintf(stderr, "talkd: can't read %s.\n", PATH_UTMP);
-               return (FAILED);
-       }
-#define SCMPN(a, b)    strncmp(a, b, sizeof (a))
+       notty = (*tty == '\0');
+
        status = NOT_HERE;
-       (void) strcpy(ftty, PATH_DEV);
-       while (fread((char *) &ubuf, sizeof ubuf, 1, fd) == 1)
-               if (SCMPN(ubuf.ut_name, name) == 0) {
-                       strncpy(line, ubuf.ut_line, sizeof(ubuf.ut_line));
-                       line[sizeof(ubuf.ut_line)] = '\0';
-                       if (*tty == '\0') {
-                               status = PERMISSION_DENIED;
+       strcpy(ftty, PATH_DEV);
+       setutent();
+       while ((uptr = getutent())!=NULL) {
+#ifdef USER_PROCESS
+               if (uptr->ut_type!=USER_PROCESS) 
+                       continue;
+#endif
+               if (!strncmp(uptr->ut_name, name, sizeof(uptr->ut_name))) {
+                       if (notty) {
                                /* no particular tty was requested */
-                               (void) strcpy(ftty + sizeof(PATH_DEV) - 1,
-                                   line);
+                               strncpy(ftty+5, uptr->ut_line, sizeof(ftty)-5);
+                               ftty[sizeof(ftty)-1] = 0;
+
                                if (stat(ftty, &statb) == 0) {
-                                       if (!(statb.st_mode & 020))
+                                       if (!(statb.st_mode & S_IWGRP)) {
+                                           if (status!=SUCCESS)
+                                               status = PERMISSION_DENIED;
                                                continue;
-                                       (void) strcpy(tty, line);
+                                       }
+                                       if (statb.st_atime > last_time) {
+                                               last_time = statb.st_atime;
+                                               strcpy(tty, uptr->ut_line);
                                        status = SUCCESS;
-                                       break;
                                }
+                                       continue;
                        }
-                       if (strcmp(line, tty) == 0) {
+                       }
+                       if (!strcmp(uptr->ut_line, tty)) {
                                status = SUCCESS;
                                break;
                        }
+               }
                }
-       fclose(fd);
-       return (status);
+       endutent();
+       return status;
 }


So how about your idea of breaking the stuff into libraries? Oh, by
the way, what was the reason of including ifconfig in the package? The
stuff is heavily OS-dependent, it doesn't seem to belong here, does
it? Anyway, I am trying to make it compile and work on Solaris/x86
now...


Cheers,
Sergey



reply via email to

[Prev in Thread] Current Thread [Next in Thread]