$NetBSD: patch-ac,v 1.1 2004/02/09 09:17:50 wennmach Exp $

Security patches for jitterbug (taken from Debian GNU/Linux).
See http://www.debian.org/security/2004/dsa-420

--- new_message.c.orig	Wed Nov 11 13:30:17 1998
+++ new_message.c	Wed Jan 14 17:34:04 2004
@@ -206,6 +206,133 @@
 	smtp_end_mail(fd);
 }
 	
+/* This function should always return success */
+static int mail_failure(char* from, char* to, char* content)
+{
+	int fd;
+	fd = smtp_start_mail(from, to, NULL, NULL, "Request failed", strlen(content));
+	if ( fd == -1 ) {
+		fprintf(stderr, "Failed to send failure\n");
+		return 0;
+	}
+	smtp_write(fd, "\n");
+	smtp_write_data(fd, content);
+	smtp_end_mail(fd);
+	return 0; 
+}
+
+static int is_a_bug(char* name) 
+{
+	if (*name >= '1' && *name <= '9')
+		return !is_directory(name);
+	return 0;
+}
+
+static int get_bug(char *mbuf, char* to, char *query)
+{
+	int fd;
+	char *from, *p;
+	char *subject="Jitterbug results";
+	char buf[1024];
+	unsigned int size=0;
+	char boundary[128];
+	struct stat st;
+	char *bug;
+	char* msg_id;
+	char *msg_list;
+
+	snprintf(boundary, sizeof(boundary), "jitterbug-burp-%d-%d", getpid(), time(NULL));
+
+	/* maybe check for lp_download? */
+	/* maybe add info to audit? */
+	from = lp_from_address();
+	
+	while (*query && *query == ' ') query++;
+	if (!strncmp(query, "list", 4)) {
+		char** dir_l, **file_l;
+		int i, j;
+		query += 4;
+		fd = smtp_start_mail(from, to, NULL, NULL, subject, 0);
+		if ( fd == -1 )
+			return 1;
+
+		msg_id = getmailheader(mbuf, "Message-ID:", 0);
+		if ( msg_id )
+			smtp_write(fd, "References: %s\n", msg_id);
+		smtp_write(fd, "\nList for query: %s\n\n", query);
+		trim_string(query, " ", " ");
+		/* use strtok to allow multiple queries */
+		if (!*query || *query == '/' || *query == '.') {
+			query = ".";
+			dir_l = load_dir_list(query, is_directory);
+		} else {
+			dir_l = new_list();
+			add_list_item(dir_l, query);
+		}
+		for (i=0; dir_l && dir_l[i]; ++i) {
+			file_l = load_dir_list(dir_l[i], is_a_bug);
+			/* maybe add subject, from, ... */
+			for (j=0; file_l && file_l[j]; ++j)
+				smtp_write(fd, "%s/%s\n", dir_l[i], file_l[j]);
+			free_list(file_l);
+		}
+		free_list(dir_l);
+		smtp_end_mail(fd);
+		return 0;
+	} else if (!strncmp(query, "get", 3)) {
+		query += 3;
+	} else if (!strncmp(query, "search", 6)) {
+		query += 6;
+		snprintf(buf, sizeof(buf), "Not implemeted (%s)\n", query);
+		return mail_failure(from, to, buf);
+	} else {
+		snprintf(buf, sizeof(buf), "Not implemeted (%s)\n", query);
+		return mail_failure(from, to, buf);
+	}
+
+	fd = smtp_start_mail(from, to, NULL, NULL, subject, 0);
+	if ( fd == -1 )
+		return 1;
+
+	msg_id = getmailheader(mbuf, "Message-ID:", 0);
+	if ( msg_id )
+		smtp_write(fd, "References: %s\n", msg_id);
+	smtp_write(fd, "Mime-Version: 1.0\n");
+	smtp_write(fd, "Content-Type: multipart/mixed; boundary=%s\n\n", boundary);
+	msg_list = strdup(query);
+	for (query = strtok(msg_list, " \t,;"); query; query = strtok(NULL, " \t,;")) {
+		smtp_write(fd, "\n--%s\nContent-Type: text/plain; charset=us-ascii\n", boundary);
+		/* a few security checks */
+		if (*query == '/' || strchr(query, '.') || !(p=strchr(query, '/'))) {
+			smtp_write(fd, "\nNot allowed (%s)\n", query);
+			continue;
+		}
+		*p = 0;
+		if ( !is_directory(query) ) {
+			smtp_write(fd, "\nNot allowed (%s)\n", query);
+			continue;
+		}
+		*p = '/';
+		bug = load_file(query, &st, 0);
+		if ( !bug ) {
+			smtp_write(fd, "\nCannot load (%s)\n", query);
+			continue;
+		}
+		/* replace / with _ in filename */
+		p = query;
+		while(*p) {
+			if (*p == '/') *p = '_';
+			++p;
+		}
+		smtp_write(fd, "Content-Disposition: attachment; filename=\"%s\"\n\n", query);
+		smtp_write_data(fd, bug);
+		free(bug);
+	}
+	free(msg_list);
+
+	smtp_end_mail(fd);
+	return 0;
+}
 
 int process_mail(char *def_dir)
 {
@@ -253,6 +380,10 @@
 		return 1;
 	}
 
+	if (strncasecmp(from, "MAILER-DAEMON", 13) == 0) {
+		fprintf(stderr,"Ignoring bounced mail\n");
+		return 1;
+	}
 
 	/* work out if it has an existing id */
 	id = getid(mbuf);
@@ -273,6 +404,12 @@
 		}
 	}
 
+	subject = getmailheader(mbuf, "Subject:", 0);
+	if (subject && !strncmp(subject, "GETBUG:", 7)) {
+		unlink(".newnsg");
+		return get_bug(mbuf, from, subject + 7);
+	}
+
 	if (! *fname) {
 		char *idfile = load_file(".nextid", NULL, 0);
 		nextid=1;
@@ -306,7 +443,6 @@
 	}
 
 	/* forward to "forward public" if message not marked private */
-	subject = getmailheader(mbuf, "Subject:", 0);
 
 	if (subject &&
 	    lp_forward_public() && !strstr(subject,"PRIVATE")) {
