extern unsigned char QuadOptions[];
#endif
-WHERE unsigned short Counter INITVAL (0);
-
WHERE short ConnectTimeout;
WHERE short HistSize;
WHERE short MenuContext;
return 0;
}
-static void mutt_srandom (void)
-{
- struct timeval tv;
- unsigned seed;
-
- gettimeofday(&tv, NULL);
- /* POSIX.1-2008 states that seed is 'unsigned' without specifying its width.
- * Use as many of the lower order bits from the current time of day as the seed.
- * If the upper bound is truncated, that is fine.
- *
- * tv_sec is integral of type integer or float. Cast to 'long long' before
- * bitshift in case it is a float.
- */
- seed = ((LONGLONG) tv.tv_sec << 20) | tv.tv_usec;
- srandom(seed);
-}
-
void mutt_init (int skip_sys_rc, LIST *commands)
{
struct passwd *pw;
ReverseAlias = hash_create (1031, 1);
mutt_menu_init ();
- mutt_srandom ();
- /*
- * XXX - use something even more difficult to predict?
- */
snprintf (AttachmentMarker, sizeof (AttachmentMarker),
- "\033]9;%ld\a", (long) time (NULL));
+ "\033]9;%" PRIu64 "\a", mutt_rand64());
/* on one of the systems I use, getcwd() does not return the same prefix
as is listed in the passwd file */
mutt_error = mutt_nocurses_error;
mutt_message = mutt_nocurses_error;
- SRAND (time (NULL));
+ (void)mutt_rand32();
umask (077);
memset (Options, 0, sizeof (Options));
omask = umask (mh_umask (dest));
FOREVER
{
- snprintf (path, _POSIX_PATH_MAX, "%s/.mutt-%s-%d-%d",
- dest->path, NONULL (Hostname), (int) getpid (), Counter++);
+ snprintf (path, _POSIX_PATH_MAX, "%s/.mutt-%s-%d-%" PRIu64,
+ dest->path, NONULL (Hostname), (int) getpid (), mutt_rand64());
if ((fd = open (path, O_WRONLY | O_EXCL | O_CREAT, 0666)) == -1)
{
if (errno != EEXIST)
omask = umask (mh_umask (dest));
FOREVER
{
- snprintf (path, _POSIX_PATH_MAX, "%s/tmp/%s.%lld.%u_%d.%s%s",
- dest->path, subdir, (long long)time (NULL), (unsigned int)getpid (),
- Counter++, NONULL (Hostname), suffix);
+ snprintf (path, _POSIX_PATH_MAX, "%s/tmp/%s.%lld.R%" PRIu64 ".%s%s",
+ dest->path, subdir, (long long)time (NULL), mutt_rand64(),
+ NONULL (Hostname), suffix);
dprint (2, (debugfile, "maildir_open_new_message (): Trying %s.\n",
path));
/* construct a new file name. */
FOREVER
{
- snprintf (path, _POSIX_PATH_MAX, "%s/%lld.%u_%d.%s%s", subdir,
- (long long)time (NULL), (unsigned int)getpid (), Counter++,
+ snprintf (path, _POSIX_PATH_MAX, "%s/%lld.R%" PRIu64 ".%s%s", subdir,
+ (long long)time (NULL), mutt_rand64(),
NONULL (Hostname), suffix);
snprintf (full, _POSIX_PATH_MAX, "%s/%s", ctx->path, path);
#include <string.h>
#include <ctype.h>
#include <unistd.h>
+#include <sys/syscall.h>
#include <stdlib.h>
#include <sys/wait.h>
#include <errno.h>
mutt_free_envelope(extra);
}
+static FILE *frandom;
+
+void mutt_randbuf(void *out, size_t len)
+{
+ if (len > 1048576) {
+ mutt_error (_("mutt_randbuf len=%zu"), len);
+ exit(1);
+ }
+ /* XXX switch to HAVE_GETRANDOM and getrandom() in about 2017 */
+#if defined(SYS_getrandom) && defined(__linux__)
+ static int whined;
+ long ret;
+ do {
+ ret = syscall(SYS_getrandom, out, len, 0, 0, 0, 0);
+ } while ((ret == -1) && (errno == EINTR));
+ if (ret == len) return;
+ if (!whined) {
+ mutt_error (_("getrandom failed: %s"), strerror(errno));
+ mutt_sleep (1);
+ whined = 1;
+ }
+ /* let's try urandom in case user has configured selinux or something
+ * to not allow getrandom */
+#endif
+ if (frandom == NULL) {
+ frandom = fopen("/dev/urandom", "rb");
+ if (frandom == NULL) {
+ mutt_error (_("open /dev/urandom: %s"), strerror(errno));
+ exit(1);
+ }
+ setbuf(frandom, NULL);
+ }
+ if (fread(out, 1, len, frandom) != len) {
+ mutt_error (_("read /dev/urandom: %s"), strerror(errno));
+ exit(1);
+ }
+}
+
+static const unsigned char base32[] = "abcdefghijklmnopqrstuvwxyz234567";
+
+void mutt_rand_base32(void *out, size_t len)
+{
+ size_t pos;
+ uint8_t *p = out;
+
+ mutt_randbuf(p, len);
+ for (pos = 0; pos < len; pos++)
+ p[pos] = base32[p[pos] % 32];
+}
+
+uint32_t mutt_rand32(void)
+{
+ uint32_t ret;
+
+ mutt_randbuf(&ret, sizeof(ret));
+ return ret;
+}
+
+uint64_t mutt_rand64(void)
+{
+ uint64_t ret;
+
+ mutt_randbuf(&ret, sizeof(ret));
+ return ret;
+}
+
+
void _mutt_mktemp (char *s, size_t slen, const char *prefix, const char *suffix,
const char *src, int line)
{
- size_t n = snprintf (s, slen, "%s/%s-%s-%d-%d-%ld%ld%s%s",
+ size_t n = snprintf (s, slen, "%s/%s-%s-%d-%d-%" PRIu64 "%s%s",
NONULL (Tempdir), NONULL (prefix), NONULL (Hostname),
- (int) getuid (), (int) getpid (), random (), random (),
+ (int) getuid (), (int) getpid (), mutt_rand64(),
suffix ? "." : "", NONULL (suffix));
if (n >= slen)
dprint (1, (debugfile, "%s:%d: ERROR: insufficient buffer space to hold temporary filename! slen=%zu but need %zu\n",
void mutt_set_header_color(CONTEXT *, HEADER *);
void mutt_sleep (short);
int mutt_save_confirm (const char *, struct stat *);
+void mutt_randbuf(void *out, size_t len);
+#define MUTT_RANDTAG_LEN (16)
+void mutt_rand_base32(void *out, size_t len);
+uint32_t mutt_rand32(void);
+uint64_t mutt_rand64(void);
int mh_valid_message (const char *);
#define LONGLONG long
#endif
-#ifdef HAVE_SRAND48
-#define LRAND lrand48
-#define SRAND srand48
-#define DRAND drand48
-#else
-#define LRAND rand
-#define SRAND srand
-#define DRAND (double)rand
-#endif /* HAVE_SRAND48 */
-
/* HP-UX, ConvexOS and UNIXware don't have this macro */
#ifndef S_ISLNK
#define S_ISLNK(x) (((x) & S_IFMT) == S_IFLNK ? 1 : 0)
'8', '9', '+', '/'
};
-static char MsgIdPfx = 'A';
-
static void transform_to_7bit (BODY *a, FILE *fpin);
static void encode_quoted (FGETCONV * fc, FILE *fout, int istext)
#undef write_as_text_part
-#define BOUNDARYLEN 16
void mutt_generate_boundary (PARAMETER **parm)
{
- char rs[BOUNDARYLEN + 1];
- char *p = rs;
- int i;
-
- rs[BOUNDARYLEN] = 0;
- for (i=0;i<BOUNDARYLEN;i++)
- *p++ = B64Chars[LRAND() % sizeof (B64Chars)];
- *p = 0;
+ char rs[MUTT_RANDTAG_LEN + 1];
+ mutt_rand_base32(rs, sizeof(rs) - 1);
+ rs[MUTT_RANDTAG_LEN] = 0;
mutt_set_parameter ("boundary", rs, parm);
}
time_t now;
struct tm *tm;
const char *fqdn;
+ unsigned char rndid[MUTT_RANDTAG_LEN + 1];
+ mutt_rand_base32(rndid, sizeof(rndid) - 1);
+ rndid[MUTT_RANDTAG_LEN] = 0;
now = time (NULL);
tm = gmtime (&now);
if(!(fqdn = mutt_fqdn(0)))
fqdn = NONULL(Hostname);
- snprintf (buf, sizeof (buf), "<%d%02d%02d%02d%02d%02d.G%c%u@%s>",
+ snprintf (buf, sizeof (buf), "<%d%02d%02d%02d%02d%02d.%s@%s>",
tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday, tm->tm_hour,
- tm->tm_min, tm->tm_sec, MsgIdPfx, (unsigned int)getpid (), fqdn);
- MsgIdPfx = (MsgIdPfx == 'Z') ? 'A' : MsgIdPfx + 1;
+ tm->tm_min, tm->tm_sec, rndid, fqdn);
return (safe_strdup (buf));
}