$NetBSD$ 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")) {