Changeset 3232 in MondoRescue for branches/3.2/mindi-busybox/mailutils


Ignore:
Timestamp:
Jan 1, 2014, 12:47:38 AM (10 years ago)
Author:
Bruno Cornec
Message:
  • Update mindi-busybox to 1.21.1
Location:
branches/3.2/mindi-busybox/mailutils
Files:
5 edited

Legend:

Unmodified
Added
Removed
  • branches/3.2/mindi-busybox/mailutils/Kbuild.src

    r2725 r3232  
    88
    99INSERT
    10 lib-$(CONFIG_MAKEMIME)     += mime.o mail.o
    11 lib-$(CONFIG_POPMAILDIR)   += popmaildir.o mail.o
    12 lib-$(CONFIG_REFORMIME)    += mime.o mail.o
    13 lib-$(CONFIG_SENDMAIL)     += sendmail.o mail.o
  • branches/3.2/mindi-busybox/mailutils/mail.c

    r2725 r3232  
    5858
    5959    i = (!G.helper_pid) * 2; // for parent:0, for child:2
    60     close(pipes[i + 1]); // 1 or 3 - closing one write end
    61     close(pipes[2 - i]); // 2 or 0 - closing one read end
    62     xmove_fd(pipes[i], STDIN_FILENO); // 0 or 2 - using other read end
    63     xmove_fd(pipes[3 - i], STDOUT_FILENO); // 3 or 1 - other write end
     60    close(pipes[i + 1]);     // 1 or 3 - closing one write end
     61    close(pipes[2 - i]);     // 2 or 0 - closing one read end
     62    xmove_fd(pipes[i], STDIN_FILENO);      // 0 or 2 - using other read end
     63    xmove_fd(pipes[3 - i], STDOUT_FILENO); // 3 or 1 - using other write end
     64    // End result:
     65    // parent stdout [3] -> child stdin [2]
     66    // child stdout [1] -> parent stdin [0]
    6467
    6568    if (!G.helper_pid) {
     
    7679}
    7780
    78 const FAST_FUNC char *command(const char *fmt, const char *param)
     81char* FAST_FUNC send_mail_command(const char *fmt, const char *param)
    7982{
    80     const char *msg = fmt;
     83    char *msg;
    8184    if (timeout)
    8285        alarm(timeout);
    83     if (msg) {
     86    msg = (char*)fmt;
     87    if (fmt) {
    8488        msg = xasprintf(fmt, param);
     89        if (verbose)
     90            bb_error_msg("send:'%s'", msg);
    8591        printf("%s\r\n", msg);
    8692    }
     
    9197// NB: parse_url can modify url[] (despite const), but only if '@' is there
    9298/*
    93 static char FAST_FUNC *parse_url(char *url, char **user, char **pass)
     99static char* FAST_FUNC parse_url(char *url, char **user, char **pass)
    94100{
    95101    // parse [user[:pass]@]host
     
    114120{
    115121    enum {
    116         SRC_BUF_SIZE = 45,  /* This *MUST* be a multiple of 3 */
     122        SRC_BUF_SIZE = 57,  /* This *MUST* be a multiple of 3 */
    117123        DST_BUF_SIZE = 4 * ((SRC_BUF_SIZE + 2) / 3),
    118124    };
     
    170176        G.pass = xstrdup(bb_ask(fd, /* timeout: */ 0, "Password: "));
    171177    } else {
    172         G.user = xmalloc_reads(fd, /* pfx: */ NULL, /* maxsize: */ NULL);
    173         G.pass = xmalloc_reads(fd, /* pfx: */ NULL, /* maxsize: */ NULL);
     178        G.user = xmalloc_reads(fd, /* maxsize: */ NULL);
     179        G.pass = xmalloc_reads(fd, /* maxsize: */ NULL);
    174180    }
    175181    if (!G.user || !*G.user || !G.pass)
  • branches/3.2/mindi-busybox/mailutils/mail.h

    r2725 r3232  
     1/* vi: set sw=4 ts=4: */
     2/*
     3 * helper routines
     4 *
     5 * Copyright (C) 2008 by Vladimir Dronnikov <dronnikov@gmail.com>
     6 *
     7 * Licensed under GPLv2, see file LICENSE in this source tree.
     8 */
    19
    210struct globals {
    311    pid_t helper_pid;
    412    unsigned timeout;
     13    unsigned verbose;
    514    unsigned opts;
    615    char *user;
     
    817    FILE *fp0; // initial stdin
    918    char *opt_charset;
    10     char *content_type;
    1119};
    1220
    1321#define G (*ptr_to_globals)
    1422#define timeout         (G.timeout  )
     23#define verbose         (G.verbose  )
    1524#define opts            (G.opts     )
    16 //#define user            (G.user     )
    17 //#define pass            (G.pass     )
    18 //#define fp0             (G.fp0      )
    19 //#define opt_charset     (G.opt_charset)
    20 //#define content_type    (G.content_type)
    2125#define INIT_G() do { \
    2226    SET_PTR_TO_GLOBALS(xzalloc(sizeof(G))); \
    2327    G.opt_charset = (char *)CONFIG_FEATURE_MIME_CHARSET; \
    24     G.content_type = (char *)"text/plain"; \
    2528} while (0)
    2629
    2730//char FAST_FUNC *parse_url(char *url, char **user, char **pass);
    2831
    29 void FAST_FUNC launch_helper(const char **argv);
    30 void FAST_FUNC get_cred_or_die(int fd);
     32void launch_helper(const char **argv) FAST_FUNC;
     33void get_cred_or_die(int fd) FAST_FUNC;
    3134
    32 const FAST_FUNC char *command(const char *fmt, const char *param);
     35char *send_mail_command(const char *fmt, const char *param) FAST_FUNC;
    3336
    34 void FAST_FUNC encode_base64(char *fname, const char *text, const char *eol);
     37void encode_base64(char *fname, const char *text, const char *eol) FAST_FUNC;
  • branches/3.2/mindi-busybox/mailutils/popmaildir.c

    r2725 r3232  
    1010 * Licensed under GPLv2, see file LICENSE in this source tree.
    1111 */
     12
     13//kbuild:lib-$(CONFIG_POPMAILDIR) += popmaildir.o mail.o
     14
     15//usage:#define popmaildir_trivial_usage
     16//usage:       "[OPTIONS] MAILDIR [CONN_HELPER ARGS]"
     17//usage:#define popmaildir_full_usage "\n\n"
     18//usage:       "Fetch content of remote mailbox to local maildir\n"
     19/* //usage:  "\n    -b      Binary mode. Ignored" */
     20/* //usage:  "\n    -d      Debug. Ignored" */
     21/* //usage:  "\n    -m      Show used memory. Ignored" */
     22/* //usage:  "\n    -V      Show version. Ignored" */
     23/* //usage:  "\n    -c      Use tcpclient. Ignored" */
     24/* //usage:  "\n    -a      Use APOP protocol. Implied. If server supports APOP -> use it" */
     25//usage:     "\n    -s      Skip authorization"
     26//usage:     "\n    -T      Get messages with TOP instead of RETR"
     27//usage:     "\n    -k      Keep retrieved messages on the server"
     28//usage:     "\n    -t SEC      Network timeout"
     29//usage:    IF_FEATURE_POPMAILDIR_DELIVERY(
     30//usage:     "\n    -F \"PROG ARGS\"    Filter program (may be repeated)"
     31//usage:     "\n    -M \"PROG ARGS\"    Delivery program"
     32//usage:    )
     33//usage:     "\n"
     34//usage:     "\nFetch from plain POP3 server:"
     35//usage:     "\npopmaildir -k DIR nc pop3.server.com 110 <user_and_pass.txt"
     36//usage:     "\nFetch from SSLed POP3 server and delete fetched emails:"
     37//usage:     "\npopmaildir DIR -- openssl s_client -quiet -connect pop3.server.com:995 <user_and_pass.txt"
     38/* //usage:  "\n    -R BYTES    Remove old messages on the server >= BYTES. Ignored" */
     39/* //usage:  "\n    -Z N1-N2    Remove messages from N1 to N2 (dangerous). Ignored" */
     40/* //usage:  "\n    -L BYTES    Don't retrieve new messages >= BYTES. Ignored" */
     41/* //usage:  "\n    -H LINES    Type first LINES of a message. Ignored" */
     42//usage:
     43//usage:#define popmaildir_example_usage
     44//usage:       "$ popmaildir -k ~/Maildir -- nc pop.drvv.ru 110 [<password_file]\n"
     45//usage:       "$ popmaildir ~/Maildir -- openssl s_client -quiet -connect pop.gmail.com:995 [<password_file]\n"
     46
    1247#include "libbb.h"
    1348#include "mail.h"
     
    1550static void pop3_checkr(const char *fmt, const char *param, char **ret)
    1651{
    17     const char *msg = command(fmt, param);
     52    char *msg = send_mail_command(fmt, param);
    1853    char *answer = xmalloc_fgetline(stdin);
    1954    if (answer && '+' == answer[0]) {
     55        free(msg);
    2056        if (timeout)
    2157            alarm(0);
     
    2864        return;
    2965    }
    30     bb_error_msg_and_die("%s failed: %s", msg, answer);
     66    bb_error_msg_and_die("%s failed, reply was: %s", msg, answer);
    3167}
    3268
  • branches/3.2/mindi-busybox/mailutils/sendmail.c

    r2725 r3232  
    77 * Licensed under GPLv2, see file LICENSE in this source tree.
    88 */
     9
     10//kbuild:lib-$(CONFIG_SENDMAIL) += sendmail.o mail.o
     11
     12//usage:#define sendmail_trivial_usage
     13//usage:       "[OPTIONS] [RECIPIENT_EMAIL]..."
     14//usage:#define sendmail_full_usage "\n\n"
     15//usage:       "Read email from stdin and send it\n"
     16//usage:     "\nStandard options:"
     17//usage:     "\n    -t      Read additional recipients from message body"
     18//usage:     "\n    -f SENDER   Sender (required)"
     19//usage:     "\n    -o OPTIONS  Various options. -oi implied, others are ignored"
     20//usage:     "\n    -i      -oi synonym. implied and ignored"
     21//usage:     "\n"
     22//usage:     "\nBusybox specific options:"
     23//usage:     "\n    -v      Verbose"
     24//usage:     "\n    -w SECS     Network timeout"
     25//usage:     "\n    -H 'PROG ARGS'  Run connection helper"
     26//usage:     "\n            Examples:"
     27//usage:     "\n            -H 'exec openssl s_client -quiet -tls1 -starttls smtp"
     28//usage:     "\n                -connect smtp.gmail.com:25' <email.txt"
     29//usage:     "\n                [4<username_and_passwd.txt | -auUSER -apPASS]"
     30//usage:     "\n            -H 'exec openssl s_client -quiet -tls1"
     31//usage:     "\n                -connect smtp.gmail.com:465' <email.txt"
     32//usage:     "\n                [4<username_and_passwd.txt | -auUSER -apPASS]"
     33//usage:     "\n    -S HOST[:PORT]  Server"
     34//usage:     "\n    -auUSER     Username for AUTH LOGIN"
     35//usage:     "\n    -apPASS     Password for AUTH LOGIN"
     36////usage:     "\n  -amMETHOD   Authentication method. Ignored. LOGIN is implied"
     37//usage:     "\n"
     38//usage:     "\nOther options are silently ignored; -oi -t is implied"
     39//usage:    IF_MAKEMIME(
     40//usage:     "\nUse makemime to create emails with attachments"
     41//usage:    )
     42
    943#include "libbb.h"
    1044#include "mail.h"
     
    1448#define MAX_HEADERS 256
    1549
     50static void send_r_n(const char *s)
     51{
     52    if (verbose)
     53        bb_error_msg("send:'%s'", s);
     54    printf("%s\r\n", s);
     55}
     56
    1657static int smtp_checkp(const char *fmt, const char *param, int code)
    1758{
    1859    char *answer;
    19     const char *msg = command(fmt, param);
     60    char *msg = send_mail_command(fmt, param);
    2061    // read stdin
    21     // if the string has a form \d\d\d- -- read next string. E.g. EHLO response
     62    // if the string has a form NNN- -- read next string. E.g. EHLO response
    2263    // parse first bytes to a number
    2364    // if code = -1 then just return this number
    2465    // if code != -1 then checks whether the number equals the code
    2566    // if not equal -> die saying msg
    26     while ((answer = xmalloc_fgetline(stdin)) != NULL)
     67    while ((answer = xmalloc_fgetline(stdin)) != NULL) {
     68        if (verbose)
     69            bb_error_msg("recv:'%.*s'", (int)(strchrnul(answer, '\r') - answer), answer);
    2770        if (strlen(answer) <= 3 || '-' != answer[3])
    2871            break;
     72        free(answer);
     73    }
    2974    if (answer) {
    3075        int n = atoi(answer);
     
    3277            alarm(0);
    3378        free(answer);
    34         if (-1 == code || n == code)
     79        if (-1 == code || n == code) {
     80            free(msg);
    3581            return n;
     82        }
    3683    }
    3784    bb_error_msg_and_die("%s failed", msg);
     
    72119    char *s;
    73120    llist_t *list = NULL;
    74     char *domain = sane_address(safe_getdomainname());
     121    char *host = sane_address(safe_gethostname());
    75122    unsigned nheaders = 0;
    76123    int code;
     
    87134        OPT_S = 1 << 6,         // specify connection string
    88135        OPT_a = 1 << 7,         // authentication tokens
     136        OPT_v = 1 << 8,         // verbosity
    89137    };
    90138
     
    97145
    98146    // parse options
    99     // -f is required. -H and -S are mutually exclusive
    100     opt_complementary = "f:w+:H--S:S--H:a::";
     147    // -v is a counter, -f is required. -H and -S are mutually exclusive, -a is a list
     148    opt_complementary = "vv:f:w+:H--S:S--H:a::";
    101149    // N.B. since -H and -S are mutually exclusive they do not interfere in opt_connect
    102150    // -a is for ssmtp (http://downloads.openwrt.org/people/nico/man/man8/ssmtp.8.html) compatibility,
    103151    // it is still under development.
    104     opts = getopt32(argv, "tf:o:iw:H:S:a::", &opt_from, NULL, &timeout, &opt_connect, &opt_connect, &list);
     152    opts = getopt32(argv, "tf:o:iw:H:S:a::v", &opt_from, NULL,
     153            &timeout, &opt_connect, &opt_connect, &list, &verbose);
    105154    //argc -= optind;
    106155    argv += optind;
     
    129178        // plug it in
    130179        launch_helper(args);
    131     // vanilla connection
     180        // Now:
     181        // our stdout will go to helper's stdin,
     182        // helper's stdout will be available on our stdin.
     183
     184        // Wait for initial server message.
     185        // If helper (such as openssl) invokes STARTTLS, the initial 220
     186        // is swallowed by helper (and not repeated after TLS is initiated).
     187        // We will send NOOP cmd to server and check the response.
     188        // We should get 220+250 on plain connection, 250 on STARTTLSed session.
     189        //
     190        // The problem here is some servers delay initial 220 message,
     191        // and consider client to be a spammer if it starts sending cmds
     192        // before 220 reached it. The code below is unsafe in this regard:
     193        // in non-STARTTLSed case, we potentially send NOOP before 220
     194        // is sent by server.
     195        // Ideas? (--delay SECS opt? --assume-starttls-helper opt?)
     196        code = smtp_check("NOOP", -1);
     197        if (code == 220)
     198            // we got 220 - this is not STARTTLSed connection,
     199            // eat 250 response to our NOOP
     200            smtp_check(NULL, 250);
     201        else
     202        if (code != 250)
     203            bb_error_msg_and_die("SMTP init failed");
    132204    } else {
     205        // vanilla connection
    133206        int fd;
    134207        // host[:port] not explicitly specified? -> use $SMTPHOST
    135         // no $SMTPHOST ? -> use localhost
     208        // no $SMTPHOST? -> use localhost
    136209        if (!(opts & OPT_S)) {
    137210            opt_connect = getenv("SMTPHOST");
     
    144217        xmove_fd(fd, STDIN_FILENO);
    145218        xdup2(STDIN_FILENO, STDOUT_FILENO);
    146     }
    147     // N.B. from now we know nothing about network :)
    148 
    149     // wait for initial server OK
    150     // N.B. if we used openssl the initial 220 answer is already swallowed during openssl TLS init procedure
    151     // so we need to kick the server to see whether we are ok
    152     code = smtp_check("NOOP", -1);
    153     // 220 on plain connection, 250 on openssl-helped TLS session
    154     if (220 == code)
    155         smtp_check(NULL, 250); // reread the code to stay in sync
    156     else if (250 != code)
    157         bb_error_msg_and_die("INIT failed");
     219
     220        // Wait for initial server 220 message
     221        smtp_check(NULL, 220);
     222    }
    158223
    159224    // we should start with modern EHLO
    160     if (250 != smtp_checkp("EHLO %s", domain, -1)) {
    161         smtp_checkp("HELO %s", domain, 250);
    162     }
    163     if (ENABLE_FEATURE_CLEAN_UP)
    164         free(domain);
     225    if (250 != smtp_checkp("EHLO %s", host, -1))
     226        smtp_checkp("HELO %s", host, 250);
     227    free(host);
    165228
    166229    // perform authentication
     
    177240
    178241    // set sender
    179     // N.B. we have here a very loosely defined algotythm
     242    // N.B. we have here a very loosely defined algorythm
    180243    // since sendmail historically offers no means to specify secrets on cmdline.
    181244    // 1) server can require no authentication ->
     
    194257    //  opt_from = xasprintf("%s@%s", G.user, domain);
    195258    //}
    196     //if (ENABLE_FEATURE_CLEAN_UP)
    197     //  free(domain);
    198259    smtp_checkp("MAIL FROM:<%s>", opt_from, 250);
    199260
     
    215276                printf(".");
    216277            // dump read line
    217             printf("%s\r\n", s);
     278            send_r_n(s);
    218279            free(s);
    219280            continue;
     
    222283        // analyze headers
    223284        // To: or Cc: headers add recipients
    224         if (0 == strncasecmp("To:", s, 3) || 0 == strncasecmp("Bcc:" + 1, s, 3)) {
    225             rcptto(sane_address(s+3));
    226             goto addheader;
    227         // Bcc: header adds blind copy (hidden) recipient
    228         } else if (0 == strncasecmp("Bcc:", s, 4)) {
    229             rcptto(sane_address(s+4));
    230             free(s);
    231             // N.B. Bcc: vanishes from headers!
    232 
    233         // other headers go verbatim
    234 
    235         // N.B. RFC2822 2.2.3 "Long Header Fields" allows for headers to occupy several lines.
    236         // Continuation is denoted by prefixing additional lines with whitespace(s).
    237         // Thanks (stefan.seyfried at googlemail.com) for pointing this out.
    238         } else if (strchr(s, ':') || (list && skip_whitespace(s) != s)) {
     285        if (opts & OPT_t) {
     286            if (0 == strncasecmp("To:", s, 3) || 0 == strncasecmp("Bcc:" + 1, s, 3)) {
     287                rcptto(sane_address(s+3));
     288                goto addheader;
     289            }
     290            // Bcc: header adds blind copy (hidden) recipient
     291            if (0 == strncasecmp("Bcc:", s, 4)) {
     292                rcptto(sane_address(s+4));
     293                free(s);
     294                continue; // N.B. Bcc: vanishes from headers!
     295            }
     296        }
     297        if (strchr(s, ':') || (list && isspace(s[0]))) {
     298            // other headers go verbatim
     299            // N.B. RFC2822 2.2.3 "Long Header Fields" allows for headers to occupy several lines.
     300            // Continuation is denoted by prefixing additional lines with whitespace(s).
     301            // Thanks (stefan.seyfried at googlemail.com) for pointing this out.
    239302 addheader:
    240303            // N.B. we allow MAX_HEADERS generic headers at most to prevent attacks
     
    242305                goto bail;
    243306            llist_add_to_end(&list, s);
    244         // a line without ":" (an empty line too, by definition) doesn't look like a valid header
    245         // so stop "analyze headers" mode
    246307        } else {
     308            // a line without ":" (an empty line too, by definition) doesn't look like a valid header
     309            // so stop "analyze headers" mode
    247310 reenter:
    248311            // put recipients specified on cmdline
     
    262325            // dump the headers
    263326            while (list) {
    264                 printf("%s\r\n", (char *) llist_pop(&list));
     327                send_r_n((char *) llist_pop(&list));
    265328            }
    266329            // stop analyzing headers
     
    269332            // just dump empty line and break the loop
    270333            if (!s) {
    271                 puts("\r");
     334                send_r_n("");
    272335                break;
    273336            }
Note: See TracChangeset for help on using the changeset viewer.