Bug#285371: Still a problem.
Andreas Metzler
Andreas Metzler <ametzler@downhill.at.eu.org>, 285371@bugs.debian.org
Sun, 19 Dec 2004 15:35:36 +0100
--tKW2IUtsqtDRztdT
Content-Type: text/plain; charset=us-ascii
Content-Disposition: inline
On 2004-12-14 Andreas Metzler <ametzler@downhill.at.eu.org> wrote:
> On 2004-12-14 "Yazz D. Atlas" <yazz@230volts.net> wrote:
> [...]
> > Is there a way to generate this by hand? If I could just generate it
> > correctly then I could have it run when /etc/cron.daily/exim4-base is
> > called.
> [...]
> You can try to use the attached file to generate gnutls-params-new and
> mv it it to gnutls-params instead removing gnutls-params, however as
> it does exactly the same thing as exim4 I doubt you'll favour better.
Have you tried this? If not can you check how long the attached
version takes?
gcc -Wall -o exim_gnutls-params -O2 -g exim_gnutls-params.c -lgnutls
time ./exim_gnutls-params -v --indefinitely /var/spool/exim4
What does
sysctl -n kernel/random/entropy_avail
say on your system?
cu andreas
--
"See, I told you they'd listen to Reason," [SPOILER] Svfurlr fnlf,
fuhggvat qbja gur juveyvat tha.
Neal Stephenson in "Snow Crash"
http://downhill.aus.cc/
--tKW2IUtsqtDRztdT
Content-Type: text/x-csrc; charset=us-ascii
Content-Disposition: attachment; filename="exim_gnutls-params.c"
/*#include "exim.h"*/
/* Heading stuff for GnuTLS */
#include <gnutls/gnutls.h>
#include <gnutls/x509.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>
#include <stdlib.h>
#include <signal.h>
#include <syslog.h>
/* #include "mytypes.h" */
/* extracted from mytypes.h *
*/
typedef int BOOL;
typedef unsigned char uschar;
#define FALSE 0
#define TRUE 1
#define US (unsigned char *)
#define CS (char *)
#define CCS (const char *)
#define Ustrcmp(s,t) strcmp(CCS(s),CCS(t))
#ifdef O_BINARY /* This is for Cygwin, */
#define Uopen(s,n,m) open(CCS(s),(n)|O_BINARY,m) /* where all files must */
#else /* be opened as binary */
#define Uopen(s,n,m) open(CCS(s),n,m) /* to avoid problems */
#endif /* with CRLF endings. */
/*
extracted from mytypes.h */
#define UNKNOWN_NAME "unknown"
#define DH_BITS 768
#define RSA_BITS 512
/*************************************************
* Handle TLS error *
*************************************************/
/*
Argument:
prefix text to include in the logged error
err a GnuTLS error number, or 0 if local error
Returns: OK/DEFER/FAIL
*/
int gnutls_timeout=3;
static int
gnutls_error(uschar *prefix, int err)
{
if (err==0)
fprintf(stderr,"%s",prefix);
else
fprintf(stderr,"%s %s",prefix,gnutls_strerror(err));
return 1;
}
/*************************************************
* Write/read datum to/from file *
*************************************************/
/* These functions are used for saving and restoring the RSA and D-H parameters
for use by all Exim processes. Data that is read is placed in malloc'd store
because that's what happens for newly generated data.
Arguments:
fd the file descriptor
d points to the datum
returns: FALSE on error (errno set)
*/
static BOOL
write_datum(int fd, gnutls_datum *d)
{
if (write(fd, &(d->size), sizeof(d->size)) != sizeof(d->size)) return FALSE;
if (write(fd, d->data, d->size) != d->size) return FALSE;
return TRUE;
}
void tooktolong()
{
fprintf(stderr, "Timeout occured after %d seconds\n",gnutls_timeout);
syslog(LOG_ERR | LOG_MAIL, "Timeout occured after %d seconds\n",gnutls_timeout);
exit(1);
}
/*************************************************
* Setup up RSA and DH parameters *
*************************************************/
/* Generating the RSA and D-H parameters takes a long time. They only need to
be re-generated every so often, depending on security policy. What we do is to
keep these parameters in a file in the spool directory. If the file does not
exist, we generate them. This means that it is easy to cause a regeneration.
*/
int
main(int argc, char **argv)
{
int fd, ret, verbose=FALSE;
gnutls_datum m, e, d, p, q, u, prime, generator;
uschar filename[200]="";
#define GNUTLSPARAMFILE "/gnutls-params"
struct stat statbuf;
unsigned int rsa_bits = RSA_BITS;
unsigned int dh_bits = DH_BITS;
gnutls_rsa_params rsa_params = NULL;
gnutls_dh_params dh_params = NULL;
uschar tempfilename[sizeof(filename) + 10];
if (0==geteuid()||0==getegid()) {
fprintf(stderr,"Please run as exim user and exim group.\n");
return 1;
/*
setgid(exim_gid);
setuid(exim_uid);
if (verbose) printf("Dropped privileges\n");
*/
}
signal(SIGALRM,tooktolong);
while (argc > 1)
{
if (Ustrcmp(argv[1], "-v") == 0) verbose=TRUE;
else if (Ustrcmp(argv[1], "--indefinitely")== 0) gnutls_timeout=0;
else break;
argv++;
argc--;
}
if (argc!=2) {
printf("Usage: %s [-v] [--indefinitely] spooldir\n",argv[0]);
return 1;
}
/* Set up the name of the cache file */
if (strlen(argv[1])+strlen(GNUTLSPARAMFILE)>=200)
return gnutls_error(US"overlong filename", 0);
strcat(filename,argv[1]);
strcat(filename,GNUTLSPARAMFILE);
/* exit if cache file exist
if (0==(stat(CS filename,&statbuf))) {
if (verbose) printf("File [%s] exists, exiting.\n",filename);
return 0;
}
*/
ret=gnutls_global_init();
if (ret < 0) return gnutls_error(US"tls-init", ret);
/* Initialize the data structures for holding the parameters */
ret = gnutls_rsa_params_init(&rsa_params);
if (ret < 0) return gnutls_error(US"init rsa_params", ret);
ret = gnutls_dh_params_init(&dh_params);
if (ret < 0) return gnutls_error(US"init dh_params", ret);
if (verbose) printf("generating %d bit RSA key...\n", RSA_BITS);
alarm(gnutls_timeout);
ret = gnutls_rsa_params_generate2(rsa_params, RSA_BITS);
alarm(0);
if (ret < 0) return gnutls_error(US"RSA key generation", ret);
if (verbose) printf("generating %d bit Diffie-Hellman key...\n",
DH_BITS);
alarm(gnutls_timeout);
ret = gnutls_dh_params_generate2(dh_params, DH_BITS);
alarm(0);
if (ret < 0) return gnutls_error(US"D-H key generation", ret);
/* Write the parameters to a file in the spool directory so that we
can use them from other Exim processes. */
sprintf(CS tempfilename, "%s-%d", filename, (int)getpid());
fd = Uopen(tempfilename, O_WRONLY|O_CREAT, 0400);
if (fd < 0){
fprintf(stderr, "Failed to open %s for writing, error %s\n",
tempfilename,strerror(errno));
return 1;
}
ret = gnutls_rsa_params_export_raw(rsa_params, &m, &e, &d, &p, &q, &u,
&rsa_bits);
if (ret < 0) return gnutls_error(US"RSA params export", ret);
ret = gnutls_dh_params_export_raw(dh_params, &prime, &generator, &dh_bits);
if (ret < 0) return gnutls_error(US"DH params export", ret);
if (!write_datum(fd, &m) ||
!write_datum(fd, &e) ||
!write_datum(fd, &d) ||
!write_datum(fd, &p) ||
!write_datum(fd, &q) ||
!write_datum(fd, &u) ||
!write_datum(fd, &prime) ||
!write_datum(fd, &generator))
return gnutls_error(US"TLS cache write failed", 0);
(void)close(fd);
if (rename(CS tempfilename, CS filename) < 0)
fprintf(stderr, "failed to rename %s as %s: %s\n",
tempfilename, filename, strerror(errno));
if (verbose) printf("wrote RSA and D-H parameters to file %s\n",filename);
return 0;
}
/*
* vim:tabstop=2:expandtab:shiftwidth=2
*/
--tKW2IUtsqtDRztdT--