ok, here's the news forger.. two caveats on this one: caveat #1: newer nntp servers insist on creating their own "NNTP-Posting-Host:" header and will balk the post if you try to forge it.. this header, while not usually displayed by most readers, is distributed in a post and usually contains the correct pseudo-authenticated machine that the socket connection was made from originally.. caveat #2: on one level, it seems that this is no better than sendmail or the forgepost no better than your run of the mill news poster - as it furthers people ability to ignore the mechanisms of things around them... further your mind and read the rfc's.. take care, loki (argh thru_ : contribute to the Process) -----news_forgery.h-------- /* written by Loki D. Quaeler (copyfree 1995) v1.0 */ /* #define DBUG */ #include #include #include #include #include #include #include #include #include #define NEWSPORT 119 #define MAXLEN 256 #define NNTP_INITIATE "POST" #define NNTP_CLOSE "QUIT" #define ORGANIZATION "Organization:" #define FROM "From:" #define SUBJECT "Subject:" #define NEWSGROUPS "Newsgroups:" #define DISTRIBUTION "Distribution:" #define MSGID "Message-ID:" #define NNTP_EODATA "." #define GOOD_CONNECT_STR "ready" #define GOOD_POST_ACK "240" #define BAD_NEWS "no posting" #define GOOD_DISCONNECT "205" #define QUIT_EXEC "quit" #define DIST_DEFAULT "world" #define MAX_HOSTLEN 64 #define null(type) (type) 0L #define NULL_STRING "" #ifndef YES #define YES 1 #define NO 0 #endif int s; /* socket number */ char buf[BUFSIZ+1]; /* global text data buffer */ char nntpHost[MAX_HOSTLEN]; char newsgroups[MAXLEN]; char pseudoSender[MAXLEN]; char organization[MAXLEN]; char subjectLine[MAXLEN]; char distribution[MAXLEN]; char messageID[MAXLEN]; char *body; -----news_forgery.c-------- /* by Loki D. Quaeler - copyfree 1995 */ #include "news_forgery.h" /*~~[ call_socket ]~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Connect to port MAILPORT on host 'hostname', returning the socket value. Return -1 on any errors. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ int call_socket(hostname) char *hostname; { struct sockaddr_in sa; struct hostent *hp; int a, sock; #ifdef DBUG printf("Entered call_socket, hostname = %s\n", hostname); #endif if ((hp=gethostbyname(hostname))==NULL) { errno=ECONNREFUSED; return(-1); } bzero(&sa, sizeof(sa)); bcopy(hp->h_addr, (char *)&sa.sin_addr, hp->h_length); sa.sin_family = hp->h_addrtype; sa.sin_port = htons((u_short)NEWSPORT); if((sock=socket(hp->h_addrtype, SOCK_STREAM, 0)) < 0) return(-1); if(connect(sock, &sa, sizeof(sa)) < 0) { close(sock); return(-1); } #ifdef DBUG printf("Exiting call_socket correctly, socket = %d\n", sock); #endif return(sock); } /*~~~[ readln ]~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Read all characters from socket s until a newline. Put resulting string in buf, ignoring all after the BUFSIZ'th character. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ int readln(buf) char *buf; { int to=0; char c; #ifdef DBUG printf("Entering readln\n"); #endif do { if(read(s, &c, 1)<1) return(0); if((c >= ' ') || (c <= 126)) if(to\n", MSGID, messageID); dataBody = (char*)realloc(dataBody,(strlen(dataBody) + strlen(inputString) + 1) * sizeof(char)); strcat(dataBody,inputString); } dataBody = (char*)realloc(dataBody,(strlen(dataBody) + strlen(body) + 1) * sizeof(char)); strcat(dataBody,body); printf(" Contacting nntp server...\n"); contact_relay(); /* speak that protocol slang */ printf(" Exchanging protocol slang...\n"); sprintf(buf,"%s\n", NNTP_INITIATE); writeln(buf); readln(outputString); /* monitor force feed of body into buf.... */ printf(" Passing the body of mail...\n"); writeln(dataBody); sprintf(buf,"\n%s\n", NNTP_EODATA); writeln(buf); readln(outputString); if (! strstr(outputString, GOOD_POST_ACK)) printf(" Server didn't send good post acknowledgment. Post probably failed.\n"); printf(" Closing connection...\n"); sprintf(buf,"%s\n", NNTP_CLOSE); writeln(buf); readln(outputString); if (strstr(outputString,GOOD_DISCONNECT)) printf("Received good acknowldegment\n"); else printf("\t ~~ Unrecognized command at socket closure.\n"); close(s); printf("------\nFinished... copy of sent message follows\n------\n%s\n------\n",dataBody); exit(0); } int contact_relay() { /* 0:host unreachable; 1:host connect but no posting allowed; 2: good host connect */ char serverSpew[BUFSIZ]; int i; if ((s=call_socket(nntpHost))==-1) return 0; do { readln(serverSpew); } while (! strstr(serverSpew,GOOD_CONNECT_STR)); if (strstr(serverSpew,BAD_NEWS)) return 1; else return 2; }