Thu Apr 23 19:46:40 2015 UTC ()
Pull up following revision(s) (requested by christos in ticket #719):
	usr.bin/mail/cmd3.c: revision 1.43
	usr.bin/mail/extern.h: revision 1.33
	usr.bin/mail/fio.c: revisions 1.41, 1.42
	usr.bin/mail/mail.1: revision 1.61
	usr.bin/mail/names.c: revision 1.31, 1.32
	usr.bin/mail/send.c: revision 1.38
Fix various security related issues:
    0001. Do not recognize paths, mail folders, and pipes in mail addresses
    by default.  That avoids a direct command injection with syntactically
    valid email addresses starting with |.
    Such addresses can be specified both on the command line, the mail
    headers (with -t) or in address lines copied over from previous
    while replying.
    This was assigned CVE-2014-7844 for some versions of BSD mailx.  It is
    documented behavior for Heirloom mailx, and was mentioned in an old
    technical report about BSD mailx (which does not usually make its way
    into operating system installations).  The patch switches off this
    processing and updates the documentation.
Added expandaddr option to explicitly enable this behavior.
    0002. When invoking sendmail, prevent option processing for email
    address arguments.  This prevents changing e.g. the Postfix
    configuration file in unexpected ways.  This behavior was documented for
    BSD mailx (sort of), but not for Heirloom mailx.  We did not assign a
    CVE to this because it is more of a missing feature, and code invoking
    mailx needs adjustment in the caller as well.
Fixed.
    0003. Make wordexp support mandatory.  (No functional change.)
Fixed (replaced explicit shell pipe implementation).
    0004. Prevent command execution in the expand function, which is IMHO
    unexpected.  (Not really required with patch 1, and there is still
    information disclosure/DoS potential if this expansion occurs.)  This is
    a historic vulnerability already fixed in the Debian package,
    retroactively assigned CVE-2004-2771:
Fixed (as part of the pipe replacement with wordexp).
--
fix incorrect arg size computation


(snj)
diff -r1.42 -r1.42.10.1 src/usr.bin/mail/cmd3.c
diff -r1.32 -r1.32.10.1 src/usr.bin/mail/extern.h
diff -r1.40 -r1.40.8.1 src/usr.bin/mail/fio.c
diff -r1.60 -r1.60.8.1 src/usr.bin/mail/mail.1
diff -r1.30 -r1.30.8.1 src/usr.bin/mail/names.c
diff -r1.37 -r1.37.10.1 src/usr.bin/mail/send.c

cvs diff -r1.42 -r1.42.10.1 src/usr.bin/mail/cmd3.c (expand / switch to unified diff)

--- src/usr.bin/mail/cmd3.c 2012/04/29 23:50:22 1.42
+++ src/usr.bin/mail/cmd3.c 2015/04/23 19:46:40 1.42.10.1
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: cmd3.c,v 1.42 2012/04/29 23:50:22 christos Exp $ */ 1/* $NetBSD: cmd3.c,v 1.42.10.1 2015/04/23 19:46:40 snj Exp $ */
2 2
3/* 3/*
4 * Copyright (c) 1980, 1993 4 * Copyright (c) 1980, 1993
5 * The Regents of the University of California. All rights reserved. 5 * The Regents of the University of California. All rights reserved.
6 * 6 *
7 * Redistribution and use in source and binary forms, with or without 7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions 8 * modification, are permitted provided that the following conditions
9 * are met: 9 * are met:
10 * 1. Redistributions of source code must retain the above copyright 10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer. 11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright 12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the 13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution. 14 * documentation and/or other materials provided with the distribution.
@@ -24,27 +24,27 @@ @@ -24,27 +24,27 @@
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE. 29 * SUCH DAMAGE.
30 */ 30 */
31 31
32#include <sys/cdefs.h> 32#include <sys/cdefs.h>
33#ifndef lint 33#ifndef lint
34#if 0 34#if 0
35static char sccsid[] = "@(#)cmd3.c 8.2 (Berkeley) 4/20/95"; 35static char sccsid[] = "@(#)cmd3.c 8.2 (Berkeley) 4/20/95";
36#else 36#else
37__RCSID("$NetBSD: cmd3.c,v 1.42 2012/04/29 23:50:22 christos Exp $"); 37__RCSID("$NetBSD: cmd3.c,v 1.42.10.1 2015/04/23 19:46:40 snj Exp $");
38#endif 38#endif
39#endif /* not lint */ 39#endif /* not lint */
40 40
41#include "rcv.h" 41#include "rcv.h"
42#include <assert.h> 42#include <assert.h>
43#include <util.h> 43#include <util.h>
44#include "extern.h" 44#include "extern.h"
45#include "mime.h" 45#include "mime.h"
46#include "sig.h" 46#include "sig.h"
47#include "thread.h" 47#include "thread.h"
48 48
49/* 49/*
50 * Mail -- a mail program 50 * Mail -- a mail program
@@ -567,27 +567,27 @@ bounce(void *v) @@ -567,27 +567,27 @@ bounce(void *v)
567 /* setup the bounce tab */ 567 /* setup the bounce tab */
568 add_ignore("Status", bouncetab); 568 add_ignore("Status", bouncetab);
569 add_ignore("Delivered-To", bouncetab); 569 add_ignore("Delivered-To", bouncetab);
570 add_ignore("To", bouncetab); 570 add_ignore("To", bouncetab);
571 add_ignore("X-Original-To", bouncetab); 571 add_ignore("X-Original-To", bouncetab);
572 } 572 }
573 (void)memset(&hdr, 0, sizeof(hdr)); 573 (void)memset(&hdr, 0, sizeof(hdr));
574 if ((rval = grabh(&hdr, GTO)) != 0) 574 if ((rval = grabh(&hdr, GTO)) != 0)
575 return rval; 575 return rval;
576 576
577 if (hdr.h_to == NULL) 577 if (hdr.h_to == NULL)
578 return 1; 578 return 1;
579 579
580 smargs = unpack(hdr.h_to); 580 smargs = unpack(NULL, hdr.h_to);
581 for (ip = msgvec; *ip; ip++) { 581 for (ip = msgvec; *ip; ip++) {
582 int e; 582 int e;
583 if ((e = bounce_one(*ip, smargs, hdr.h_to)) != 0) 583 if ((e = bounce_one(*ip, smargs, hdr.h_to)) != 0)
584 return e; 584 return e;
585 } 585 }
586 return 0; 586 return 0;
587} 587}
588 588
589/* 589/*
590 * Preserve the named messages, so that they will be sent 590 * Preserve the named messages, so that they will be sent
591 * back to the system mailbox. 591 * back to the system mailbox.
592 */ 592 */
593PUBLIC int 593PUBLIC int

cvs diff -r1.32 -r1.32.10.1 src/usr.bin/mail/extern.h (expand / switch to unified diff)

--- src/usr.bin/mail/extern.h 2012/02/28 22:30:44 1.32
+++ src/usr.bin/mail/extern.h 2015/04/23 19:46:40 1.32.10.1
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: extern.h,v 1.32 2012/02/28 22:30:44 joerg Exp $ */ 1/* $NetBSD: extern.h,v 1.32.10.1 2015/04/23 19:46:40 snj Exp $ */
2 2
3/*- 3/*-
4 * Copyright (c) 1992, 1993 4 * Copyright (c) 1992, 1993
5 * The Regents of the University of California. All rights reserved. 5 * The Regents of the University of California. All rights reserved.
6 * 6 *
7 * Redistribution and use in source and binary forms, with or without 7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions 8 * modification, are permitted provided that the following conditions
9 * are met: 9 * are met:
10 * 1. Redistributions of source code must retain the above copyright 10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer. 11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright 12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the 13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution. 14 * documentation and/or other materials provided with the distribution.
@@ -19,27 +19,27 @@ @@ -19,27 +19,27 @@
19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE. 29 * SUCH DAMAGE.
30 * 30 *
31 * @(#)extern.h 8.2 (Berkeley) 4/20/95 31 * @(#)extern.h 8.2 (Berkeley) 4/20/95
32 * $NetBSD: extern.h,v 1.32 2012/02/28 22:30:44 joerg Exp $ 32 * $NetBSD: extern.h,v 1.32.10.1 2015/04/23 19:46:40 snj Exp $
33 */ 33 */
34 34
35#ifndef __EXTERN_H__ 35#ifndef __EXTERN_H__
36#define __EXTERN_H__ 36#define __EXTERN_H__
37 37
38/* 38/*
39 * from cmd1.c 39 * from cmd1.c
40 */ 40 */
41int More(void *); 41int More(void *);
42int Type(void *); 42int Type(void *);
43int folders(void *); 43int folders(void *);
44int from(void *); 44int from(void *);
45int headers(void *); 45int headers(void *);
@@ -214,27 +214,27 @@ int main(int, char **); @@ -214,27 +214,27 @@ int main(int, char **);
214 214
215/* 215/*
216 * from names.c 216 * from names.c
217 */ 217 */
218struct name *cat(struct name *, struct name *); 218struct name *cat(struct name *, struct name *);
219int count(struct name *); 219int count(struct name *);
220struct name *delname(struct name *, char []); 220struct name *delname(struct name *, char []);
221char * detract(struct name *, int); 221char * detract(struct name *, int);
222struct name * elide(struct name *); 222struct name * elide(struct name *);
223struct name * extract(char [], int); 223struct name * extract(char [], int);
224struct name * gexpand(struct name *, struct grouphead *, int, int); 224struct name * gexpand(struct name *, struct grouphead *, int, int);
225struct name * nalloc(char [], int); 225struct name * nalloc(char [], int);
226struct name * outof(struct name *, FILE *, struct header *); 226struct name * outof(struct name *, FILE *, struct header *);
227const char ** unpack(struct name *); 227const char ** unpack(struct name *, struct name *);
228struct name * usermap(struct name *); 228struct name * usermap(struct name *);
229#if 0 229#if 0
230void prettyprint(struct name *); /* commented out? */ 230void prettyprint(struct name *); /* commented out? */
231#endif 231#endif
232 232
233/* 233/*
234 * from popen.c 234 * from popen.c
235 */ 235 */
236int Fclose(FILE *); 236int Fclose(FILE *);
237FILE * Fdopen(int, const char *); 237FILE * Fdopen(int, const char *);
238FILE * Fopen(const char *, const char *); 238FILE * Fopen(const char *, const char *);
239int Pclose(FILE *); 239int Pclose(FILE *);
240FILE * Popen(const char *, const char *); 240FILE * Popen(const char *, const char *);

cvs diff -r1.40 -r1.40.8.1 src/usr.bin/mail/fio.c (expand / switch to unified diff)

--- src/usr.bin/mail/fio.c 2013/03/09 19:43:07 1.40
+++ src/usr.bin/mail/fio.c 2015/04/23 19:46:40 1.40.8.1
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: fio.c,v 1.40 2013/03/09 19:43:07 christos Exp $ */ 1/* $NetBSD: fio.c,v 1.40.8.1 2015/04/23 19:46:40 snj Exp $ */
2 2
3/* 3/*
4 * Copyright (c) 1980, 1993 4 * Copyright (c) 1980, 1993
5 * The Regents of the University of California. All rights reserved. 5 * The Regents of the University of California. All rights reserved.
6 * 6 *
7 * Redistribution and use in source and binary forms, with or without 7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions 8 * modification, are permitted provided that the following conditions
9 * are met: 9 * are met:
10 * 1. Redistributions of source code must retain the above copyright 10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer. 11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright 12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the 13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution. 14 * documentation and/or other materials provided with the distribution.
@@ -24,34 +24,35 @@ @@ -24,34 +24,35 @@
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE. 29 * SUCH DAMAGE.
30 */ 30 */
31 31
32#include <sys/cdefs.h> 32#include <sys/cdefs.h>
33#ifndef lint 33#ifndef lint
34#if 0 34#if 0
35static char sccsid[] = "@(#)fio.c 8.2 (Berkeley) 4/20/95"; 35static char sccsid[] = "@(#)fio.c 8.2 (Berkeley) 4/20/95";
36#else 36#else
37__RCSID("$NetBSD: fio.c,v 1.40 2013/03/09 19:43:07 christos Exp $"); 37__RCSID("$NetBSD: fio.c,v 1.40.8.1 2015/04/23 19:46:40 snj Exp $");
38#endif 38#endif
39#endif /* not lint */ 39#endif /* not lint */
40 40
41#include "rcv.h" 41#include "rcv.h"
42#include "extern.h" 42#include "extern.h"
43#include "thread.h" 43#include "thread.h"
44#include "sig.h" 44#include "sig.h"
 45#include <wordexp.h>
45 46
46/* 47/*
47 * Mail -- a mail program 48 * Mail -- a mail program
48 * 49 *
49 * File I/O. 50 * File I/O.
50 */ 51 */
51 52
52#ifndef THREAD_SUPPORT 53#ifndef THREAD_SUPPORT
53/************************************************************************/ 54/************************************************************************/
54/* 55/*
55 * If we have threading support, these routines live in thread.c. 56 * If we have threading support, these routines live in thread.c.
56 */ 57 */
57static struct message *message; /* message structure array */ 58static struct message *message; /* message structure array */
@@ -414,33 +415,30 @@ getfold(char *name, size_t namesize) @@ -414,33 +415,30 @@ getfold(char *name, size_t namesize)
414 * Supported meta characters: 415 * Supported meta characters:
415 * % for my system mail box 416 * % for my system mail box
416 * %user for user's system mail box 417 * %user for user's system mail box
417 * # for previous file 418 * # for previous file
418 * & invoker's mbox file 419 * & invoker's mbox file
419 * +file file in folder directory 420 * +file file in folder directory
420 * any shell meta character 421 * any shell meta character
421 * Return the file name as a dynamic string. 422 * Return the file name as a dynamic string.
422 */ 423 */
423PUBLIC const char * 424PUBLIC const char *
424expand(const char *name) 425expand(const char *name)
425{ 426{
426 char xname[PATHSIZE]; 427 char xname[PATHSIZE];
427 char cmdbuf[PATHSIZE]; /* also used for file names */ 428 char cmdbuf[PATHSIZE];
428 pid_t pid; 429 int e;
429 ssize_t l; 430 wordexp_t we;
430 char *cp; 431 sigset_t nset, oset;
431 const char *shellcmd; 
432 int pivec[2]; 
433 struct stat sbuf; 
434 432
435 /* 433 /*
436 * The order of evaluation is "%" and "#" expand into constants. 434 * The order of evaluation is "%" and "#" expand into constants.
437 * "&" can expand into "+". "+" can expand into shell meta characters. 435 * "&" can expand into "+". "+" can expand into shell meta characters.
438 * Shell meta characters expand into constants. 436 * Shell meta characters expand into constants.
439 * This way, we make no recursive expansion. 437 * This way, we make no recursive expansion.
440 */ 438 */
441 switch (*name) { 439 switch (*name) {
442 case '%': 440 case '%':
443 findmail(name[1] ? name + 1 : myname, xname, sizeof(xname)); 441 findmail(name[1] ? name + 1 : myname, xname, sizeof(xname));
444 return savestr(xname); 442 return savestr(xname);
445 case '#': 443 case '#':
446 if (name[1] != 0) 444 if (name[1] != 0)
@@ -456,67 +454,74 @@ expand(const char *name) @@ -456,67 +454,74 @@ expand(const char *name)
456 /* fall through */ 454 /* fall through */
457 } 455 }
458 if (name[0] == '+' && getfold(cmdbuf, sizeof(cmdbuf)) >= 0) { 456 if (name[0] == '+' && getfold(cmdbuf, sizeof(cmdbuf)) >= 0) {
459 (void)snprintf(xname, sizeof(xname), "%s/%s", cmdbuf, name + 1); 457 (void)snprintf(xname, sizeof(xname), "%s/%s", cmdbuf, name + 1);
460 name = savestr(xname); 458 name = savestr(xname);
461 } 459 }
462 /* catch the most common shell meta character */ 460 /* catch the most common shell meta character */
463 if (name[0] == '~' && (name[1] == '/' || name[1] == '\0')) { 461 if (name[0] == '~' && (name[1] == '/' || name[1] == '\0')) {
464 (void)snprintf(xname, sizeof(xname), "%s%s", homedir, name + 1); 462 (void)snprintf(xname, sizeof(xname), "%s%s", homedir, name + 1);
465 name = savestr(xname); 463 name = savestr(xname);
466 } 464 }
467 if (strpbrk(name, "~{[*?$`'\"\\") == NULL) 465 if (strpbrk(name, "~{[*?$`'\"\\") == NULL)
468 return name; 466 return name;
469 if (pipe(pivec) < 0) { 467
470 warn("pipe"); 468 *xname = '\0';
471 return name; 469
472 } 470 sigemptyset(&nset);
473 (void)snprintf(cmdbuf, sizeof(cmdbuf), "echo %s", name); 471 sigaddset(&nset, SIGCHLD);
474 if ((shellcmd = value(ENAME_SHELL)) == NULL) 472 sigprocmask(SIG_BLOCK, &nset, &oset);
475 shellcmd = _PATH_CSHELL; 473 e = wordexp(name, &we, WRDE_NOCMD);
476 pid = start_command(shellcmd, NULL, -1, pivec[1], "-c", cmdbuf, NULL); 474 sigprocmask(SIG_SETMASK, &oset, NULL);
477 if (pid < 0) { 475
478 (void)close(pivec[0]); 476 switch (e) {
479 (void)close(pivec[1]); 477 case 0: /* OK */
 478 break;
 479 case WRDE_NOSPACE:
 480 warnx("Out of memory expanding `%s'", name);
480 return NULL; 481 return NULL;
481 } 482 case WRDE_BADVAL:
482 (void)close(pivec[1]); 483 case WRDE_BADCHAR:
483 l = read(pivec[0], xname, sizeof(xname)); 484 case WRDE_SYNTAX:
484 (void)close(pivec[0]); 485 warnx("Syntax error expanding `%s'", name);
485 if (wait_child(pid) < 0 && WTERMSIG(wait_status) != SIGPIPE) { 
486 warnx("Expansion `%s' failed [%x]", cmdbuf, wait_status); 
487 return NULL; 486 return NULL;
488 } 487 case WRDE_CMDSUB:
489 if (l < 0) { 488 warnx("Command substitution not allowed expanding `%s'",
490 warn("read"); 489 name);
491 return NULL; 490 return NULL;
492 } 491 default:
493 if (l == 0) { 492 warnx("Unknown expansion error %d expanding `%s'", e, name);
494 warnx("No match for `%s'", name); 
495 return NULL; 493 return NULL;
496 } 494 }
497 if (l == sizeof(xname)) { 495
498 warnx("Expansion buffer overflow for `%s'", name); 496 switch (we.we_wordc) {
499 return NULL; 497 case 0:
500 } 498 warnx("No match for `%s'", name);
501 xname[l] = '\0'; 499 break;
502 for (cp = &xname[l-1]; *cp == '\n' && cp > xname; cp--) 500 case 1:
503 continue; 501 if (strlen(we.we_wordv[0]) >= PATHSIZE)
504 cp[1] = '\0'; 502 warnx("Expansion too long for `%s'", name);
505 if (strchr(xname, ' ') && stat(xname, &sbuf) < 0) { 503 strlcpy(xname, we.we_wordv[0], PATHSIZE);
 504 break;
 505 default:
506 warnx("Ambiguous expansion for `%s'", name); 506 warnx("Ambiguous expansion for `%s'", name);
507 return NULL; 507 break;
508 } 508 }
509 return savestr(xname); 509
 510 wordfree(&we);
 511 if (!*xname)
 512 return NULL;
 513 else
 514 return savestr(xname);
510} 515}
511 516
512/* 517/*
513 * Return the name of the dead.letter file. 518 * Return the name of the dead.letter file.
514 */ 519 */
515PUBLIC const char * 520PUBLIC const char *
516getdeadletter(void) 521getdeadletter(void)
517{ 522{
518 const char *cp; 523 const char *cp;
519 524
520 if ((cp = value(ENAME_DEAD)) == NULL || (cp = expand(cp)) == NULL) 525 if ((cp = value(ENAME_DEAD)) == NULL || (cp = expand(cp)) == NULL)
521 cp = expand("~/dead.letter"); 526 cp = expand("~/dead.letter");
522 else if (*cp != '/') { 527 else if (*cp != '/') {

cvs diff -r1.60 -r1.60.8.1 src/usr.bin/mail/mail.1 (expand / switch to unified diff)

--- src/usr.bin/mail/mail.1 2013/03/09 19:43:20 1.60
+++ src/usr.bin/mail/mail.1 2015/04/23 19:46:40 1.60.8.1
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1.\" $NetBSD: mail.1,v 1.60 2013/03/09 19:43:20 christos Exp $ 1.\" $NetBSD: mail.1,v 1.60.8.1 2015/04/23 19:46:40 snj Exp $
2.\" 2.\"
3.\" Copyright (c) 1980, 1990, 1993 3.\" Copyright (c) 1980, 1990, 1993
4.\" The Regents of the University of California. All rights reserved. 4.\" The Regents of the University of California. All rights reserved.
5.\" 5.\"
6.\" Redistribution and use in source and binary forms, with or without 6.\" Redistribution and use in source and binary forms, with or without
7.\" modification, are permitted provided that the following conditions 7.\" modification, are permitted provided that the following conditions
8.\" are met: 8.\" are met:
9.\" 1. Redistributions of source code must retain the above copyright 9.\" 1. Redistributions of source code must retain the above copyright
10.\" notice, this list of conditions and the following disclaimer. 10.\" notice, this list of conditions and the following disclaimer.
11.\" 2. Redistributions in binary form must reproduce the above copyright 11.\" 2. Redistributions in binary form must reproduce the above copyright
12.\" notice, this list of conditions and the following disclaimer in the 12.\" notice, this list of conditions and the following disclaimer in the
13.\" documentation and/or other materials provided with the distribution. 13.\" documentation and/or other materials provided with the distribution.
14.\" 3. Neither the name of the University nor the names of its contributors 14.\" 3. Neither the name of the University nor the names of its contributors
@@ -19,27 +19,27 @@ @@ -19,27 +19,27 @@
19.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 21.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
22.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 22.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 23.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
24.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 24.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
25.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 25.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
26.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 26.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
27.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 27.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
28.\" SUCH DAMAGE. 28.\" SUCH DAMAGE.
29.\" 29.\"
30.\" @(#)mail.1 8.8 (Berkeley) 4/28/95 30.\" @(#)mail.1 8.8 (Berkeley) 4/28/95
31.\" 31.\"
32.Dd March 9, 2013 32.Dd December 15, 2014
33.Dt MAIL 1 33.Dt MAIL 1
34.Os 34.Os
35.Sh NAME 35.Sh NAME
36.Nm mail , 36.Nm mail ,
37.Nm mailx , 37.Nm mailx ,
38.Nm Mail 38.Nm Mail
39.Nd send and receive mail 39.Nd send and receive mail
40.Sh SYNOPSIS 40.Sh SYNOPSIS
41.Nm 41.Nm
42.Op Fl EIinv 42.Op Fl EIinv
43.Op Fl a Ar file 43.Op Fl a Ar file
44.Op Fl b Ar bcc-addr 44.Op Fl b Ar bcc-addr
45.Op Fl c Ar cc-addr 45.Op Fl c Ar cc-addr
@@ -715,26 +715,30 @@ Terminate an @@ -715,26 +715,30 @@ Terminate an
715or 715or
716.Ic ifndef 716.Ic ifndef
717command. 717command.
718.It Ic exit 718.It Ic exit
719.Po Ic ex 719.Po Ic ex
720or 720or
721.Ic x 721.Ic x
722.Pc 722.Pc
723Effects an immediate return to the Shell without 723Effects an immediate return to the Shell without
724modifying the user's system mailbox, his 724modifying the user's system mailbox, his
725.Ar mbox 725.Ar mbox
726file, or his edit file in 726file, or his edit file in
727.Fl f . 727.Fl f .
 728.It Ic expandaddr
 729If unset (the default), recipient addresses must be names of local mailboxes
 730or Internet mail addresses.
 731If set, shell expansion of existing mailbox names will be performed.
728.It Ic expose 732.It Ic expose
729Expose the thread structure so all messages appear in header listings. 733Expose the thread structure so all messages appear in header listings.
730(See 734(See
731.Ar hide 735.Ar hide
732for the inverse.) 736for the inverse.)
733The default header prompt will indent each header line one space for 737The default header prompt will indent each header line one space for
734each level in the threading. 738each level in the threading.
735The 739The
736.Dq Li "%?* ?" 740.Dq Li "%?* ?"
737format string does this. 741format string does this.
738.It Ic file 742.It Ic file
739.Pq Ic fi 743.Pq Ic fi
740The same as 744The same as

cvs diff -r1.30 -r1.30.8.1 src/usr.bin/mail/names.c (expand / switch to unified diff)

--- src/usr.bin/mail/names.c 2012/10/21 01:11:23 1.30
+++ src/usr.bin/mail/names.c 2015/04/23 19:46:40 1.30.8.1
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: names.c,v 1.30 2012/10/21 01:11:23 christos Exp $ */ 1/* $NetBSD: names.c,v 1.30.8.1 2015/04/23 19:46:40 snj Exp $ */
2 2
3/* 3/*
4 * Copyright (c) 1980, 1993 4 * Copyright (c) 1980, 1993
5 * The Regents of the University of California. All rights reserved. 5 * The Regents of the University of California. All rights reserved.
6 * 6 *
7 * Redistribution and use in source and binary forms, with or without 7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions 8 * modification, are permitted provided that the following conditions
9 * are met: 9 * are met:
10 * 1. Redistributions of source code must retain the above copyright 10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer. 11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright 12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the 13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution. 14 * documentation and/or other materials provided with the distribution.
@@ -24,27 +24,27 @@ @@ -24,27 +24,27 @@
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE. 29 * SUCH DAMAGE.
30 */ 30 */
31 31
32#include <sys/cdefs.h> 32#include <sys/cdefs.h>
33#ifndef lint 33#ifndef lint
34#if 0 34#if 0
35static char sccsid[] = "@(#)names.c 8.1 (Berkeley) 6/6/93"; 35static char sccsid[] = "@(#)names.c 8.1 (Berkeley) 6/6/93";
36#else 36#else
37__RCSID("$NetBSD: names.c,v 1.30 2012/10/21 01:11:23 christos Exp $"); 37__RCSID("$NetBSD: names.c,v 1.30.8.1 2015/04/23 19:46:40 snj Exp $");
38#endif 38#endif
39#endif /* not lint */ 39#endif /* not lint */
40 40
41/* 41/*
42 * Mail -- a mail program 42 * Mail -- a mail program
43 * 43 *
44 * Handle name lists. 44 * Handle name lists.
45 */ 45 */
46 46
47#include "rcv.h" 47#include "rcv.h"
48#include "extern.h" 48#include "extern.h"
49 49
50/* 50/*
@@ -244,26 +244,29 @@ isfileaddr(char *name) @@ -244,26 +244,29 @@ isfileaddr(char *name)
244 */ 244 */
245PUBLIC struct name * 245PUBLIC struct name *
246outof(struct name *names, FILE *fo, struct header *hp) 246outof(struct name *names, FILE *fo, struct header *hp)
247{ 247{
248 int c, fd; 248 int c, fd;
249 struct name *np, *begin; 249 struct name *np, *begin;
250 time_t now; 250 time_t now;
251 char *date; 251 char *date;
252 const char *fname; 252 const char *fname;
253 FILE *fout, *fin; 253 FILE *fout, *fin;
254 int ispipe; 254 int ispipe;
255 char tempname[PATHSIZE]; 255 char tempname[PATHSIZE];
256 256
 257 if (value("expandaddr") == NULL)
 258 return names;
 259
257 begin = names; 260 begin = names;
258 np = names; 261 np = names;
259 (void)time(&now); 262 (void)time(&now);
260 date = ctime(&now); 263 date = ctime(&now);
261 while (np != NULL) { 264 while (np != NULL) {
262 if (!isfileaddr(np->n_name) && np->n_name[0] != '|') { 265 if (!isfileaddr(np->n_name) && np->n_name[0] != '|') {
263 np = np->n_flink; 266 np = np->n_flink;
264 continue; 267 continue;
265 } 268 }
266 ispipe = np->n_name[0] == '|'; 269 ispipe = np->n_name[0] == '|';
267 if (ispipe) 270 if (ispipe)
268 fname = np->n_name+1; 271 fname = np->n_name+1;
269 else { 272 else {
@@ -522,57 +525,61 @@ count(struct name *np) @@ -522,57 +525,61 @@ count(struct name *np)
522 int c; 525 int c;
523 526
524 for (c = 0; np != NULL; np = np->n_flink) 527 for (c = 0; np != NULL; np = np->n_flink)
525 if ((np->n_type & GDEL) == 0) 528 if ((np->n_type & GDEL) == 0)
526 c++; 529 c++;
527 return c; 530 return c;
528} 531}
529 532
530/* 533/*
531 * Unpack the name list onto a vector of strings. 534 * Unpack the name list onto a vector of strings.
532 * Return an error if the name list won't fit. 535 * Return an error if the name list won't fit.
533 */ 536 */
534PUBLIC const char ** 537PUBLIC const char **
535unpack(struct name *np) 538unpack(struct name *smopts, struct name *np)
536{ 539{
537 const char **ap, **begin; 540 const char **ap, **begin;
538 struct name *n; 541 struct name *n;
539 int t, extra, metoo, verbose; 542 int t, extra, metoo, verbose;
540 543
541 n = np; 544 n = np;
542 if ((t = count(n)) == 0) 545 if ((t = count(n)) == 0)
543 errx(EXIT_FAILURE, "No names to unpack"); 546 errx(EXIT_FAILURE, "No names to unpack");
544 /* 547 /*
545 * Compute the number of extra arguments we will need. 548 * Compute the number of extra arguments we will need.
546 * We need at least two extra -- one for "mail" and one for 549 * We need at least two extra -- one for "mail" and one for
547 * the terminating 0 pointer. Additional spots may be needed 550 * the terminating 0 pointer. Additional spots may be needed
548 * to pass along -f to the host mailer. 551 * to pass along -f to the host mailer.
549 */ 552 */
550 extra = 2; 553 extra = 3 + count(smopts);
551 extra++; 554 extra++;
552 metoo = value(ENAME_METOO) != NULL; 555 metoo = value(ENAME_METOO) != NULL;
553 if (metoo) 556 if (metoo)
554 extra++; 557 extra++;
555 verbose = value(ENAME_VERBOSE) != NULL; 558 verbose = value(ENAME_VERBOSE) != NULL;
556 if (verbose) 559 if (verbose)
557 extra++; 560 extra++;
558 begin = salloc((t + extra) * sizeof(*begin)); 561 begin = salloc((t + extra) * sizeof(*begin));
559 ap = begin; 562 ap = begin;
560 *ap++ = "sendmail"; 563 *ap++ = "sendmail";
561 *ap++ = "-i"; 564 *ap++ = "-i";
562 if (metoo) 565 if (metoo)
563 *ap++ = "-m"; 566 *ap++ = "-m";
564 if (verbose) 567 if (verbose)
565 *ap++ = "-v"; 568 *ap++ = "-v";
 569 for (/*EMPTY*/; smopts != NULL; smopts = smopts->n_flink)
 570 if ((smopts->n_type & GDEL) == 0)
 571 *ap++ = smopts->n_name;
 572 *ap++ = "--";
566 for (/*EMPTY*/; n != NULL; n = n->n_flink) 573 for (/*EMPTY*/; n != NULL; n = n->n_flink)
567 if ((n->n_type & GDEL) == 0) 574 if ((n->n_type & GDEL) == 0)
568 *ap++ = n->n_name; 575 *ap++ = n->n_name;
569 *ap = NULL; 576 *ap = NULL;
570 return begin; 577 return begin;
571} 578}
572 579
573/* 580/*
574 * Remove all of the duplicates from the passed name list by 581 * Remove all of the duplicates from the passed name list by
575 * insertion sorting them, then checking for dups. 582 * insertion sorting them, then checking for dups.
576 * Return the head of the new list. 583 * Return the head of the new list.
577 */ 584 */
578PUBLIC struct name * 585PUBLIC struct name *

cvs diff -r1.37 -r1.37.10.1 src/usr.bin/mail/send.c (expand / switch to unified diff)

--- src/usr.bin/mail/send.c 2012/04/29 23:50:22 1.37
+++ src/usr.bin/mail/send.c 2015/04/23 19:46:40 1.37.10.1
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: send.c,v 1.37 2012/04/29 23:50:22 christos Exp $ */ 1/* $NetBSD: send.c,v 1.37.10.1 2015/04/23 19:46:40 snj Exp $ */
2 2
3/* 3/*
4 * Copyright (c) 1980, 1993 4 * Copyright (c) 1980, 1993
5 * The Regents of the University of California. All rights reserved. 5 * The Regents of the University of California. All rights reserved.
6 * 6 *
7 * Redistribution and use in source and binary forms, with or without 7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions 8 * modification, are permitted provided that the following conditions
9 * are met: 9 * are met:
10 * 1. Redistributions of source code must retain the above copyright 10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer. 11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright 12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the 13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution. 14 * documentation and/or other materials provided with the distribution.
@@ -24,27 +24,27 @@ @@ -24,27 +24,27 @@
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE. 29 * SUCH DAMAGE.
30 */ 30 */
31 31
32#include <sys/cdefs.h> 32#include <sys/cdefs.h>
33#ifndef lint 33#ifndef lint
34#if 0 34#if 0
35static char sccsid[] = "@(#)send.c 8.1 (Berkeley) 6/6/93"; 35static char sccsid[] = "@(#)send.c 8.1 (Berkeley) 6/6/93";
36#else 36#else
37__RCSID("$NetBSD: send.c,v 1.37 2012/04/29 23:50:22 christos Exp $"); 37__RCSID("$NetBSD: send.c,v 1.37.10.1 2015/04/23 19:46:40 snj Exp $");
38#endif 38#endif
39#endif /* not lint */ 39#endif /* not lint */
40 40
41#include <assert.h> 41#include <assert.h>
42 42
43#include "rcv.h" 43#include "rcv.h"
44#include "extern.h" 44#include "extern.h"
45#ifdef MIME_SUPPORT 45#ifdef MIME_SUPPORT
46#include "mime.h" 46#include "mime.h"
47#endif 47#endif
48#include "sig.h" 48#include "sig.h"
49 49
50/* 50/*
@@ -751,27 +751,27 @@ mail1(struct header *hp, int printheader @@ -751,27 +751,27 @@ mail1(struct header *hp, int printheader
751 return; 751 return;
752 } 752 }
753 if (hp->h_smopts == NULL) { 753 if (hp->h_smopts == NULL) {
754 hp->h_smopts = get_smopts(to); 754 hp->h_smopts = get_smopts(to);
755 if (hp->h_smopts != NULL && 755 if (hp->h_smopts != NULL &&
756 hp->h_smopts->n_name[0] != '\0' && 756 hp->h_smopts->n_name[0] != '\0' &&
757 value(ENAME_SMOPTS_VERIFY) != NULL) 757 value(ENAME_SMOPTS_VERIFY) != NULL)
758 if (grabh(hp, GSMOPTS)) { 758 if (grabh(hp, GSMOPTS)) {
759 (void)printf("mail aborted!\n"); 759 (void)printf("mail aborted!\n");
760 savedeadletter(mtf); 760 savedeadletter(mtf);
761 goto out; 761 goto out;
762 } 762 }
763 } 763 }
764 namelist = unpack(cat(hp->h_smopts, to)); 764 namelist = unpack(hp->h_smopts, to);
765 mail2(mtf, namelist); 765 mail2(mtf, namelist);
766 out: 766 out:
767 (void)Fclose(mtf); 767 (void)Fclose(mtf);
768} 768}
769 769
770/* 770/*
771 * Interface between the argument list and the mail1 routine 771 * Interface between the argument list and the mail1 routine
772 * which does all the dirty work. 772 * which does all the dirty work.
773 */ 773 */
774PUBLIC int 774PUBLIC int
775mail(struct name *to, struct name *cc, struct name *bcc, 775mail(struct name *to, struct name *cc, struct name *bcc,
776 struct name *smopts, char *subject, struct attachment *attach) 776 struct name *smopts, char *subject, struct attachment *attach)
777{ 777{