Changeset 3232 in MondoRescue for branches/3.2/mindi-busybox/mailutils
- Timestamp:
- Jan 1, 2014, 12:47:38 AM (10 years ago)
- Location:
- branches/3.2/mindi-busybox/mailutils
- Files:
-
- 5 edited
Legend:
- Unmodified
- Added
- Removed
-
branches/3.2/mindi-busybox/mailutils/Kbuild.src
r2725 r3232 8 8 9 9 INSERT 10 lib-$(CONFIG_MAKEMIME) += mime.o mail.o11 lib-$(CONFIG_POPMAILDIR) += popmaildir.o mail.o12 lib-$(CONFIG_REFORMIME) += mime.o mail.o13 lib-$(CONFIG_SENDMAIL) += sendmail.o mail.o -
branches/3.2/mindi-busybox/mailutils/mail.c
r2725 r3232 58 58 59 59 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] 64 67 65 68 if (!G.helper_pid) { … … 76 79 } 77 80 78 c onst FAST_FUNC char *command(const char *fmt, const char *param)81 char* FAST_FUNC send_mail_command(const char *fmt, const char *param) 79 82 { 80 c onst char *msg = fmt;83 char *msg; 81 84 if (timeout) 82 85 alarm(timeout); 83 if (msg) { 86 msg = (char*)fmt; 87 if (fmt) { 84 88 msg = xasprintf(fmt, param); 89 if (verbose) 90 bb_error_msg("send:'%s'", msg); 85 91 printf("%s\r\n", msg); 86 92 } … … 91 97 // NB: parse_url can modify url[] (despite const), but only if '@' is there 92 98 /* 93 static char FAST_FUNC *parse_url(char *url, char **user, char **pass)99 static char* FAST_FUNC parse_url(char *url, char **user, char **pass) 94 100 { 95 101 // parse [user[:pass]@]host … … 114 120 { 115 121 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 */ 117 123 DST_BUF_SIZE = 4 * ((SRC_BUF_SIZE + 2) / 3), 118 124 }; … … 170 176 G.pass = xstrdup(bb_ask(fd, /* timeout: */ 0, "Password: ")); 171 177 } 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); 174 180 } 175 181 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 */ 1 9 2 10 struct globals { 3 11 pid_t helper_pid; 4 12 unsigned timeout; 13 unsigned verbose; 5 14 unsigned opts; 6 15 char *user; … … 8 17 FILE *fp0; // initial stdin 9 18 char *opt_charset; 10 char *content_type;11 19 }; 12 20 13 21 #define G (*ptr_to_globals) 14 22 #define timeout (G.timeout ) 23 #define verbose (G.verbose ) 15 24 #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)21 25 #define INIT_G() do { \ 22 26 SET_PTR_TO_GLOBALS(xzalloc(sizeof(G))); \ 23 27 G.opt_charset = (char *)CONFIG_FEATURE_MIME_CHARSET; \ 24 G.content_type = (char *)"text/plain"; \25 28 } while (0) 26 29 27 30 //char FAST_FUNC *parse_url(char *url, char **user, char **pass); 28 31 29 void FAST_FUNC launch_helper(const char **argv);30 void FAST_FUNC get_cred_or_die(int fd);32 void launch_helper(const char **argv) FAST_FUNC; 33 void get_cred_or_die(int fd) FAST_FUNC; 31 34 32 c onst FAST_FUNC char *command(const char *fmt, const char *param);35 char *send_mail_command(const char *fmt, const char *param) FAST_FUNC; 33 36 34 void FAST_FUNC encode_base64(char *fname, const char *text, const char *eol);37 void encode_base64(char *fname, const char *text, const char *eol) FAST_FUNC; -
branches/3.2/mindi-busybox/mailutils/popmaildir.c
r2725 r3232 10 10 * Licensed under GPLv2, see file LICENSE in this source tree. 11 11 */ 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 12 47 #include "libbb.h" 13 48 #include "mail.h" … … 15 50 static void pop3_checkr(const char *fmt, const char *param, char **ret) 16 51 { 17 c onst char *msg =command(fmt, param);52 char *msg = send_mail_command(fmt, param); 18 53 char *answer = xmalloc_fgetline(stdin); 19 54 if (answer && '+' == answer[0]) { 55 free(msg); 20 56 if (timeout) 21 57 alarm(0); … … 28 64 return; 29 65 } 30 bb_error_msg_and_die("%s failed : %s", msg, answer);66 bb_error_msg_and_die("%s failed, reply was: %s", msg, answer); 31 67 } 32 68 -
branches/3.2/mindi-busybox/mailutils/sendmail.c
r2725 r3232 7 7 * Licensed under GPLv2, see file LICENSE in this source tree. 8 8 */ 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 9 43 #include "libbb.h" 10 44 #include "mail.h" … … 14 48 #define MAX_HEADERS 256 15 49 50 static 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 16 57 static int smtp_checkp(const char *fmt, const char *param, int code) 17 58 { 18 59 char *answer; 19 c onst char *msg =command(fmt, param);60 char *msg = send_mail_command(fmt, param); 20 61 // read stdin 21 // if the string has a form \d\d\d- -- read next string. E.g. EHLO response62 // if the string has a form NNN- -- read next string. E.g. EHLO response 22 63 // parse first bytes to a number 23 64 // if code = -1 then just return this number 24 65 // if code != -1 then checks whether the number equals the code 25 66 // 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); 27 70 if (strlen(answer) <= 3 || '-' != answer[3]) 28 71 break; 72 free(answer); 73 } 29 74 if (answer) { 30 75 int n = atoi(answer); … … 32 77 alarm(0); 33 78 free(answer); 34 if (-1 == code || n == code) 79 if (-1 == code || n == code) { 80 free(msg); 35 81 return n; 82 } 36 83 } 37 84 bb_error_msg_and_die("%s failed", msg); … … 72 119 char *s; 73 120 llist_t *list = NULL; 74 char * domain = sane_address(safe_getdomainname());121 char *host = sane_address(safe_gethostname()); 75 122 unsigned nheaders = 0; 76 123 int code; … … 87 134 OPT_S = 1 << 6, // specify connection string 88 135 OPT_a = 1 << 7, // authentication tokens 136 OPT_v = 1 << 8, // verbosity 89 137 }; 90 138 … … 97 145 98 146 // parse options 99 // - f is required. -H and -S are mutually exclusive100 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::"; 101 149 // N.B. since -H and -S are mutually exclusive they do not interfere in opt_connect 102 150 // -a is for ssmtp (http://downloads.openwrt.org/people/nico/man/man8/ssmtp.8.html) compatibility, 103 151 // 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); 105 154 //argc -= optind; 106 155 argv += optind; … … 129 178 // plug it in 130 179 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"); 132 204 } else { 205 // vanilla connection 133 206 int fd; 134 207 // host[:port] not explicitly specified? -> use $SMTPHOST 135 // no $SMTPHOST 208 // no $SMTPHOST? -> use localhost 136 209 if (!(opts & OPT_S)) { 137 210 opt_connect = getenv("SMTPHOST"); … … 144 217 xmove_fd(fd, STDIN_FILENO); 145 218 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 } 158 223 159 224 // 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); 165 228 166 229 // perform authentication … … 177 240 178 241 // set sender 179 // N.B. we have here a very loosely defined algo tythm242 // N.B. we have here a very loosely defined algorythm 180 243 // since sendmail historically offers no means to specify secrets on cmdline. 181 244 // 1) server can require no authentication -> … … 194 257 // opt_from = xasprintf("%s@%s", G.user, domain); 195 258 //} 196 //if (ENABLE_FEATURE_CLEAN_UP)197 // free(domain);198 259 smtp_checkp("MAIL FROM:<%s>", opt_from, 250); 199 260 … … 215 276 printf("."); 216 277 // dump read line 217 printf("%s\r\n",s);278 send_r_n(s); 218 279 free(s); 219 280 continue; … … 222 283 // analyze headers 223 284 // 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. 239 302 addheader: 240 303 // N.B. we allow MAX_HEADERS generic headers at most to prevent attacks … … 242 305 goto bail; 243 306 llist_add_to_end(&list, s); 244 // a line without ":" (an empty line too, by definition) doesn't look like a valid header245 // so stop "analyze headers" mode246 307 } else { 308 // a line without ":" (an empty line too, by definition) doesn't look like a valid header 309 // so stop "analyze headers" mode 247 310 reenter: 248 311 // put recipients specified on cmdline … … 262 325 // dump the headers 263 326 while (list) { 264 printf("%s\r\n",(char *) llist_pop(&list));327 send_r_n((char *) llist_pop(&list)); 265 328 } 266 329 // stop analyzing headers … … 269 332 // just dump empty line and break the loop 270 333 if (!s) { 271 puts("\r");334 send_r_n(""); 272 335 break; 273 336 }
Note:
See TracChangeset
for help on using the changeset viewer.