Newsgroups: vmsnet.networks.tcp-ip.multinet
Subject: Re: Finger
From: jms@carat.arizona.edu (A virtually vegetal non-entity)
Date: 17 Nov 1992 11:47 MST  
Reply-To: jms@Arizona.EDU
Distribution: world,local
Organization: University of Arizona MIS Department - Mosaic Group
X-Lunar-Date: 5 days, 21 hours, 3 minutes since the full moon
News-Software: VAX/VMS VNEWS 1.50A   

I guess it all depends on what you want Finger to do for people.  On one
system I managed, we felt that the information that finger gave out was a
little too intrusive, and so I re-wrote finger to do the equivalent of a
"show users/full" and pass that back over the pipe.  I think it was about a
hundred lines of code.

On my system at home, the link is slow, so I want to discourage people from
fingering (especially since it doesn't tell them anything).  After
encountering a system manager who thought that security management meant
fingering every single system around every ten minutes, I wrote "JFINGER,"
which responds to finger requests by randomly picking a host from a list
of systems (generated from the multi-thousand HOSTS.TXT NIC tables),
fingering THAT host, and sending that data back.  

Ehud Gavron enhanced JFINGER two ways: one is to reply to fingers with
fingers of the fingerers own machine (read that one slowly, eh), and the
other is to hang forever on fingers from certain machines, which is a
strong discouragement to the folks on those machines from fingering you
at all.

Anyway: code below, for anyone interested. 

Joel M Snyder, 1103 E Spring Street, Tucson, AZ, 85719 
Phone: 602.882.4094 (voice) .4095 (FAX) .4093 (data)
BITNET: jms@Arizona  Internet: jms@arizona.edu  SPAN: 47541::telcom::jms
Yow!  I want my nose in lights!

/* JFINGER - replaces a FINGER server for Multinet; returns random answers */

/* This code is placed into the public domain. jms/920703 */

/* Modified:
	04-Jul-1992	Ehud Gavron	If SELF is defined, then this will
					finger the fingeree instead of a
			random host from a randomly unavailable file ;-) 

	12-Oct-1992	Ehud Gavron	The folks at bruno.cs.colorado.edu
					insist on fingering me several times
			a day in the hopes I would create a wide area 
			information server all of a sudden.  Although I have
			asked them nicely, they don't want to take my host
			out of their pinging tables.  This little addition,
			activated by  /DEFINE=(SELF,FUCKTHEM) makes Jfinger
			hang on the read.  Note: successive fingerings by
			them will cause one of the machines to run out of
			TCBs or process slots first.  I suspect it won't
			be me.  However, if it turns out it's me, I can
			always modify the code so ONE connection from them
			turns into 32767 sockets coming right back at them :) */


#include <stdio.h>
#ifndef SELF
#include <time.h>
#endif
#include <descrip.h>
#include "multinet_root:[multinet.include.sys]types.h"
#include "multinet_root:[multinet.include.sys]socket.h"
#include "multinet_root:[multinet.include.netinet]in.h"
#include "multinet_root:[multinet.include]netdb.h"

main()
{
	unsigned int seed, random, n, status;
	unsigned short lchan, rchan;	
	time_t now;
	struct tm *tptr;	
	FILE *hostfile;
	char ahost[25], buf[256];
	static struct {int Size; char *Ptr;} Descr={9 ,"SYS$INPUT"};
	struct servent *sp;
#ifdef	FUCKTHEM
	struct hostent *hp;
#endif
	struct sockaddr_in sin;

/*
 * Open up the LOCAL finger channel.  That's the one coming in to
 * us.  Read the record that the other end sent, and promptly ignore it.
 */
	status = SYS$ASSIGN(&Descr, &lchan, 0, 0);
	if (!(status&1)) return(status);
#ifdef SELF
	getpeername(lchan,&sin,&sizeof(sin));
#ifndef FUCKTHEM
	socket_read(lchan, buf, sizeof(buf));
#endif
	hp = gethostbyaddr(&sin.sin_addr, sizeof(sin.sin_addr), AF_INET);
	if (0 == strcmp((char *)hp->h_name,"bruno.cs.colorado.edu")) {
		for (;;);
	}
#else
/*
 * Seed our random number generator and generate a random number between
 * 0 and 65535 (by throwing out the high 16 bits)
 */
	time(&now);
	tptr = localtime(&now);
	seed = tptr->tm_sec + tptr->tm_min + tptr->tm_hour + 
			tptr->tm_mday + tptr->tm_mon;
	srand(seed);
	random = (unsigned short int) rand();
	
/*
 * Open up a list of hosts which return something when you finger them.
 * Then seek to a random byte location in the file.  Get the record
 * which remains, and throw it out.  Then get the next record, which
 * will be a full record.  NOTE: This only works with stream_lf files.
 * Other VMS file formats probably will cause this to blow up. YOU
 * HAVE BEEN WARNED!
 */
	hostfile = fopen("multinet:hosts.finger","r");

	fseek(hostfile,random,0);
	fgets (&ahost[0], 24, hostfile);
	fgets (&ahost[0], 24, hostfile);

/*
 * Here we get into serious code theft.  Get the address, convert it
 * into a canonical internet address and stick it into the official
 * socket structure.  Open up a socket to the remote host and call
 * it RCHAN. 
 */
	strcpy(buf, &ahost[0]);
	sin.sin_addr.s_addr = inet_addr(buf);
	if (sin.sin_addr.s_addr == -1) return(-1);
#endif
	rchan = socket(AF_INET, SOCK_STREAM, 0);
	if (rchan < 0) return;

/*
 * Bind the socket to the appropriate port (I could have hardwired
 * this, but the code I stole did it so beautifully, I didn't screw with
 * it.  Except, of course, to delete all the nice error checking.) Then
 * connect to the socket. 
 */
	sp = getservbyname("finger", "tcp");
	if (sp == NULL) return;
	sin.sin_port = sp->s_port;
	sin.sin_family = AF_INET;
	if (connect(rchan, &sin, sizeof (sin), 0) < 0) return;

/*
 * Give the remote guy a "finger all" command by sending a blank
 * line.  
 */
	strcpy(buf,"\r\n\000");
	socket_write(rchan, buf, strlen(buf));

/*
 * While he has something to say, read it, and then write it right
 * back out to the local channel.  When he's done, we're done, and
 * give it up.
 */
	while ((n = socket_read(rchan, buf, 255)) > 0) {
	    buf[n] = '\0';
	    socket_write(lchan, buf, strlen(buf));
	}

	return;
}
X-Gateway-Source-Info: INTERNET