1
0
This repository has been archived on 2024-07-22. You can view files and clone it, but cannot push or open issues or pull requests.
TP-Link_Archer-XR500v/BBA1.5_platform/apps/public/mailx-12.5/ssl.c
2024-07-22 01:58:46 -03:00

353 lines
8.3 KiB
C
Executable File

/*
* Heirloom mailx - a mail user agent derived from Berkeley Mail.
*
* Copyright (c) 2000-2004 Gunnar Ritter, Freiburg i. Br., Germany.
*/
/*
* Copyright (c) 2002
* Gunnar Ritter. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by Gunnar Ritter
* and his contributors.
* 4. Neither the name of Gunnar Ritter nor the names of his contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY GUNNAR RITTER AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL GUNNAR RITTER OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#ifndef lint
#ifdef DOSCCS
static char sccsid[] = "@(#)ssl.c 1.39 (gritter) 6/12/06";
#endif
#endif /* not lint */
#include "config.h"
#include "rcv.h"
#include "extern.h"
void
ssl_set_vrfy_level(const char *uhp)
{
char *cp;
char *vrvar;
ssl_vrfy_level = VRFY_ASK;
vrvar = ac_alloc(strlen(uhp) + 12);
strcpy(vrvar, "ssl-verify-");
strcpy(&vrvar[11], uhp);
if ((cp = value(vrvar)) == NULL)
cp = value("ssl-verify");
ac_free(vrvar);
if (cp != NULL) {
if (equal(cp, "strict"))
ssl_vrfy_level = VRFY_STRICT;
else if (equal(cp, "ask"))
ssl_vrfy_level = VRFY_ASK;
else if (equal(cp, "warn"))
ssl_vrfy_level = VRFY_WARN;
else if (equal(cp, "ignore"))
ssl_vrfy_level = VRFY_IGNORE;
else
DEBUG_ERROR( catgets(catd, CATSET, 265,
"invalid value of ssl-verify: %s\n"),
cp);
}
}
enum okay
ssl_vrfy_decide(void)
{
enum okay ok = STOP;
switch (ssl_vrfy_level) {
case VRFY_STRICT:
ok = STOP;
break;
case VRFY_ASK:
{
char *line = NULL;
size_t linesize = 0;
DEBUG_ERROR( catgets(catd, CATSET, 264,
"Continue (y/n)? "));
if (readline(stdin, &line, &linesize) > 0 &&
*line == 'y')
ok = OKAY;
else
ok = STOP;
if (line)
free(line);
}
break;
case VRFY_WARN:
case VRFY_IGNORE:
ok = OKAY;
}
return ok;
}
char *
ssl_method_string(const char *uhp)
{
char *cp, *mtvar;
mtvar = ac_alloc(strlen(uhp) + 12);
strcpy(mtvar, "ssl-method-");
strcpy(&mtvar[11], uhp);
if ((cp = value(mtvar)) == NULL)
cp = value("ssl-method");
ac_free(mtvar);
return cp;
}
enum okay
smime_split(FILE *ip, FILE **hp, FILE **bp, long xcount, int keep)
{
char *buf, *hn, *bn;
char *savedfields = NULL;
size_t bufsize, buflen, count, savedsize = 0;
int c;
if ((*hp = Ftemp(&hn, "Rh", "w+", 0600, 1)) == NULL ||
(*bp = Ftemp(&bn, "Rb", "w+", 0600, 1)) == NULL) {
perror("tempfile");
return STOP;
}
unlink(hn);
unlink(bn);
Ftfree(&hn);
Ftfree(&bn);
buf = smalloc(bufsize = LINESIZE);
savedfields = smalloc(savedsize = 1);
*savedfields = '\0';
if (xcount < 0)
count = fsize(ip);
else
count = xcount;
while (fgetline(&buf, &bufsize, &count, &buflen, ip, 0) != NULL &&
*buf != '\n') {
if (ascncasecmp(buf, "content-", 8) == 0) {
if (keep)
fputs("X-Encoded-", *hp);
for (;;) {
savedsize += buflen;
savedfields = srealloc(savedfields, savedsize);
strcat(savedfields, buf);
if (keep)
fwrite(buf, sizeof *buf, buflen, *hp);
c = getc(ip);
ungetc(c, ip);
if (!blankchar(c))
break;
fgetline(&buf, &bufsize, &count, &buflen,
ip, 0);
}
continue;
}
fwrite(buf, sizeof *buf, buflen, *hp);
}
fflush(*hp);
rewind(*hp);
fputs(savedfields, *bp);
putc('\n', *bp);
while (fgetline(&buf, &bufsize, &count, &buflen, ip, 0) != NULL)
fwrite(buf, sizeof *buf, buflen, *bp);
fflush(*bp);
rewind(*bp);
free(buf);
return OKAY;
}
FILE *
smime_sign_assemble(FILE *hp, FILE *bp, FILE *sp)
{
char *boundary, *cp;
FILE *op;
int c, lastc = EOF;
if ((op = Ftemp(&cp, "Rs", "w+", 0600, 1)) == NULL) {
perror("tempfile");
return NULL;
}
unlink(cp);
Ftfree(&cp);
boundary = makeboundary();
while ((c = getc(hp)) != EOF) {
if (c == '\n' && lastc == '\n')
break;
putc(c, op);
lastc = c;
}
fprintf(op, "Content-Type: multipart/signed;\n"
" protocol=\"application/x-pkcs7-signature\"; micalg=sha1;\n"
" boundary=\"%s\"\n\n", boundary);
fprintf(op, "This is an S/MIME signed message.\n\n--%s\n",
boundary);
while ((c = getc(bp)) != EOF)
putc(c, op);
fprintf(op, "\n--%s\n", boundary);
fputs("Content-Type: application/x-pkcs7-signature; "
"name=\"smime.p7s\"\n"
"Content-Transfer-Encoding: base64\n"
"Content-Disposition: attachment; filename=\"smime.p7s\"\n\n",
op);
while ((c = getc(sp)) != EOF) {
if (c == '-') {
while ((c = getc(sp)) != EOF && c != '\n');
continue;
}
putc(c, op);
}
fprintf(op, "\n--%s--\n", boundary);
Fclose(hp);
Fclose(bp);
Fclose(sp);
fflush(op);
if (ferror(op)) {
perror("signed output data");
Fclose(op);
return NULL;
}
rewind(op);
return op;
}
FILE *
smime_encrypt_assemble(FILE *hp, FILE *yp)
{
char *cp;
FILE *op;
int c, lastc = EOF;
if ((op = Ftemp(&cp, "Rs", "w+", 0600, 1)) == NULL) {
perror("tempfile");
return NULL;
}
unlink(cp);
Ftfree(&cp);
while ((c = getc(hp)) != EOF) {
if (c == '\n' && lastc == '\n')
break;
putc(c, op);
lastc = c;
}
fprintf(op, "Content-Type: application/x-pkcs7-mime; "
"name=\"smime.p7m\"\n"
"Content-Transfer-Encoding: base64\n"
"Content-Disposition: attachment; "
"filename=\"smime.p7m\"\n\n");
while ((c = getc(yp)) != EOF) {
if (c == '-') {
while ((c = getc(yp)) != EOF && c != '\n');
continue;
}
putc(c, op);
}
Fclose(hp);
Fclose(yp);
fflush(op);
if (ferror(op)) {
perror("encrypted output data");
Fclose(op);
return NULL;
}
rewind(op);
return op;
}
struct message *
smime_decrypt_assemble(struct message *m, FILE *hp, FILE *bp)
{
int binary = 0, lastnl = 0;
char *buf = NULL, *cp;
size_t bufsize = 0, buflen, count;
long lines = 0, octets = 0;
struct message *x;
off_t offset;
x = salloc(sizeof *x);
*x = *m;
fflush(mb.mb_otf);
fseek(mb.mb_otf, 0L, SEEK_END);
offset = ftell(mb.mb_otf);
count = fsize(hp);
while (fgetline(&buf, &bufsize, &count, &buflen, hp, 0) != NULL) {
if (buf[0] == '\n')
break;
if ((cp = thisfield(buf, "content-transfer-encoding")) != NULL)
if (ascncasecmp(cp, "binary", 7) == 0)
binary = 1;
fwrite(buf, sizeof *buf, buflen, mb.mb_otf);
octets += buflen;
lines++;
}
octets += mkdate(mb.mb_otf, "X-Decoding-Date");
lines++;
count = fsize(bp);
while (fgetline(&buf, &bufsize, &count, &buflen, bp, 0) != NULL) {
lines++;
if (!binary && buf[buflen-1] == '\n' && buf[buflen-2] == '\r')
buf[--buflen-1] = '\n';
fwrite(buf, sizeof *buf, buflen, mb.mb_otf);
octets += buflen;
if (buf[0] == '\n')
lastnl++;
else if (buf[buflen-1] == '\n')
lastnl = 1;
else
lastnl = 0;
}
while (!binary && lastnl < 2) {
putc('\n', mb.mb_otf);
lines++;
octets++;
lastnl++;
}
Fclose(hp);
Fclose(bp);
free(buf);
fflush(mb.mb_otf);
if (ferror(mb.mb_otf)) {
perror("decrypted output data");
return NULL;
}
x->m_size = x->m_xsize = octets;
x->m_lines = x->m_xlines = lines;
x->m_block = mailx_blockof(offset);
x->m_offset = mailx_offsetof(offset);
return x;
}
enum okay
rfc2595_hostname_match(const char *host, const char *pattern)
{
if (pattern[0] == '*' && pattern[1] == '.') {
pattern++;
while (*host && *host != '.')
host++;
}
return asccasecmp(host, pattern) == 0 ? OKAY : STOP;
}