Subject: [inn 1.4] unoff. patch to identify posters

From: [email-masked] (Luke Mewburn)
Date: 13 Mar 1994 15:56:20 GMT

Here's an unofficial patch that's in use locally that adds a bit more
identification to posters. It's great for limiting the number of
probablamtic posts from users who try and hide behind a forged note.

It adds an extra header `NNTP-posting-user:' which is determined by
the ident protocol. It contains the name of the user returned by
identd. (I.e, check out the headers on this post)

A couple of comments.
- Some people are dead against using identd. Well, I run the only
  machines which are allowed to post to our server, and if anyone
  manages to hack those, I'm sure they'd do more than spoof identd
  so they can forge news. So, where's the `spoofing' problem.
- Rich $alz didn't want to incorporate this particular patch into the
  official tree. That's his prerogative, and I respect that. (He'd
  rather just be syslogging the info.) Our site decided to allow the
  world to see that Joe Bloggs is being a pain, rather than just
  making a note to the local sysop. That's our prerogative :)
- The header entry is as difficult to override as NNTP-Posting-Host.
  (I.e, a normal connection shouldn't be able to do it.)
- If the ident fails, it doesn't add the header
- Only one package has failed with connecting to a modified nnrpd
  system - an old (pre winsock.dll) version of WinQVT net on the PC -
  it couldn't handle the ident request...
- The request occurs at the same time that nntp-posting-host does.

We've had it running for two months now, and besides the WinQVT
problem, all seems well.

Anyway, here's the source. I couldn't think of a good place to post
it, so alt.sources and news.software.nntp has it.

---
diff --new-file -c O_nnrpd/Makefile nnrpd/Makefile
*** O_nnrpd/Makefile	Thu Sep 23 15:45:33 1993
--- nnrpd/Makefile	Wed Jan 12 16:12:56 1994
***************
*** 32,41 ****
  LINTLIB	= ../llib-linn.ln

  SOURCES	= \
! 	article.c group.c commands.c misc.c newnews.c nnrpd.c post.c loadave.c

  OBJECTS	= \
! 	article.o group.o commands.o misc.o newnews.o nnrpd.o post.o loadave.o

  ALL	= nnrpd

--- 32,43 ----
  LINTLIB	= ../llib-linn.ln

  SOURCES	= \
! 	article.c group.c commands.c misc.c newnews.c nnrpd.c post.c loadave.c \
! 	ident_client.c

  OBJECTS	= \
! 	article.o group.o commands.o misc.o newnews.o nnrpd.o post.o loadave.o \
! 	ident_client.o

  ALL	= nnrpd

diff --new-file -c O_nnrpd/ident_client.c nnrpd/ident_client.c
*** O_nnrpd/ident_client.c
--- nnrpd/ident_client.c	Wed Jan 12 16:12:17 1994
***************
*** 0 ****
--- 1,97 ----
+ /*
+  *	ident_client.c
+  *
+  * Identifies the remote user of a given connection.
+  *
+  * Written 940112 by Luke Mewburn <[email-masked]>
+  *
+  * Copyright (C) 1994 by Luke Mewburn.
+  * This code may be used freely by anyone as long as this copyright remains.
+  *
+  */
+ 
+ #include <stdio.h>
+ #include <string.h>
+ #include <sys/types.h>
+ #include <sys/socket.h>
+ #include <netinet/in.h>
+ #include <netdb.h>
+ 
+ #define IDENT_PORT	113
+ 
+ /*
+  * ident_client
+  *	- user interface to identd
+  *
+  * Args:
+  *	peeraddr	sockaddr_in struct of peer end, from getpeername(...)
+  *	ouraddr		sockaddr_in struct of local end, from getsockname(...)
+  *
+  * Returns:
+  *	NULL on failure to identify (for whatever reason), or pointer to
+  *	static character string with the identity.
+  */
+ 
+ char *
+ ident_client(peeraddr, ouraddr)
+ 	struct sockaddr_in	peeraddr, ouraddr;
+ {
+ 	struct sockaddr_in	authcon;
+ 	int			authfd, authlen;
+ 	struct servent		*identserv;
+ 	int			identport;
+ 
+ 	FILE			*authfpin, *authfpout;
+ 	char			buffer[8192];	/* XXX: argh! magic numbers */
+ 	char			reply_type[81]; 
+ 	char			opsys_or_err[81]; 
+ 	int			rport, lport;
+ 
+ 	static char		identifier[1024]; 
+ 
+ 	authfd = socket(AF_INET, SOCK_STREAM, 0);
+ 	if (authfd == -1)
+ 		return NULL;
+ 
+ 	identserv = getservbyname("ident", "tcp");
+ 	if (identserv)
+ 		identport = identserv->s_port;
+ 	else
+ 		identport = ntohs(IDENT_PORT);
+ 
+ 	memset(&authcon, 0, sizeof(authcon));
+ 	authcon.sin_family = AF_INET;
+ 	authcon.sin_addr.s_addr = peeraddr.sin_addr.s_addr;
+ 	authcon.sin_port = identport;
+ 
+ 	authlen = sizeof(authcon);
+ 	if (connect(authfd, (struct sockaddr *)&authcon, authlen) < 0)
+ 		return NULL;
+    
+ 	authfpin  = fdopen(authfd, "r");
+ 	authfpout = fdopen(authfd, "w");
+ 	if (!authfpin || !authfpout)
+ 		return NULL;
+ 
+ 	fprintf(authfpout, "%d , %d\n", peeraddr.sin_port, ouraddr.sin_port);
+ 	fflush(authfpout);
+ 
+ 	if (fgets(buffer, sizeof(buffer)-1, authfpin) == NULL)
+ 		return NULL;
+ 
+ 	shutdown(authfd, 1);
+ 
+ 	authlen = sscanf(buffer, "%d , %d : %[^ \t\n\r:] : %[^ \t\n\r:] : %[^\n\r]",
+ 		    &lport, &rport, reply_type, opsys_or_err, identifier);
+ 	if (authlen < 3)
+ 		return NULL;
+ 
+ #if 0		/* XXX: for if we ever handle the ERROR class */
+ 	if (! strcasecmp(reply_type, "ERROR"))
+ 		return NULL;
+ #endif
+ 	if (strcasecmp(reply_type, "USERID"))
+ 		return NULL;
+ 
+ 	return identifier;
+ } /* ident_client */
diff --new-file -c O_nnrpd/nnrpd.c nnrpd/nnrpd.c
*** O_nnrpd/nnrpd.c	Fri Mar 19 07:04:44 1993
--- nnrpd/nnrpd.c	Wed Jan 12 16:22:33 1994
***************
*** 357,363 ****
  StartConnection(accesslist)
      char		*accesslist;
  {
!     struct sockaddr_in	sin;
      int			length;
      char		buff[SMBUF];
      char		*ClientAddr;
--- 357,363 ----
  StartConnection(accesslist)
      char		*accesslist;
  {
!     struct sockaddr_in	sin, ourad;
      int			length;
      char		buff[SMBUF];
      char		*ClientAddr;
***************
*** 404,409 ****
--- 404,425 ----
  	    NNTP_ACCESS_VAL);
  	ExitWithStats(1);
      }
+ 
+ 		/* lm, 940112 */
+     ClientUser[0] = '\0';
+     if (!isatty(STDIN)) {
+ 	length = sizeof(ourad);
+ 	if (getsockname(STDIN, (struct sockaddr *)&ourad, &length) >= 0) {
+ 	    char *ident_client();
+ 	    char *them;
+ 
+ 	    them = ident_client(sin, ourad);
+ 	    if (them) {
+ 		(void)strncpy(ClientUser, them, sizeof(ClientUser) - 1);
+ 		ClientUser[sizeof(ClientUser) - 1] = '\0';
+ 	    }
+ 	}
+     }
  }

diff --new-file -c O_nnrpd/nnrpd.h nnrpd/nnrpd.h
*** O_nnrpd/nnrpd.h	Fri Mar 19 07:04:45 1993
--- nnrpd/nnrpd.h	Wed Jan 12 16:11:52 1994
***************
*** 105,110 ****
--- 105,111 ----
  EXTERN STRING	MyHostName;
  extern char	ACTIVE[];
  EXTERN char	ClientHost[SMBUF];
+ EXTERN char	ClientUser[SMBUF];	/* lm, 931203 */
  extern char	ACTIVETIMES[];
  extern char	HISTORY[];
  extern char	NEWSGROUPS[];
diff --new-file -c O_nnrpd/post.c nnrpd/post.c
*** O_nnrpd/post.c	Sat Jan 30 03:52:04 1993
--- nnrpd/post.c	Fri Dec  3 15:05:26 1993
***************
*** 80,85 ****
--- 80,87 ----
  #define _contenttype	19
      {	"Content-Transfer-Encoding", TRUE, HTstd },
  #define _contenttransferencoding 20
+     {	"NNTP-Posting-User",	FALSE,	HTstd },	/* lm, 931203 */
+ #define _nntppostuser	21
      {	"Xref",			FALSE,	HTstd },
      {	"Summary",		TRUE,	HTstd },
      {	"Keywords",		TRUE,	HTstd },
***************
*** 420,425 ****
--- 422,431 ----
      /* NNTP-Posting host; set. */
      HDR(_nntpposthost) = ClientHost;

+     /* NNTP-Posting user; set. */
+     if (ClientUser[0])
+ 	HDR(_nntppostuser) = ClientUser;		/* lm, 931203 */
+ 
      /* Now make sure everything is there. */
      for (hp = Table; hp < ENDOF(Table); hp++)
  	if (hp->Type == HTreq && hp->Value == NULL) {

--
Luke Mewburn			Programmer, Technical Services Group,
Email: <[email-masked]>		Department of Computer Science, RMIT,
Phone: +61 3 660 3210		Melbourne, Victoria, Australia.