allbery@uunet.UU.NET (Brandon S. Allbery - comp.sources.misc) (03/21/89)
Posting-number: Volume 6, Issue 64 Submitted-by: jeff@quark.wv.tek.com (Jeff Beadles) Archive-name: mverify This program opens a connection to SMTP sendmail on a target host. It then attempts to verify that an alias/user exists in the eyes of the sendmail. I use it to verify users on remote hosts without waiting for mail to bounce. -Jeff Beadles -- Jeff Beadles jeff@quark.WV.TEK.COM #--------------------------------CUT HERE------------------------------------- #! /bin/sh # # This is a shell archive. Save this into a file, edit it # and delete all lines above this comment. Then give this # file to sh by executing the command "sh file". The files # will be extracted into the current directory owned by # you with default permissions. # # The files contained herein are: # # -rw-r--r-- 1 jeff 1647 Mar 7 20:32 README # -rw-r--r-- 1 jeff 4049 Mar 6 10:47 mverify.c # echo 'x - README' if test -f README; then echo 'shar: not overwriting README'; else sed 's/^X//' << '________This_Is_The_END________' > README X XRequirements: SMTP sendmail on the receiving (target) host, and an OS that X supports sockets. X XTo compile: "make mverify" (Yes that's right, there's no makefile.) X (or) cc -O -o mverify mverify.c X XTo execute: "mverify user@host" X X--------------------------------------------------------------------------- Xmverify.c Copyright 1989, Jeff Beadles jeff@quark.WV.TEK.COM X XPermission is granted to freely copy this program without charge. XIf you distribute a binary to someone, you must also provide the source Xupon request. X XThis started out as a little tool, and a learning experience for sockets & Xthe like. If you find it useful, then good for you. If not, then read rm(1). XWhat it does is fairly simple. It opens a connection to SMTP sendmail on a Xtarget host. It then attempts to verify that the user exists in the eyes Xof the sendmail. For example: Let's say that I want to know who the Xuser/alias 'postmaster@quark' expanded to. Mverify would be invoked as: X X% mverify postmaster@quark X XJeff Beadles jeff X XWith the /usr/lib/sendmail -bv command/option, it would only tell you that Xthe mail was 'deliverable' if the target was on another host. X XMost all of the error messages should be self explainatory. X XAs long as the local host can find the target host DIRECTLY, it Xshould work. This program has no concept of mail domains. XIf it is given a domain-style host, it truncates everything up to Xincluding the first '.' IE: jeff@quark.WV.TEK.COM = jeff@quark X XIf you think of something useful to add, please send it to me, and XI'll see about adding it. X XJeff Beadles Xjeff@quark.WV.TEK.COM X...!uunet!tektronix.TEK.COM!quark.WV!jeff ________This_Is_The_END________ if test `wc -l < README` -ne 43; then echo 'shar: README was damaged during transit (should have been 43 lines)' fi fi ; : end of overwriting check echo 'x - mverify.c' if test -f mverify.c; then echo 'shar: not overwriting mverify.c'; else sed 's/^X//' << '________This_Is_The_END________' > mverify.c X/* X * mverify.c Copyright 1989, Jeff Beadles X * jeff@quark.WV.TEK.COM X * X * Permission is granted to freely copy this program without charge. X * There are a couple of lines of autobounce.c by Pete Shipley X * shipley@berkley.edu. X * X * To compile, cc -o mverify mverify : To use, mverify user@host X * X * Note: This program has no concept of mail domains. X * If it is given a domain-style host, it truncates everything up to X * including the '.' IE: jeff@quark.WV.TEK.COM = jeff@quark X * X * This started out as a little tool. If you find it useful, then X * good for you. If not, then read rm(1). X * X * If you think of something useful to add, please send it to me, and X * I'll see about adding it. X * X * Jeff Beadles X * jeff@quark.WV.TEK.COM X * X */ X X/* #define index strchr /* */ X X#include <sys/param.h> X#include <sys/socket.h> X#include <netdb.h> X#include <netinet/in.h> X#include <stdio.h> X#include <strings.h> X Xmain(argc, argv) Xint argc; Xchar **argv; X{ X FILE *fin; X FILE *fout; X char *retval, X *fgets(), X *index(), X buffer[2048], X targetuser[1024], X targethost[1024]; X X int s; X struct servent *sp; X struct hostent *hp, *gethostbyname(); X struct sockaddr_in server; X X if ( argc != 2) { X (void)fprintf(stderr,"Usage: %s user@host\n",argv[0]); X exit(1); X } X strcpy(targetuser,argv[1]); X if( (retval=index(targetuser,'@')) == 0) { X (void)fprintf(stdout,"Usage: %s user@host\n",argv[0]); X exit(1); X } X *retval='\0'; X retval++; X strcpy(targethost,retval); X if ( (retval=index(targethost,'.')) != 0) { X fprintf(stderr,"\nWarning: I do not know about mail domains.\n"); X fprintf(stderr,"Converting %s to ",targethost); X *retval='\0'; X fprintf(stderr,"%s\n\n",targethost); X } X X/* X * One socket please... X */ X if ( (s = socket(AF_INET, SOCK_STREAM, 0)) < 0) { X perror("opening stream socket"); X exit(1); X } X/* X * Now get the information for the @host part of the address. X */ X server.sin_family = AF_INET; X if ( (hp = gethostbyname(targethost)) == 0) { X (void) fprintf(stderr, "%s: unknown host\n", targethost); X exit(2); X } X X X/* X * Now get the smtp port using tcp. X */ X bcopy(hp->h_addr, (char *)&server.sin_addr, hp->h_length); X sp = getservbyname("smtp", "tcp"); X server.sin_port = sp->s_port; X if(server.sin_port == htons(0)) { X (void)fprintf(stderr,"Unknown service: smtp/tcp\n"); X exit(1); X } X X/* X * Connecting to the socket might make things go a little easier... :-) X */ X if (connect(s, (struct sockaddr *)&server, sizeof(server)) < 0) { X perror("connecting stream socket"); X exit(1); X } X X/* X * Change the to streams 'cause I like'em better. X */ X fout = fdopen(s,"w"); X fin = fdopen(s,"r"); X X/* X * Wait for the smtp mailer to answer. It will greet us with: X * 220 quark.WV.TEK.COM Sendmail 5.17/6.24 ready at Thu, 2 Mar 89 23:52:29 PST X */ X while( (retval=fgets(buffer,sizeof(buffer) - 1,fin)) != NULL) { X if ( !strncmp(buffer,"220 ",4)) X break; X } X X/* X * Now that we have the mailers attention, tell it to 'verify' the user. X */ X fprintf(fout,"\nVRFY %s\n",targetuser); X fflush(fout); X X/* X * Now just go into a loop reading responces from the mailer. X */ X while( (retval=fgets(buffer,sizeof(buffer) -1,fin)) != NULL) { X/* X * Zap ^M < > from the lines. X */ X if ( (retval=index(buffer,'\r')) != 0) X *retval='\0'; X if ( (retval=index(buffer,'<')) != 0) X *retval=' '; X if ( (retval=index(buffer,'>')) != 0) X *retval=' '; X/* X * 250 = valid data follows. If true, then this is a valid line. X * The +4 skips the '250-' X */ X if ( !strncmp(buffer,"250",3)) { X puts( buffer + 4); X } X/* X * 550 is 'Command unrecognized. Tell the user and exit. X * The +4 skips the '550-' X */ X if ( !strncmp(buffer,"550",3)) { X puts( buffer + 4); X break; X } X/* X * If "250 " then this was the last line of data. X * (Note the space. a '-' means that there's still more to come.) X */ X if ( !strncmp(buffer,"250 ", 4)) X break; X } X/* X * Close the SMTP connection. X */ X fputs("\n\nQUIT\n", fout); X fflush(fout); X fclose(fout); X fclose(fin); X/* X * And leave this nice program. X */ X exit(0); X} X ________This_Is_The_END________ if test `wc -l < mverify.c` -ne 176; then echo 'shar: mverify.c was damaged during transit (should have been 176 lines)' fi fi ; : end of overwriting check exit 0