Пример #1
0
static void check_sender()
{
	const char *h=hdr("reply-to");
	struct rfc822t *t;
	struct rfc822a *a;

	if (!h || !*h)
		h=hdr("from");

	if (!h || !*h)
		exit(0);

	t=rfc822t_alloc_new(h, NULL, NULL);

	if (!t || !(a=rfc822a_alloc(t)))
	{
		perror("malloc");
		exit(EX_TEMPFAIL);
	}

	if (a->naddrs <= 0)
		exit (0);
	sender=rfc822_getaddr(a, 0);
	rfc822a_free(a);
	rfc822t_free(t);

	if (!sender || !*sender)
		exit(0);
}
Пример #2
0
static void check_recips()
{
	char *buf;
	struct rfc822t *t;
	struct rfc822a *a;
	struct header *h;

	if (!recips || !*recips)
		return;

	buf=strdup(recips);
	if (!buf)
	{
		perror("strdup");
		exit(EX_TEMPFAIL);
	}

	for (h=header_list; h; h=h->next)
	{
		int i;

		if (strncasecmp(h->buf, "to:", 3) &&
		    strncasecmp(h->buf, "cc:", 3))
			continue;

		t=rfc822t_alloc_new(h->buf+3, NULL, NULL);
		if (!t || !(a=rfc822a_alloc(t)))
		{
			perror("malloc");
			exit(EX_TEMPFAIL);
		}

		for (i=0; i<a->naddrs; i++)
		{
			char *p=rfc822_getaddr(a, i);
			char *q;

			strcpy(buf, recips);

			for (q=buf; (q=strtok(q, ", ")) != 0; q=0)
			{
				if (p && strcasecmp(p, q) == 0)
				{
					free(p);
					free(buf);
					rfc822a_free(a);
					rfc822t_free(t);
					return;
				}
			}

			free(p);
		}
		rfc822a_free(a);
		rfc822t_free(t);
	}
	free(buf);
	exit(0);
}
Пример #3
0
struct rfc822t *rw_rewrite_tokenize(const char *address)
{
struct rfc822t *tokens=rfc822t_alloc_new(address, NULL, NULL);
int	i;

	if (!tokens)	clog_msg_errno();
	for (i=1; i<tokens->ntokens; i++)
		tokens->tokens[i-1].next=tokens->tokens+i;
	return (tokens);
}
Пример #4
0
static int knownkey(const char *shortname, const char *known_keys)
{
	struct rfc822t *t=rfc822t_alloc_new(shortname, NULL, NULL);
	struct rfc822a *a;
	int i;

	if (!t)
		return (0);

	a=rfc822a_alloc(t);

	if (!a)
	{
		rfc822t_free(t);
		return (0);
	}

	for (i=0; i<a->naddrs; i++)
	{
		char *p=rfc822_getaddr(a, i);
		int plen;
		const char *q;

		if (!p)
			continue;

		if (!*p)
		{
			free(p);
			continue;
		}

		plen=strlen(p);

		for (q=known_keys; *q; )
		{
			if (strncasecmp(q, p, plen) == 0 && q[plen] == '\n')
			{
				free(p);
				rfc822a_free(a);
				rfc822t_free(t);
				return (1);
			}

			while (*q)
				if (*q++ == '\n')
					break;
		}
		free(p);
	}
	rfc822a_free(a);
	rfc822t_free(t);
	return (0);
}
Пример #5
0
char *rfc2045_related_start(const struct rfc2045 *p)
{
const char *cb=rfc2045_getattr( p->content_type_attr, "start");
struct	rfc822t *t;
struct	rfc822a	*a;
int	i;

	if (!cb || !*cb)	return (0);

	t=rfc822t_alloc_new(cb, 0, NULL);
	if (!t)
	{
		rfc2045_enomem();
		return(0);
	}

	a=rfc822a_alloc(t);
	if (!a)
	{
		rfc822t_free(t);
		rfc2045_enomem();
		return (0);
	}
	for (i=0; i<a->naddrs; i++)
		if (a->addrs[i].tokens)
		{
		char	*s=rfc822_getaddr(a, i);

			rfc822a_free(a);
			rfc822t_free(t);
			if (!s)
				rfc2045_enomem();
			return (s);
		}

	rfc822a_free(a);
	rfc822t_free(t);
	return (0);
}
Пример #6
0
static void newmsg_header_rfc822(const char *label, const char *field,
				 const char *encoded, const char *val,
				 int is_readonly)
{
int		hdrmaxlen=512;
const char	*p=getarg("HDRMAXLEN");

	if (p && (atoi(p) > hdrmaxlen))
		hdrmaxlen=atoi(p);

	printf("<tr><th align=\"right\"><p class=\"new-message-header\">"
	       "<span class=\"new-message-header-%s\">%s</span></p></th>"
	       "<td width=\"6\">&nbsp;</td>",
	       field, label);

	printf("<td><input type=\"text\" name=\"%s\" size=\"50\" maxlength=\"%d\""
	       " class=\"new-message-header-text\" value=\"",
		field, hdrmaxlen);
	if (encoded)
	{
		struct rfc822t *t=rfc822t_alloc_new(encoded, NULL, NULL);
		struct rfc822a *a=t ? rfc822a_alloc(t):NULL;

		if (a)
		{
			rfc2047_print_unicodeaddr(a, sqwebmail_content_charset,
						  printc,
						  printsep, NULL);
			rfc822a_free(a);
		}

		if (t)
			rfc822t_free(t);
	}
	else if (val)
		output_attrencoded(val);
	printf("\"%s /></td></tr>\n",
		is_readonly ? " readonly=\"readonly\"":"");
}
Пример #7
0
static struct rfc822t *tokenize(const char *p)
{
struct	rfc822t	*tp;
int	i;
char	buf[2];

	printf("Tokenize: %s\n", p);
	tp=rfc822t_alloc_new(p, NULL, NULL);
	if (!tp)	exit(0);
	buf[1]=0;
	for (i=0; i<tp->ntokens; i++)
	{
		buf[0]=tp->tokens[i].token;
		if (buf[0] == '\0' || buf[0] == '"' || buf[0] == '(')
		{
			printf("%s: ", buf[0] == '"' ? "Quote":
				buf[0] == '(' ? "Comment":"Atom");
			fwrite(tp->tokens[i].ptr, tp->tokens[i].len, 1, stdout);
			printf("\n");
		}
		else	printf("Token: %s\n", buf[0] ? buf:"atom");
	}
	return (tp);
}
Пример #8
0
char *newmsg_alladdrs(FILE *fp)
{
	char	*headers=NULL;
	struct rfc822t *t;
	struct rfc822a *a;
	char *p, *q;
	int l, i;

	if (fp)
	{
		char *header, *value;

		rewind(fp);

		/* First, combine all the headers into one header. */

		while ((header=maildir_readheader(fp, &value, 1)) != 0)
		{
			char *newh;

			if (strcmp(header, "from") &&
			    strcmp(header, "to") &&
			    strcmp(header, "cc") &&
			    strcmp(header, "bcc"))
				continue;

			if (headers)
			{
				newh=realloc(headers, strlen(headers)
					     +strlen(value)+2);
				if (!newh)
					continue;
				strcat(newh, ",");
				headers=newh;
			}
			else
			{
				newh=malloc(strlen(value)+1);
				if (!newh)
					continue;
				*newh=0;
				headers=newh;
			}
			strcat(headers, value);
		}

	}

	/* Now, parse the header, and extract the addresses */

	t=rfc822t_alloc_new(headers ? headers:"", NULL, NULL);
	a= t ? rfc822a_alloc(t):NULL;

	l=1;
	for (i=0; i < (a ? a->naddrs:0); i++)
	{
		p=rfc822_getaddr(a, i);
		if (p)
		{
			++l;
			l +=strlen(p);
			free(p);
		}
	}
	p=malloc(l);
	if (p)
		*p=0;

	for (i=0; i < (a ? a->naddrs:0); i++)
	{
		q=rfc822_getaddr(a, i);
		if (q)
		{
			if (p)
			{
				strcat(strcat(p, q), "\n");
			}
			free(q);
		}
	}

	rfc822a_free(a);
	rfc822t_free(t);
	free(headers);
	return (p);
}
Пример #9
0
static void doenva(void (*writefunc)(const char *, size_t), char *s)
{
struct rfc822t *t;
struct rfc822a *a;
int	i;
char	*q, *r;

	if (!s)
	{
		(*writefunc)("NIL", 3);
		return;
	}

	t=rfc822t_alloc_new(s, 0, 0);
	if (!t)
	{
		perror("malloc");
		exit(0);
	}
	a=rfc822a_alloc(t);
	if (!a)
	{
		perror("malloc");
		exit(1);
	}

	if (a->naddrs == 0)
	{
		rfc822a_free(a);
		rfc822t_free(t);
		free(s);
		(*writefunc)("NIL", 3);
		return;
	}

	(*writefunc)("(", 1);
	for (i=0; i<a->naddrs; i++)
	{
		(*writefunc)("(", 1);

		q=rfc822_display_name_tobuf(a, i, NULL);

		if (!q)
		{
			perror("malloc");
			exit(1);
		}
		if (a->addrs[i].tokens == 0)
		{
			if (strcmp(q, ";") == 0)
			{
				(*writefunc)("NIL NIL NIL NIL)", 16);
				free(q);
				continue;
			}
			r=strrchr(q, ':');
			if (r && r[1] == 0)	*r=0;

			(*writefunc)("NIL NIL \"", 9);
			msgappends(writefunc, q, strlen(q));
			(*writefunc)("\" NIL)", 6);
			free(q);
			continue;
		}

		if (a->addrs[i].name == 0)
			*q=0;
		/* rfc822_display_name_tobuf() defaults to addr, ignore. */

		doenvs(writefunc, q);
		(*writefunc)(" NIL \"", 6);	/* TODO @domain list */
		q=rfc822_gettok(a->addrs[i].tokens);
		if (!q)
		{
			perror("malloc");
			exit(1);
		}
		r=strrchr(q, '@');
		if (r)	*r++=0;
		msgappends(writefunc, q, strlen(q));
		(*writefunc)("\" \"", 3);
		if (r)
			msgappends(writefunc, r, strlen(r));
		(*writefunc)("\")", 2);
		free(q);
	}
	(*writefunc)(")", 1);
	rfc822a_free(a);
	rfc822t_free(t);
	free(s);
}
Пример #10
0
static char *rewrite_from(const char *oldfrom, const char *newuser,
	const char *newhost, const char *newname)
{
struct rfc822t *rfct;
struct rfc822a *rfca;
struct rfc822t *usert, *hostt, *namet;
struct rfc822token attoken, **tp;
char	*p;
const char *q;
char	*gecosname=0;

	if (!oldfrom)
	{
	char	*p=courier_malloc(
			(newuser ? strlen(newuser):0)+
			(newhost ? strlen(newhost):0)+4);
		strcpy(p, "<");
		if (newuser)	strcat(p, newuser);
		if (newuser && newhost)
			strcat(strcat(p, "@"), newhost);
		strcat(p, ">");
		if (newname)
		{
		char *q, *r;

			namet=tokenize_name(newname);
			q=rfc822_gettok(namet->tokens);
			rfc822t_free(namet);
			r=courier_malloc(strlen(p)+strlen(q)+2);
			strcat(strcat(strcpy(r, q), " "), p);
			free(p);
			p=r;
			free(q);
		}
		return (p);
	}

	if ((rfct=rfc822t_alloc_new(oldfrom, NULL, NULL)) == 0 ||
		(rfca=rfc822a_alloc(rfct)) == 0)
	{
		clog_msg_errno();
		return(0);
	}

	if ((q=env("MAILNAME")) || (q=env("NAME")))
		newname=q;

	if (!newname && rfca->naddrs == 0)
		newname=gecosname=get_gecos();

	if ((rfca->naddrs == 0 || rfca->addrs[0].tokens == 0) && newuser == 0)
	{
	struct	passwd *pw=mypwd();

		if (pw)	newuser=pw->pw_name;
	}

	namet=newname ? tokenize_name(newname):0;
	usert=newuser ? rw_rewrite_tokenize(newuser):0;
	hostt=newhost ? rw_rewrite_tokenize(newhost):0;

	if (rfca->naddrs == 0 || rfca->addrs[0].tokens == 0)
	{
	struct rfc822addr a;
	struct rfc822a	fakea;

		if (hostt)
		{
		struct rfc822token *t;

			attoken.token='@';
			attoken.next=hostt->tokens;
			attoken.ptr=0;
			attoken.len=0;

			for (t=usert->tokens; t->next; t=t->next)
				;
			t->next=&attoken;
		}
		fakea.naddrs=1;
		fakea.addrs= &a;

		if (!namet)	namet=tokenize_name("");
		if (!usert)	usert=rw_rewrite_tokenize("");
		a.name=namet->tokens;
		a.tokens=usert->tokens;
		p=rfc822_getaddrs(&fakea);
	}
	else
	{
	struct	rfc822token *t, *u;

		rfca->naddrs=1;
		if (usert)
		{
			for (t=rfca->addrs[0].tokens; t; t=t->next)
				if (t->token == '@')	break;
			
			for (u=usert->tokens; u->next; u=u->next)
				;
			u->next=t;
			rfca->addrs[0].tokens=usert->tokens;;
		}

		if (hostt && rfca->addrs[0].tokens)
		{
			for (tp= &rfca->addrs[0].tokens; *tp;
				tp= &(*tp)->next)
				if ( (*tp)->token == '@')	break;
			*tp=&attoken;
			attoken.token='@';
			attoken.next=hostt->tokens;
			attoken.ptr=0;
			attoken.len=0;
		}
		if (namet)
			rfca->addrs[0].name=namet->tokens;

		p=rfc822_getaddrs(rfca);
	}

	if (!p)	clog_msg_errno();

	if (usert)	rfc822t_free(usert);
	if (hostt)	rfc822t_free(hostt);
	if (namet)	rfc822t_free(namet);
	rfc822t_free(rfct);
	rfc822a_free(rfca);
	if (gecosname)	free(gecosname);
	return (p);
}
Пример #11
0
static void do_header(struct rfc2045 *p)
{
struct rfc822t *header;
char	*t;

	if (p->headerlen == 0)	return;
	rfc2045_add_buf( &p->header, &p->headersize, &p->headerlen, "", 1);
				/* 0 terminate */

	/* Parse the header line according to RFC822 */

	header=rfc822t_alloc_new(p->header, NULL, NULL);

	if (!header)	return;	/* Broken header */

	if (header->ntokens < 2 ||
		header->tokens[0].token ||
		header->tokens[1].token != ':')
	{
		rfc822t_free(header);
		return;	/* Broken header */
	}

	t=lower_paste_token(header, 0);

	if (t == 0)
		;
	else if (strcmp(t, "mime-version") == 0)
	{
		free(t);
		mime_version(p, header);
	}
	else if (strcmp(t, "content-type") == 0)
	{
		free(t);
		content_type(p, header);
	} else if (strcmp(t, "content-transfer-encoding") == 0)
	{
		free(t);
		content_transfer_encoding(p, header);
	} else if (strcmp(t, "content-disposition") == 0)
	{
		free(t);
		content_disposition(p, header);
	} else if (strcmp(t, "content-id") == 0)
	{
		free(t);
		content_id(p, header);
	} else if (strcmp(t, "content-description") == 0)
	{
		free(t);
		t=strchr(p->header, ':');
		if (t)	++t;
		while (t && isspace((int)(unsigned char)*t))
			++t;
		content_description(p, t);
	} else if (strcmp(t, "content-language") == 0)
	{
		free(t);
		t=strchr(p->header, ':');
		if (t)	++t;
		while (t && isspace((int)(unsigned char)*t))
			++t;
		content_language(p, t);
	} else if (strcmp(t, "content-base") == 0)
	{
		free(t);
		content_base(p, header);
	} else if (strcmp(t, "content-location") == 0)
	{
		free(t);
		content_location(p, header);
	} else if (strcmp(t, "content-md5") == 0)
	{
		free(t);
		t=strchr(p->header, ':');
		if (t)	++t;
		while (t && isspace((int)(unsigned char)*t))
			++t;
		content_md5(p, t);
	}
	else	free(t);
	rfc822t_free(header);
}
Пример #12
0
static void dodel(const char *username, const char *userhome,
	FILE *c, char *ctl,
	const char *extension, const char *sender, const char *receipient,
	const char *defaultext, const char *quota, const char *defaultmail,
	int recursion_level)
{
char	*ufromline;
char	*dtline;
char	*rpline;
time_t	t;
const char *curtime;

	time(&t);
	curtime=ctime(&t);
	if ((ufromline=malloc(strlen(curtime)+strlen(sender)+30))==0||
		(dtline=malloc(strlen(receipient)+
			sizeof("Delivered-To: "))) == 0 ||
		(rpline=malloc(strlen(sender) +
			sizeof("Return-Path: <>"))) == 0)
	{
		perror("malloc");
		exit(EX_TEMPFAIL);
	}

	if ( (!ctl || !*ctl) && recursion_level == 0)
	{
	const char *p= *defaultmail ? defaultmail:config_defaultdelivery();

		if ((ctl=malloc(strlen(p)+1)) == 0)
		{
			perror("malloc");
			exit(EX_TEMPFAIL);
		}
		strcpy(ctl, p);
	}

	sprintf(ufromline, "From %s %s", sender, curtime);

	{
	char *p;

		if ((p=strchr(ufromline, '\n')) != 0)
			*p=0;
	}

	strcat(strcpy(dtline, "Delivered-To: "), receipient);
	strcat(strcat(strcpy(rpline, "Return-Path: <"), sender), ">");

	while (*ctl)
	{
		if (*ctl == '#' || *ctl == '\n')
		{
			while (*ctl)
				if (*ctl++ == '\n')	break;
			continue;
		}

		/*
		** The fd hack is needed for BSD, whose C lib doesn't like
		** mixing stdio and unistd seek calls.
		*/

		if (*ctl == '.' || *ctl == '/')
		{
		const char *filename=ctl;
		int fd_hack=dup(fileno(stdin));
		FILE *fp_hack;

			if (fd_hack < 0 || lseek(fd_hack, 0L, SEEK_SET) < 0 ||
				(fp_hack=fdopen(fd_hack, "r")) == NULL)
			{
				perror("dup");
				exit(EX_TEMPFAIL);
			}

			while (*ctl)
			{
				if (*ctl == '/' && (ctl[1] == '\n' ||
					ctl[1] == 0))
					*ctl=0; /* Strip trailing / */
				if (*ctl == '\n')
				{
					*ctl++='\0';
					break;
				}
				++ctl;
			}

			if (savemessage(extension, sender, receipient,
				fp_hack, filename,
				ufromline,
				dtline,
				rpline, quota))
				exit(EX_TEMPFAIL);
			fclose(fp_hack);
			close(fd_hack);
			continue;
		}
		if (*ctl == '|')
		{
		const char *command=++ctl;
		int	rc;
		int fd_hack=dup(fileno(stdin));
		FILE *fp_hack;

			if (fd_hack < 0 || lseek(fd_hack, 0L, SEEK_SET) < 0 ||
				(fp_hack=fdopen(fd_hack, "r")) == NULL)
			{
				perror("dup");
				exit(EX_TEMPFAIL);
			}

			ctl=skip_eol(ctl, 0);
			while (*command == ' ' || *command == '\t')
				++command;

			rc=docommand(extension, sender, receipient, defaultext,
				fp_hack, username, userhome, command,
				dtline,
				rpline,
				ufromline,
				quota, defaultmail,
				recursion_level);
			if (rc)
				exit(rc);
			fclose(fp_hack);
			close(fd_hack);
			continue;
		}

		/* Forwarding instructions, parse RFC822 addresses */

		if (*ctl == '&' || *ctl == '!')	++ctl;	/* Legacy */
		{
			const char *addresses=ctl;
			struct rfc822t *tokens;
			struct rfc822a *addrlist;
			int n;

			ctl=skip_eol(ctl, 1);
			if ((tokens=rfc822t_alloc_new(addresses, NULL,
						      NULL)) == 0 ||
				(addrlist=rfc822a_alloc(tokens)) == 0)
			{
				perror("malloc");
				exit(EX_TEMPFAIL);
			}

			for (n=0; n<addrlist->naddrs; ++n)
			{
				char *p;

				if (addrlist->addrs[n].tokens == NULL)
					continue;

				p=rfc822_display_addr_tobuf(addrlist, n,
							    NULL);

				if (!p)
				{
					perror(addresses);
					exit(EX_TEMPFAIL);
				}

				printf("%s\n", p);
				free(p);
			}
			rfc822a_free(addrlist);
			rfc822t_free(tokens);
			fflush(stdout);
		}
	}
			
	free(rpline);
	free(dtline);
	free(ufromline);
}
Пример #13
0
static void readforward(FILE *f, int n)
{
char	buf[BUFSIZ];
char	*p;
struct	rfc822t *t;
struct	rfc822a *a;
int	i;
char	*sep;

	while (fgets(buf, sizeof(buf), f))
	{
		p=strchr(buf, '\n');
		if (p)	*p=0;
		p=buf;
		while (*p && isspace((int)(unsigned char)*p))	++p;
		if (strncmp(p, ":include:",  9) == 0)
		{
		FILE	*g;

			if (n > 10)
			{
				fprintf(stderr, "dotforward: too many :include files.\n");
				exit(EX_NOUSER);
			}

			p += 9;
			while (*p && isspace((int)(unsigned char)*p))	++p;
			if (!*p)	continue;
			g=fopen(p, "r");
			if (!g)
			{
				perror(p);
				exit(EX_NOUSER);
			}
			readforward(g, n+1);
			fclose(g);
			continue;
		}
		if (*p == '|' || *p == '/' || *p == '.')
		{
			printf("%s\n", p);
			continue;
		}
		t=rfc822t_alloc_new(p, NULL, NULL);
		if (!t || !(a=rfc822a_alloc(t)))
		{
			perror("malloc");
			exit(EX_NOUSER);
		}

		for (i=0; i<a->naddrs; i++)
		{
			if (a->addrs[i].tokens &&
			    a->addrs[i].tokens->token == '"' &&
			    a->addrs[i].tokens->next == NULL)
				a->addrs[i].tokens->token=0;

			p=rfc822_getaddr(a, i);
			if (!p)
			{
				perror("malloc");
				exit(EX_NOUSER);
			}
			if (*p == '|' || *p == '/')
			{
				printf("%s\n", p);
			}
			free(p);
		}
		sep=0;
		for (i=0; i<a->naddrs; i++)
		{
		char	*q, *r;
		struct delivered_to *s;
		char	*t;
		char	*orig;

			p=rfc822_getaddr(a, i);
			if (!p)
			{
				perror("malloc");
				exit(EX_NOUSER);
			}
			if (*p == '|' || *p == '/' || *p == '.')
			{
				free(p);
				continue;
			}
			q=p;
			if (*q == '\\')
				++q;

			r=strchr(q, '@');
			if (!r || config_islocal(r+1, 0))
				locallower(q);
			domainlower(q);
			t=0;
			orig=q;

			if (strchr(q, '@') == 0)
			{
				t=malloc(strlen(q)+1+strlen(myaddr));
					/* overkill, yeah */
				if (!t)
				{
					perror("malloc");
					exit(EX_NOUSER);
				}
				strcat(strcpy(t, q), strchr(myaddr, '@'));
				q=t;
			}

			if (strcmp(myaddr, q) == 0)
			{
				exit_code=0;
				free(p);
				if (t)	free(t);
				continue;
			}

			for (s=delivtolist; s; s=s->next)
			{
				if (strcmp(s->addr, q) == 0)
					break;
			}
			if (!s)
			{
				if (sep)	printf("%s", sep);
				else	printf("!");
				sep=", ";
				printf("%s", orig);
			}
			free(p);
			if (t)	free(t);
		}
		if (sep)	printf("\n");
		rfc822a_free(a);
		rfc822t_free(t);
	}
}