Impliment elements of TCP Wrappers's `safe_finger'.

* if run by root (or root process) drop privs
* ensure output size is not infinate (net finger only)
* ensure output lines are not infinate in length (net finger only)
* do not allow finger client to run longer than 3 minutes (net finger only)
This commit is contained in:
David E. O'Brien 1999-05-08 00:46:06 +00:00
parent f66190fa14
commit dd5288f3a5
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=46662
3 changed files with 46 additions and 2 deletions

View File

@ -55,7 +55,7 @@ static char copyright[] =
static char sccsid[] = "@(#)finger.c 8.5 (Berkeley) 5/4/95";
#else
static const char rcsid[] =
"$Id$";
"$Id: finger.c,v 1.12 1997/07/02 06:34:48 charnier Exp $";
#endif
#endif /* not lint */
@ -154,6 +154,17 @@ main(argc, argv)
{
int envargc, argcnt;
char *envargv[3];
struct passwd *pw;
if (getuid() == 0 || geteuid() == 0) {
if ((pw = getpwnam(UNPRIV_NAME)) && pw->pw_uid > 0) {
setgid(pw->pw_gid);
setuid(pw->pw_uid);
} else {
setgid(UNPRIV_UGID);
setuid(UNPRIV_UGID);
}
}
(void) setlocale(LC_ALL, "");

View File

@ -34,6 +34,7 @@
* SUCH DAMAGE.
*
* @(#)finger.h 8.1 (Berkeley) 6/6/93
* $Id$
*/
typedef struct person {
@ -62,4 +63,9 @@ typedef struct where {
char host[UT_HOSTSIZE+1]; /* null terminated remote host name */
} WHERE;
#define UNPRIV_NAME "nobody" /* Preferred privilege level */
#define UNPRIV_UGID 32767 /* Default uid and gid */
#define OUTPUT_MAX 100000 /* Do not keep listinging forever */
#define TIME_LIMIT 360 /* Do not keep listinging forever */
#include "extern.h"

View File

@ -39,7 +39,7 @@
static char sccsid[] = "@(#)net.c 8.4 (Berkeley) 4/28/95";
#else
static const char rcsid[] =
"$Id: net.c,v 1.9 1997/08/01 20:10:44 wollman Exp $";
"$Id: net.c,v 1.10 1998/06/09 04:30:40 imp Exp $";
#endif
#endif /* not lint */
@ -58,12 +58,23 @@ static const char rcsid[] =
#include <ctype.h>
#include <string.h>
#include <sys/uio.h>
#include <signal.h>
#include <limits.h>
#include "finger.h"
void
cleanup(sig)
int sig;
{
exit(0);
}
void
netfinger(name)
char *name;
{
int cnt;
int line_len;
extern int lflag;
extern int Tflag;
register FILE *fp;
@ -80,6 +91,8 @@ netfinger(name)
if (!(host = rindex(name, '@')))
return;
*host++ = '\0';
signal(SIGALRM, cleanup);
(void) alarm(TIME_LIMIT);
if (isdigit(*host) && (defaddr.s_addr = inet_addr(host)) != -1) {
def.h_name = host;
def.h_addr_list = alist;
@ -152,7 +165,14 @@ netfinger(name)
*/
lastc = 0;
if ((fp = fdopen(s, "r")) != NULL) {
cnt = 0;
line_len = 0;
while ((c = getc(fp)) != EOF) {
if (++cnt > OUTPUT_MAX) {
printf("\n\n Output truncated at %d bytes...\n",
cnt - 1);
break;
}
if (c == 0x0d) {
if (lastc == '\r') /* ^M^M - skip dupes */
continue;
@ -171,6 +191,13 @@ netfinger(name)
}
}
putchar(c);
if (c != '\n' && ++line_len > _POSIX2_LINE_MAX) {
putchar('\\');
putchar('\n');
lastc = '\r';
}
if (lastc == '\n' || lastc == '\r')
line_len = 0;
}
if (lastc != '\n')
putchar('\n');