static int maildir_tmpcreate_fd_do(struct maildir_tmpcreate_info *info)
{
	const char *maildir=info->maildir;
	const char *uniq=info->uniq;
	const char *hostname=info->hostname;

	char hostname_buf[256];
	char time_buf[NUMBUFSIZE];
	char usec_buf[NUMBUFSIZE];
	char pid_buf[NUMBUFSIZE];
	char len_buf[NUMBUFSIZE+3];
	char dev_buf[NUMBUFSIZE];
	char ino_buf[NUMBUFSIZE];
	struct timeval tv;

	struct stat stat_buf;
	int fd;

	if (!maildir)
		maildir=".";
	if (!uniq)
		uniq="";

	if (!hostname || !*hostname)
	{
		hostname_buf[sizeof(hostname_buf)-1]=0;
		if (gethostname(hostname_buf, sizeof(hostname_buf)-1) < 0)
			strcpy(hostname_buf, "localhost");
		hostname=hostname_buf;
	}

	gettimeofday(&tv, NULL);

	libmail_str_time_t(tv.tv_sec, time_buf);
	libmail_str_time_t(tv.tv_usec, usec_buf);
	libmail_str_pid_t(getpid(), pid_buf);
	len_buf[0]=0;
	if (info->msgsize > 0)
	{
		strcpy(len_buf, ",S=");
		libmail_str_size_t(info->msgsize, len_buf+3);
	}

	if (info->tmpname)
		free(info->tmpname);

	info->tmpname=malloc(strlen(maildir)+strlen(uniq)+
			     strlen(hostname)+strlen(time_buf)+
			     strlen(usec_buf)+
			     strlen(pid_buf)+strlen(len_buf)+100);

	if (!info->tmpname)
	{
		maildir_tmpcreate_free(info);
		return -1;
	}

	strcpy(info->tmpname, maildir);
	strcat(info->tmpname, "/tmp/");
	strcat(info->tmpname, time_buf);
	strcat(info->tmpname, ".M");
	strcat(info->tmpname, usec_buf);
	strcat(info->tmpname, "P");
	strcat(info->tmpname, pid_buf);

	if (*uniq)
		strcat(strcat(info->tmpname, "_"), uniq);
	strcat(info->tmpname, ".");
	strcat(info->tmpname, hostname);
	strcat(info->tmpname, len_buf);

	if (stat( info->tmpname, &stat_buf) == 0)
	{
		maildir_tmpcreate_free(info);
		errno=EAGAIN;
		return -1;
	}

	if (errno != ENOENT)
	{
		maildir_tmpcreate_free(info);
		if (errno == EAGAIN)
			errno=EIO;
		return -1;
	}

	if ((fd=maildir_safeopen_stat(info->tmpname, O_CREAT|O_RDWR|O_TRUNC,
				      info->openmode, &stat_buf)) < 0)
	{
		maildir_tmpcreate_free(info);
		return -1;
	}

	libmail_strh_dev_t(stat_buf.st_dev, dev_buf);
	libmail_strh_ino_t(stat_buf.st_ino, ino_buf);

	if (info->newname)
		free(info->newname);
	info->newname=NULL;

	if (info->curname)
		free(info->curname);
	info->curname=NULL;

	info->newname=malloc(strlen(info->tmpname)+strlen(ino_buf)+
			     strlen(dev_buf)+3);

	if (info->newname)
	{
		info->curname=malloc(strlen(info->tmpname)+strlen(ino_buf)+
				     strlen(dev_buf)+3);
		if (!info->curname)
		{
			free(info->newname);
			info->newname=NULL;
		}
	}

	if (!info->newname)
	{
		maildir_tmpcreate_free(info);
		unlink(info->tmpname);
		close(fd);
		if (errno == EAGAIN)
			errno=EIO;
		return -1;
	}

	strcpy(info->newname, maildir);
	strcat(info->newname, "/new/");
	strcat(info->newname, time_buf);
	strcat(info->newname, ".M");
	strcat(info->newname, usec_buf);
	strcat(info->newname, "P");
	strcat(info->newname, pid_buf);
	strcat(info->newname, "V");
	strcat(info->newname, dev_buf);
	strcat(info->newname, "I");
	strcat(info->newname, ino_buf);
	if (*uniq)
		strcat(strcat(info->newname, "_"), uniq);
	strcat(info->newname, ".");
	strcat(info->newname, hostname);
	strcat(info->newname, len_buf);

	strcpy(info->curname, info->newname);
	memcpy(info->curname + strlen(maildir)+1, "cur", 3);

	return fd;
}
Beispiel #2
0
static char *mkcmdbuf(const char *name, const char *addr, const char *comment,
		      int skeylen,
		      int ekeylen,
		      unsigned expire,
		      char expire_unit,
		      const char *passphrase)
{
	static const char genkey_cmd[]=
		"Key-Type: DSA\n"
		"Key-Length: %s\n"
		"Subkey-Type: ELG-E\n"
		"Subkey-Length: %s\n"
		"Name-Real: %s\n"
		"%s%s%s"
		"%s%s%s"
		"Name-Email: %s\n"
		"Expire-Date: %s\n"
		"%%commit\n";

	static const char comment1[]="Name-Comment: ";
	static const char comment2[]="\n";
	static const char passphrase1[]="Passphrase: ";
	static const char passphrase2[]="\n";

	char skl_buf[NUMBUFSIZE];
	char kl_buf[NUMBUFSIZE];
	char exp_buf[NUMBUFSIZE+1];

	char *p;

	libmail_str_size_t(skeylen, skl_buf);
	libmail_str_size_t(ekeylen, kl_buf);
	if (expire == 0)
	{
		strcpy(exp_buf, "0");
	}
	else
	{
		char b[2];

		b[0]=expire_unit;
		b[1]=0;

		strcat(libmail_str_size_t(expire, exp_buf), b);
	}

	p=malloc(256+strlen(kl_buf)+strlen(skl_buf)+strlen(exp_buf)
		 +strlen(name)+strlen(addr)+strlen(comment)
		 +strlen(passphrase));

	if (!p)
		return (NULL);

	while (*comment == ' ' || *comment == '\t')
		++comment;

	sprintf(p, genkey_cmd, skl_buf, kl_buf, name,
		*comment ? comment1:"",
		comment,
		*comment ? comment2:"",

		*passphrase ? passphrase1:"",
		passphrase,
		*passphrase ? passphrase2:"",

		addr, exp_buf);
	return (p);
}
Beispiel #3
0
int msgq::tmpscan()
{
	int	found=0;

	time(&current_time);

	DIR *tmpdir=opendir(TMPDIR);

	if (!tmpdir)	clog_msg_errno();

	struct dirent *de;
	std::string	subdir;
	std::string	ctlfile, datfile, newctlfile, newdatfile;
	struct	stat stat_buf;
	std::string	qdir, qname;

	while ((de=readdir(tmpdir)) != 0)
	{
	const char *p;

		for (p=de->d_name; *p; p++)
			if (!isdigit((int)(unsigned char)*p))	break;
		if (*p)	continue;	// Subdirs must be named all digits

		subdir=TMPDIR "/";
		subdir += de->d_name;

		DIR *subde=opendir(subdir.c_str());

		while ((de=readdir(subde)) != 0 && found < 100)
		{
			if (strcmp(de->d_name, ".") == 0 ||
				strcmp(de->d_name, "..") == 0)	continue;

			ctlfile=subdir;
			ctlfile += '/';
			ctlfile += de->d_name;

			int	i=-1;

			if (stat(ctlfile.c_str(), &stat_buf))	continue;

			size_t j=ctlfile.size();

			while (j)
			{
				if (ctlfile[--j] == '/')
					break;

				if (ctlfile[j] == '.')
				{
					i=j;
					break;
				}
			}

		ino_t	inum=stat_buf.st_ino;

		// Cleanup timeout. Should always be sufficiently longer than
		// the submit timeout set in submit.C via alarm_timeout.

			if (stat_buf.st_mtime < current_time - 48 * 60 * 60)
			{
				if (de->d_name[0] == 'D')
				{
					datfile=subdir + "/C" +
						(de->d_name+1);

					if (stat(datfile.c_str(), &stat_buf)
					    == 0)
						continue;
						// Wait until the C file is
						// purged

				// Be carefull with Cnnnn.x files, because
				// Cnnnn.1 is used to hold submission of all
				// of them.  A race condition can leave
				// Cnnnn.1 in a submittable state, so if it
				// is removed, other copies of this message
				// can become submittable, during a very small
				// window.

				} else if (de->d_name[0] == 'C' && i >= 0)
				{

				// This race condition is handled simply
				// by not removing Cxxxxx.n if Cxxxxx.n+1
				// exists.

					char	nbuf[NUMBUFSIZE];

					datfile=ctlfile.substr(0, i);

					size_t	n=atoi( ctlfile.c_str()+i+1);

					++n;

					datfile += '.';
					datfile += libmail_str_size_t(n, nbuf);

					if (stat(datfile.c_str(), &stat_buf)
					    == 0)
						continue;
						// Wait until the C.1 file is
						// purged

					unlink(ctlfile.c_str());

					ctlfile=subdir + "/D" +
						(de->d_name+1);
					/* FALLTHRU */
				}
				unlink(ctlfile.c_str());
				continue;
			}

			if (de->d_name[0] != 'C')	continue;
			if (i >= 0)
			{
				datfile=ctlfile.substr(0, i);
				datfile += ".1";

				if (ctlfile == datfile ||
				    stat(datfile.c_str(), &stat_buf) == 0)
					continue;
			}


			datfile=subdir + "/D" + (de->d_name+1);

			newdatfile=qmsgsdatname(inum);
			newctlfile=qmsgsctlname(inum);

			struct	ctlfile ctf;

			if ((access(datfile.c_str(), 0) == 0 &&
			     access(newdatfile.c_str(), 0) == 0) ||
			    access(newctlfile.c_str(), 0) == 0 ||
			    ctlfile_openfn(ctlfile.c_str(), &ctf, 0, 0))
			{
				clog_msg_start_err();
				clog_msg_str("QUEUE FILE CORRUPTION: inode ");
				clog_msg_uint(inum);
				clog_msg_send();
				utime(ctlfile.c_str(), 0);
				// Keep it around
				continue;
			}

		time_t	nextattempt=current_time+delaytime;

			if ((i=ctlfile_searchfirst(&ctf,
				COMCTLFILE_SUBMITDELAY)) >= 0)
				nextattempt=current_time+
					atoi(ctf.lines[i]+1);

			qname=qmsgqname(inum, nextattempt);

			ctlfile_nextattempt(&ctf, nextattempt);

			if (link(ctlfile.c_str(), qname.c_str()))
			{
				mkdir(qmsgqdir(current_time),0755);
				if (link(ctlfile.c_str(), qname.c_str())
				    && errno != EEXIST)
					clog_msg_errno();
			}

			if (rename(datfile.c_str(), newdatfile.c_str()))
			{
				mkdir(qmsgsdir(inum), 0755);
					// We may need to create this dir
				rename(datfile.c_str(), newdatfile.c_str());
			}

			if (rename(ctlfile.c_str(), newctlfile.c_str()))
				clog_msg_errno();

			for (i=qname.size(); i; )
			{
				if (qname[--i] == '/')
					break;
			}

			qdir=qname.substr(0, i);
			qname=qname.substr(i+1);
			++found;
			ctlfile_close(&ctf);

			queuescan3(qdir, qname, de->d_name);
		}
		closedir(subde);

		if (stat(subdir.c_str(), &stat_buf) == 0 &&
			stat_buf.st_mtime < current_time - 2 * 60 * 60)
			rmdir(subdir.c_str());	// Just give it a try
	}
	closedir(tmpdir);
	return (found);
}
Beispiel #4
0
int gpgdecode(int in_fd, int out_fd)
{
	char passfd_buf[NUMBUFSIZE];
	FILE *fp=passphrasefp();
	int in_dup, out_dup;
	FILE *in_fp, *out_fp;
	struct libmail_gpg_info gi;
	char *argvec[2];
	int i;

	gpginiterr();

	if ((in_dup=dup(in_fd)) < 0 || (in_fp=fdopen(in_dup, "r")) == NULL)
	{
		if (in_dup >= 0)
			close(in_dup);
		fclose(fp);
		enomem();
		return 1;
	}

	if ((out_dup=dup(out_fd)) < 0 || (out_fp=fdopen(out_dup, "w")) == NULL)
	{
		if (out_dup >= 0)
			close(out_dup);
		fclose(in_fp);
		close(in_dup);
		fclose(fp);
		enomem();
		return 1;
	}

	memset(&gi, 0, sizeof(gi));

	gi.gnupghome=GPGDIR;
	if (fp)
	{
		gi.passphrase_fd=libmail_str_size_t(fileno(fp), passfd_buf);
	}

	gi.input_func= read_fd;
	gi.input_func_arg= in_fp;
	gi.output_func= write_fd;
	gi.output_func_arg= out_fp;
	gi.errhandler_func= gpg_error_save;
	gi.errhandler_arg= NULL;

	argvec[0] = "--no-tty";
	argvec[1]=NULL;
	gi.argc=1;
	gi.argv=argvec;

	i=libmail_gpg_decode(LIBMAIL_GPG_UNENCRYPT|LIBMAIL_GPG_CHECKSIGN,
			     &gi);
	fclose(out_fp);
	close(out_dup);
	fclose(in_fp);
	close(in_dup);
	if (fp)
		fclose(fp);

	if (i)
	{
		printf("<div class=\"indent\"><pre style=\"color: red;\">");
		sent_gpgerrtxt();
		printf("</pre></div>\n");
	}
	return (i);
}
Beispiel #5
0
int gpgdomsg(int in_fd, int out_fd, const char *signkey,
	     const char *encryptkeys)
{
	char *k=strdup(encryptkeys ? encryptkeys:"");
	int n;
	int i;
	char *p;
	char **argvec;
	FILE *passfd=NULL;
	char passfd_buf[NUMBUFSIZE];
	struct libmail_gpg_info gi;

	int in_dup, out_dup;
	FILE *in_fp, *out_fp;

	gpginiterr();

	if (!k)
	{
		enomem();
		return 1;
	}

	if ((in_dup=dup(in_fd)) < 0 || (in_fp=fdopen(in_dup, "r")) == NULL)
	{
		if (in_dup >= 0)
			close(in_dup);
		free(k);
		enomem();
		return 1;
	}

	if ((out_dup=dup(out_fd)) < 0 || (out_fp=fdopen(out_dup, "w")) == NULL)
	{
		if (out_dup >= 0)
			close(out_dup);
		fclose(in_fp);
		close(in_dup);
		free(k);
		enomem();
		return 1;
	}

	passfd=passphrasefp();

	n=0;
	for (p=k; (p=strtok(p, " ")) != NULL; p=NULL)
		++n;

	argvec=malloc((n * 2 + 22)*sizeof(char *));
	if (!argvec)
	{
		fclose(out_fp);
		close(out_dup);
		fclose(in_fp);
		close(in_dup);
		free(k);
		enomem();
		return 1;
	}

	memset(&gi, 0, sizeof(gi));

	gi.gnupghome=GPGDIR;
	if (passfd)
	{
		gi.passphrase_fd=libmail_str_size_t(fileno(passfd),
						    passfd_buf);
	}

	gi.input_func= read_fd;
	gi.input_func_arg= in_fp;
	gi.output_func= write_fd;
	gi.output_func_arg= out_fp;
	gi.errhandler_func= gpg_error_save;
	gi.errhandler_arg= NULL;


	i=0;
	argvec[i++] = "--no-tty";
	if (signkey)
	{
		argvec[i++]="--default-key";
		argvec[i++]=(char *)signkey;
	}

	argvec[i++]="--always-trust";

	for (p=strcpy(k, encryptkeys ? encryptkeys:"");
	     (p=strtok(p, " ")) != NULL; p=NULL)
	{
		argvec[i++]="-r";
		argvec[i++]=p;
	}
	argvec[i]=0;
	gi.argc=i;
	gi.argv=argvec;

	i=libmail_gpg_signencode(signkey ? 1:0,
				 n > 0 ? LIBMAIL_GPG_ENCAPSULATE:0,
				 &gi);

	free(argvec);
	fclose(out_fp);
	close(out_dup);
	fclose(in_fp);
	close(in_dup);
	free(k);
	if (passfd)
		fclose(passfd);

	return i;
}
Beispiel #6
0
Datei: gpg.c Projekt: zixia/wmail
int gpgdecode(int in_fd, int out_fd)
{
	pid_t pid;
	int stderrfd[2];
	int rc;

	if (pipe(stderrfd))
	{
		enomem();
	}

	pid=fork();
	if (pid < 0)
	{
		close(stderrfd[0]);
		close(stderrfd[1]);
		enomem();
	}

	if (pid == 0)
	{
		FILE *fp=passphrasefp();
		char *argvec[20];
		int i;
		char passfd_buf[NUMBUFSIZE];

		close(0);
		dup(in_fd);
		close(1);
		dup(out_fd);
		close(in_fd);
		close(out_fd);

		close(2);
		dup(stderrfd[1]);
		close(stderrfd[1]);
		close(stderrfd[0]);

		argvec[0]=MIMEGPG;
		argvec[1]="-c";
		argvec[2]="-d";

		i=3;

		if (fp)
		{
			argvec[i++]="-p";
			argvec[i++]=libmail_str_size_t(fileno(fp), passfd_buf);
		}

		argvec[i++]="--";
		argvec[i++]="--no-tty";
		argvec[i]=0;

		putenv("GNUPGHOME=" GPGDIR);
		execv(MIMEGPG, argvec);
		perror(MIMEGPG);
		exit(1);
	}
	close (stderrfd[1]);
	rc=wait_mimegpg(pid, stderrfd[0]);

	if (rc)
	{
		printf("<blockquote><pre style=\"color: red;\">");
		sent_gpgerrtxt();
		printf("</pre></blockquote>\n");
	}
	return (rc);
}
Beispiel #7
0
Datei: gpg.c Projekt: zixia/wmail
int gpgdomsg(int in_fd, int out_fd, const char *signkey,
	     const char *encryptkeys)
{
	char *k=strdup(encryptkeys ? encryptkeys:"");
	int n;
	int i;
	char *p;
	char **argvec;
	pid_t pid;
	int stderrfd[2];
	FILE *passfd=NULL;
	const char *cp;
	char passfd_buf[NUMBUFSIZE];

	if (!k)
		enomem();

	if (pipe(stderrfd))
	{
		free(k);
		enomem();
	}

	if (*(cp=cgi("passphrase")) != 0)
	{
		passfd=tmpfile();
		if (passfd)
		{
			fprintf(passfd, "%s", cp);
			if (fflush(passfd) || ferror(passfd)
			    || lseek(fileno(passfd), 0L, SEEK_SET) < 0
			    || fcntl(fileno(passfd), F_SETFD, 0) < 0)
			{
				fclose(passfd);
				passfd=NULL;
			}
		}
	}

	n=0;
	for (p=k; (p=strtok(p, " ")) != NULL; p=NULL)
		++n;

	argvec=malloc((n * 2 + 22)*sizeof(char *));
	if (!argvec)
	{
		close(stderrfd[0]);
		close(stderrfd[1]);
		free(k);
		enomem();
	}

	i=0;
	argvec[i++]=MIMEGPG;
	if (signkey)
		argvec[i++]="-s";
	if (n > 0)
		argvec[i++]="-E";
	if (passfd)
	{
		argvec[i++]="-p";
		argvec[i++]=libmail_str_size_t(fileno(passfd), passfd_buf);
	}

	argvec[i++] = "--";
	argvec[i++] = "--no-tty";
	if (signkey)
	{
		argvec[i++]="--default-key";
		argvec[i++]=(char *)signkey;
	}

	argvec[i++]="--always-trust";

	for (p=strcpy(k, encryptkeys ? encryptkeys:"");
	     (p=strtok(p, " ")) != NULL; p=NULL)
	{
		argvec[i++]="-r";
		argvec[i++]=p;
	}
	argvec[i]=0;

	pid=fork();
	if (pid < 0)
	{
		free(k);
		close(stderrfd[0]);
		close(stderrfd[1]);
		return (-1);
	}

	if (pid == 0)
	{
		close(0);
		dup(in_fd);
		close(1);
		dup(out_fd);
		close(in_fd);
		close(out_fd);

		close(2);
		dup(stderrfd[1]);
		close(stderrfd[1]);
		close(stderrfd[0]);

		putenv("GNUPGHOME=" GPGDIR);
		execv(argvec[0], argvec);
		perror("mimegpg");
		exit(1);
	}
	free(argvec);
	free(k);
	close(stderrfd[1]);
	if (passfd)
		fclose(passfd);

	return ( wait_mimegpg(pid, stderrfd[0]));
}