Beispiel #1
0
int
main( int argc, char** argv ){
    int argn;
    char* message;
#ifdef DO_RECEIVED
    char* received;
#endif /* DO_RECEIVED */
    char* username;
    char hostname[500];
    char from[1000];
    int status;
    char buf[2000];

    /* Parse args. */
    argv0 = argv[0];
    fake_from = (char*) 0;
    parse_message = 0;
#ifdef DO_MINUS_SP
    server = "127.0.0.1";
    port = SMTP_PORT;
#endif /* DO_MINUS_SP */
    verbose = 0;
    timeout = DEFAULT_TIMEOUT;
    argn = 1;
    if (access("/tmp/_articasend.err", F_OK)==0){
	if (unlink("/tmp/_articasend.err")<0){
		printf("cannot delete file %s\n", "/tmp/_articasend.err");
	  }
    }


    while ( argn < argc && argv[argn][0] == '-' )
	{
	if ( strncmp( argv[argn], "-f", 2 ) == 0 && argv[argn][2] != '\0' )
	    fake_from = &(argv[argn][2]);
	else if ( strcmp( argv[argn], "-t" ) == 0 )
	    parse_message = 1;
#ifdef DO_MINUS_SP
	else if ( strncmp( argv[argn], "-s", 2 ) == 0 && argv[argn][2] != '\0' )
	    server = &(argv[argn][2]);
	else if ( strncmp( argv[argn], "-p", 2 ) == 0 && argv[argn][2] != '\0' )
	    port = atoi( &(argv[argn][2]) );
#endif /* DO_MINUS_SP */
	else if ( strncmp( argv[argn], "-T", 2 ) == 0 && argv[argn][2] != '\0' )
	    timeout = atoi( &(argv[argn][2]) );
	else if ( strcmp( argv[argn], "-v" ) == 0 )
	    verbose = 1;
	else if ( strcmp( argv[argn], "-i" ) == 0 )
	    ;	/* ignore */
	else if ( strcmp( argv[argn], "-oi" ) == 0 )
	    ;	/* ignore */
	else if ( strcmp( argv[argn], "--" ) == 0 )
	    ;	/* ignore */
	else
	    usage();
	++argn;
	}

    username = getlogin();
    if ( username == (char*) 0 )
	{
#ifdef DO_GETPWUID
	struct passwd* pw = getpwuid( getuid() );
	if ( pw == (struct passwd*) 0 )
	    {
	    (void) fprintf( stderr, "%s: can't determine username\n", argv0 );
	    exit( 1 );
	    }
	username = pw->pw_name;
#else /* DO_GETPWUID */
	(void) fprintf( stderr, "%s: can't determine username\n", argv0 );
	exit( 1 );
#endif /* DO_GETPWUID */
	}

    if ( gethostname( hostname, sizeof(hostname) - 1 ) < 0 )
	show_error( "gethostname" );

    if ( fake_from == (char*) 0 )
	(void) snprintf( from, sizeof(from), "%s@%s", username, hostname );
    else
	if ( strchr( fake_from, '@' ) == (char*) 0 )
	    (void) snprintf( from, sizeof(from), "%s@%s", fake_from, hostname );
	else
	    (void) snprintf( from, sizeof(from), "%s", fake_from );

    /* Strip off any angle brackets in the from address. */
    while ( from[0] == '<' )
	(void) strcpy( from, &from[1] );
    while ( from[strlen(from)-1] == '>' )
	from[strlen(from)-1] = '\0';

    message = slurp_message();
#ifdef DO_RECEIVED
    received = make_received( from, username, hostname );
#endif /* DO_RECEIVED */

    (void) signal( SIGALRM, sigcatch );

    (void) alarm( timeout );
    sockfd1 = open_client_socket();

    sockfd2 = dup( sockfd1 );
    sockrfp = fdopen( sockfd1, "r" );
    sockwfp = fdopen( sockfd2, "w" );

    /* The full SMTP protocol is spelled out in RFC821, available at
    ** http://www.faqs.org/rfcs/rfc821.html
    ** The only non-obvious wrinkles:
    **  - The commands are terminated with CRLF, not newline.
    **  - Newlines in the data file get turned into CRLFs.
    **  - Any data lines beginning with a period get an extra period prepended.
    */

    status = read_response();
    if ( status != 220 )
	{
	(void) fprintf(
	    stderr,  "%s: unexpected initial greeting %d\n", argv0, status );
	    myError( "ERROR", "unexpected initial greeting" );
	exit( 1 );
	}

    (void) snprintf( buf, sizeof(buf), "HELO %s", hostname );
    send_command( buf );
    status = read_response();
    if ( status != 250 )
	{
	(void) fprintf(
	    stderr,  "%s: unexpected response %d to HELO command\n",argv0, status );
	    myError( "ERROR", "unexpected response %d to HELO command" );
	exit( 1 );
	}

    (void) snprintf( buf, sizeof(buf), "MAIL FROM:<%s>", from );
    send_command( buf );
    status = read_response();
    if ( status != 250 )
	{
	(void) fprintf(
	    stderr,  "%s: unexpected response %d to MAIL FROM command\n",argv0, status );
	    myError( "ERROR", "unexpected response to MAIL FROM command" );
	exit( 1 );
	}

    got_a_recipient = 0;
    for ( ; argn < argc; ++argn )
	add_recipient( argv[argn], strlen( argv[argn] ) );
    if ( parse_message )
	parse_for_recipients( message );
    if ( ! got_a_recipient )
	{
	(void) fprintf( stderr,  "%s: no recipients found\n", argv0 );
	 myError( "ERROR", "no recipients found" );
	exit( 1 );
	}

    send_command( "DATA" );
    status = read_response();
    if ( status != 354 )
	{
	(void) fprintf(stderr,  "%s: unexpected response %d to DATA command\n",argv0, status );
	myError( "ERROR", "unexpected response to DATA" );
	exit( 1 );
	}

#ifdef DO_RECEIVED
    send_data( received );
#endif /* DO_RECEIVED */
    send_data( message );
    send_done();
    status = read_response();
    if ( status != 250 )
	{
	(void) fprintf(stderr,  "%s: unexpected response %d to DATA\n", argv0, status );
	myError( "ERROR", "unexpected response to DATA" );
	exit( 1 );
	}

    send_command( "QUIT" );
    status = read_response();
    if ( status != 221 )
	(void) fprintf(
	    stderr,  "%s: unexpected response %d to QUIT command - ignored\n",argv0, status );
	    myError( "INFO", "unexpected response to QUIT command - ignored" );

    (void) close( sockfd1 );
    (void) close( sockfd2 );

    exit( 0 );
    }
Beispiel #2
0
int main( int argc, char** argv , char** envp) {
#ifdef RECEPIENT_DEBUG
    int argn = 1;
#endif
	int status;
	int i, h, j, from_count = 0, idx = 0;
    char* message;
#ifdef DO_RECEIVED
    char* received;
#endif /* DO_RECEIVED */
    char* username;
	char **ep;
	char xuser[50] = "";
	char xopt[5000] = "";
    char hostname[500] = "";
    char from[1000] = "";
// #ifdef RECEPIENT_DEBUG
	char to[1000] = "";
// #endif
	char to_buf[1000] = "";
	char *to_ptr = to_buf;
    char buf[2000] = "";
	int has_from_header = 0;
	int has_date_header = 0;
	char date_header[50];
	char from_header[1010];

    /* Parse args. */
    argv0 = argv[0];
//     char *fake_from = from;
#ifdef RECEPIENT_DEBUG
	fake_to = (char*) 0;
#endif
    parse_message = 0;
#ifdef DO_MINUS_SP
    server = "127.0.0.1";
    port = SMTP_PORT;
#endif /* DO_MINUS_SP */
    verbose = 0;
    debug = 0;
    timeout = DEFAULT_TIMEOUT;
	skip_quoted_text = 0;

	char *safe_env_lst[] = {
		"USER",
		"SCRIPT_FILENAME",
		"REQUEST_URI",
		"PWD",
		"REMOTE_ADDR",
		"MESSAGE_ID"
	};

/*
-fname		DONE
-f name 	DONE
-f name user@domain
-f <name> user@domain
-f '' user@domain
-f "" user@domain
*/
	for (i=0; i < argc; i++) {
			if ( strncmp( argv[i], "-d", 2 ) == 0 )
				debug = 1;
			else if ( strncmp( argv[i], "-c", 2 ) == 0 )
				skip_quoted_text = 1;
			else if ( strncmp( argv[i], "-V", 2 ) == 0 ) {
				printf("Version: %s\n", VERSION);
				return(0);
			} else if ( strncmp( argv[i], "-i", 2 ) == 0 ||
				strncmp( argv[i], "-oi", 3 ) == 0 ||
				strncmp( argv[i], "-n", 2 ) == 0 ||
				strcmp( argv[i], "--") == 0 ) {
				if ( debug )
					printf("ARGV[%d](%s): Ignored!\n", i, argv[i]);	/* ignore */
			} else if ( strncmp( argv[i], "--help", 6 ) == 0 ) {
#ifdef DO_MINUS_SP
	#ifdef DO_DNS
					char* spflag = "[-s<server>] [-p<port>] ";
	#else /* DO_DNS */
					char* spflag = "[-s<server_ip>] [-p<port>] ";
	#endif /* DO_DNS */
#else /* DO_MINUS_SP */
					char* spflag = "";
#endif /* DO_MINUS_SP */
					printf("Usage: %s [-f name] [-v] [-d] [-t] [-T] %s\n", argv[0], spflag);
					printf("  -i, -oi, -n and -- are ignored\n");
					printf("  -d debug\n");
					printf("  -v verbose\n");
					printf("  -V version\n");
					printf("  -s server\n");
					printf("  -p port\n");
					printf("  -c skip quoted text\n");
					printf("  -T timeout (default: 60)\n");
					printf("  -t parse the whole message searching for To: Cc: Bcc:\n");
					printf("  -f can be used in any format if the last part of that is the email address\n");
					printf("Version: %s\n", VERSION);
					return(0);
			} else if ( strncmp( argv[i], "-t", 2 ) == 0 )
				parse_message = 1;
			else if ( strncmp( argv[i], "-T", 2 ) == 0 && argv[i][2] != '\0' )
				timeout = atoi( &(argv[i][2]) );
			else if ( strncmp( argv[i], "-v", 2 ) == 0 )
				verbose = 1;
			else if ( strncmp( argv[i], "-f", 2 ) == 0) {
				if ( argv[i][2] != '\0' ) {
					if ( strlen(argv[i]) < 998 ) {
						for ( h=2; h <= strlen(argv[i]); h++)
							from[h-2] = argv[i][h];
						if ( debug )
							printf("FROM0: %s\n", from);
					}
				} else if ( strncmp( argv[i+1], "-", 1) != 0 ) {
					for (h=i+1; h < argc; h++) {
						if ( argv[h] != NULL ) {
							// Ako imam oshte edin argument sled tozi i toi ne zapochva s -
							// to tozi ne e recipient
							if ( argv[h+1] == NULL ) {
								// Tui kato nqmam argumenti sled tekushtqt argument
								// priemame che tova e recipient :)
								// ako tozi argument naistina sushtestvuva
								if ( ( strlen(to) + strlen(argv[h]) ) < 1000 ) {
									for ( j=0; j <= strlen(argv[h]); j++)
										to[j] = argv[h][j];
									if ( debug )
										printf("TO0: %s (%s)\n", to, argv[h]);
								} else {
									(void) fprintf( stderr, "%s: TO argument too long\n", argv0 );
									return(1);
								}
							} else {
								if (strlen(from) + strlen(argv[h]) < 1000) {
									for ( j=0; j <= strlen(argv[h]); j++)
										from[j] = argv[h][j];
									if ( debug )
										printf("FROM1: %s\t(%s), from_count: %d\n", from, argv[h], from_count);
								} else {
									(void) fprintf( stderr, "%s: FROM argument too long\n", argv0 );
									return(1);
								}
								// Ako sledvashtiqt agument ne zapochva s -
								// i ne e posleden, to neka go dobavim kum from-a
 								if ( strncmp( argv[h+1], "-", 1) != 0 && argv[h+2] != NULL ) {
								// Ako cqlostnata duljina na tekushtiqt string + cmd
								// argument-a sa po-malki ot 1000 to dobavi tekushtiqt
								// cmd argument kum from
									if (strlen(from) + strlen(argv[h+1]) < 1000) {
										for ( j=0; j <= strlen(argv[h+1]); j++)
											from[j] = argv[h+1][j];
										if ( debug )
											printf("FROM2: %s\t(%s), from_count: %d\n", from, argv[h+1], from_count);
									} else {
										(void) fprintf( stderr, "%s: FROM argument too long\n", argv0 );
										return(1);
									}
								}
							}
						}
					}
				}
			}
#ifdef DO_MINUS_SP
			else if ( strncmp( argv[i], "-s", 2 ) == 0 && argv[i][2] != '\0' )
				server = &(argv[i][2]);
			else if ( strncmp( argv[i], "-p", 2 ) == 0 && argv[i][2] != '\0' )
				port = atoi( &(argv[i][2]) );
#endif /* DO_MINUS_SP */
				if ( ! got_a_recipient && i == argc-1 && parse_message != 1 ) {
					got_a_recipient++;
					strcat(to_buf, argv[i]);
					if ( debug )
						printf("This has to be the TO %s\n", argv[i]);
				}
				if ( debug )
					printf("ARGV[%d]: |%s| %lu\n", i, argv[i], (unsigned long)strlen(argv[i]));
	}

	if ( timeout == 0 )
		timeout = DEFAULT_TIMEOUT;

	if ( debug )
#ifdef DO_MINUS_SP
		printf("parse_message: %d\nserver: %s port: %d\ntimeout: %d verbose: %d\n",
			parse_message, server, port, timeout, verbose);
#else
		printf("parse_message: %d\ntimeout: %d verbose: %d\n",
			parse_message, timeout, verbose);
#endif

#ifdef DO_GETLOGIN
    username = getlogin();
    if ( username == (char*) 0 ) {
#endif
#ifdef DO_GETPWUID
		struct passwd* pw = getpwuid( getuid() );
		if ( pw == (struct passwd*) 0 ) {
			(void) fprintf( stderr, "%s: can't determine username\n", argv0 );
			exit( 1 );
		}
		username = pw->pw_name;
#endif /* DO_GETPWUID */
#ifdef DO_GETLOGIN
		(void) fprintf( stderr, "%s: can't determine username\n", argv0 );
		exit( 1 );
	}
#endif
    if ( gethostname( hostname, sizeof(hostname) - 1 ) < 0 )
		show_error( "gethostname" );
	if ( strlen(from) < 2 ) {
		if ( debug )
			printf("Ko tursish sq tuka?\n");
 		(void) snprintf( from, sizeof(from), "%s@%s", username, hostname );
	} else {
		// Ako nqmame @ znachi trqbva da fake-nem from-a
		if ( strchr( from, '@' ) == (char*) 0 ) {
			if ( debug )
				printf("Sho go zamestvash toq email sega??\n");
			h = strlen(from);
			from[h] = '@';
			h++;
			for (i=0; i<=strlen(hostname); i++)
				from[i+h] = hostname[i];
		}
	}
    /* Strip off any angle brackets in the from address. */
    while ( from[0] == '<' )
		(void) strcpy( from, &from[1] );
    while ( from[strlen(from)-1] == '>' )
		from[strlen(from)-1] = '\0';
    message = slurp_message();
#ifdef DO_RECEIVED
    received = make_received( from, username, hostname );
#endif /* DO_RECEIVED */
	has_from_header = has_from(message);
	has_date_header = has_date(message);

	if (! has_from_header) {
		snprintf(from_header, sizeof(from_header), "From: %s\n", from);
	}

	if (! has_date_header) {
		time_t t;
		struct tm *tmp;

		t = time(NULL);
		tmp = localtime(&t);

		strftime(date_header, sizeof(date_header), "Date: %a, %d %b %Y %T %z\n", tmp);
	}

    (void) signal( SIGALRM, sigcatch );

    (void) alarm( timeout );
    sockfd1 = open_client_socket();

    sockfd2 = dup( sockfd1 );
    sockrfp = fdopen( sockfd1, "r" );
    sockwfp = fdopen( sockfd2, "w" );

    /* The full SMTP protocol is spelled out in RFC821, available at
    ** http://www.faqs.org/rfcs/rfc821.html
    ** The only non-obvious wrinkles:
    **  - The commands are terminated with CRLF, not newline.
    **  - Newlines in the data file get turned into CRLFs.
    **  - Any data lines beginning with a period get an extra period prepended.
    */

    status = read_response();
    if ( status != 220 ) {
		(void) fprintf( stderr,  "%s: unexpected initial greeting %d\n", argv0, status );
		exit( 1 );
	}

    (void) snprintf( buf, sizeof(buf), "HELO %s", hostname );
    send_command( buf );
    status = read_response();
    if ( status != 250 ) {
		(void) fprintf( stderr,  "%s: unexpected response %d to HELO command\n", argv0, status );
		exit( 1 );
	}

    (void) snprintf( buf, sizeof(buf), "MAIL FROM: %s", from );
    send_command( buf );
    status = read_response();
    if ( status != 250 ) {
		(void) fprintf( stderr,  "%s: unexpected response %d to MAIL FROM command\n", argv0, status );
		exit( 1 );
	}

	if ( got_a_recipient ) {
		if ( debug )
			printf("Sending first found recipient: %s\n", to_buf);
		add_recipient( to_ptr, 0, envp );
	}
	// TO
	// Check the recipient for @ and only if we have it add the recipient
	if ( strchr( to, '@' ) ) {
		j = strlen( to );
		if ( debug )
			printf("TO: %s(%d)\n", to, j);
		h=0;
		for (i=0; i <= j; i++) {
			if ( to[i] == ' ' && to[i+1] != '\0' )
				h=i-1;
		}
		from_count=0;
		for (i=0; i <= j; i++) {
			if ( to[i+h] != '"' &&
				to[i+h] != '<' &&
				to[i+h] != '>' &&
				to[i+h] != ' ' ) {
 				to_buf[from_count] = to[i+h];
				from_count++;
			}
		}
		if ( debug )
			printf("TO2: %s\n", to_buf);
		add_recipient( to_buf, strlen( to_buf ), envp );
	}
#ifdef RECEPIENT_DEBUG
    for ( ; argn < argc; ++argn ) {

		if ( fake_to == (char*) 0 )
			(void) snprintf( to, sizeof(to), "%s@%s", argv[argn], hostname );
		else
			if ( strchr( fake_to, '@' ) == (char*) 0 )
				(void) snprintf( to, sizeof(to), "%s@%s", fake_to, hostname );
		else
			(void) snprintf( to, sizeof(to), "%s", fake_to );
		fprintf( stderr, "RCP: %s\n", fake_to );
		add_recipient( argc, argv, envp );

	}
#endif /* RECEPIENT_DEBUG */
    if ( parse_message ) {
		parse_for_recipients( message, envp );
		if ( debug )
			(void) fprintf( stderr, "%s\n", message );
	}
    if ( ! got_a_recipient ) {
		(void) fprintf( stderr,  "%s: no recipients found\n", argv0 );
		exit( 1 );
	}

    send_command( "DATA" );
    status = read_response();
    if ( status != 354 ) {
		(void) fprintf( stderr,  "%s: unexpected response %d to DATA command\n", argv0, status );
		exit( 1 );
	}

#ifdef DO_RECEIVED
    send_data( received );
#endif /* DO_RECEIVED */
	if (strlen(username) <= 20)
		sprintf( xuser, "X-SG-User: %s\n", username);

 	sprintf( xopt, "%s", "X-SG-Opt: ");
	for (ep = envp; *ep; ep++)
		for (idx = 0; idx<=5; idx++)
			if (safe_env_lst[idx] && !strncmp(*ep, safe_env_lst[idx], strlen(safe_env_lst[idx])))
				sprintf( xopt, "%s %s ", xopt, *ep);

	if (! has_from_header)
		send_data( from_header );
	if (! has_date_header)
		send_data( date_header );
 	send_data( xuser );
	send_data( xopt );
    send_data( message );
    send_done();
    status = read_response();
    if ( status != 250 ) {
		(void) fprintf( stderr,  "%s: unexpected response %d to DATA\n", argv0, status );
		exit( 1 );
	}

    send_command( "QUIT" );
    status = read_response();
    if ( status != 221 )
		(void) fprintf( stderr,  "%s: unexpected response %d to QUIT command - ignored\n", argv0, status );

    (void) close( sockfd1 );
    (void) close( sockfd2 );

    exit( 0 );
}