[Top][All Lists]
[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
- inetutils,
Sergey Poznyakoff <=