View | Details | Raw Unified | Return to bug 1025068
Collapse All | Expand All

(-)libICE-1.0.9/configure.ac (-1 / +1 lines)
Lines 38-44 AC_DEFINE(ICE_t, 1, [Xtrans transport ty Link Here
38
38
39
# Checks for library functions.
39
# Checks for library functions.
40
AC_CHECK_LIB([bsd], [arc4random_buf])
40
AC_CHECK_LIB([bsd], [arc4random_buf])
41
AC_CHECK_FUNCS([asprintf arc4random_buf])
41
AC_CHECK_FUNCS([asprintf arc4random_buf getentropy])
42
42
43
# Allow checking code with lint, sparse, etc.
43
# Allow checking code with lint, sparse, etc.
44
XORG_WITH_LINT
44
XORG_WITH_LINT
(-)libICE-1.0.9/src/iceauth.c (-18 / +165 lines)
Lines 42-72 Author: Ralph Mor, X Consortium Link Here
42
42
43
static int was_called_state;
43
static int was_called_state;
44
44
45
/*
45
#ifndef HAVE_ARC4RANDOM_BUF
46
 * MIT-MAGIC-COOKIE-1 is a sample authentication method implemented by
47
 * the SI.  It is not part of standard ICElib.
48
 */
49
46
50
47
static void
51
char *
48
emulate_getrandom_buf (
52
IceGenerateMagicCookie (
49
	char *auth,
53
	int len
50
	int len
54
)
51
)
55
{
52
{
56
    char    *auth;
57
#ifndef HAVE_ARC4RANDOM_BUF
58
    long    ldata[2];
53
    long    ldata[2];
59
    int	    seed;
54
    int	    seed;
60
    int	    value;
55
    int	    value;
61
    int	    i;
56
    int	    i;
62
#endif
63
64
    if ((auth = malloc (len + 1)) == NULL)
65
	return (NULL);
66
57
67
#ifdef HAVE_ARC4RANDOM_BUF
68
    arc4random_buf(auth, len);
69
#else
70
#ifdef ITIMER_REAL
58
#ifdef ITIMER_REAL
71
    {
59
    {
72
	struct timeval  now;
60
	struct timeval  now;
Lines 74-86 IceGenerateMagicCookie ( Link Here
74
	ldata[0] = now.tv_sec;
62
	ldata[0] = now.tv_sec;
75
	ldata[1] = now.tv_usec;
63
	ldata[1] = now.tv_usec;
76
    }
64
    }
77
#else
65
#else /* ITIMER_REAL */
78
    {
66
    {
79
	long    time ();
67
	long    time ();
80
	ldata[0] = time ((long *) 0);
68
	ldata[0] = time ((long *) 0);
81
	ldata[1] = getpid ();
69
	ldata[1] = getpid ();
82
    }
70
    }
83
#endif
71
#endif /* ITIMER_REAL */
84
    seed = (ldata[0]) + (ldata[1] << 16);
72
    seed = (ldata[0]) + (ldata[1] << 16);
85
    srand (seed);
73
    srand (seed);
86
    for (i = 0; i < len; i++)
74
    for (i = 0; i < len; i++)
Lines 88-94 IceGenerateMagicCookie ( Link Here
88
	value = rand ();
76
	value = rand ();
89
	auth[i] = value & 0xff;
77
	auth[i] = value & 0xff;
90
    }
78
    }
79
}
80
81
#ifndef _GNU_SOURCE
82
#define _GNU_SOURCE // needed on SLE11 for O_CLOEXEC
91
#endif
83
#endif
84
#include <sys/types.h>
85
#include <sys/stat.h>
86
#include <fcntl.h>
87
#include <errno.h>
88
#include <linux/random.h>
89
#include <sys/syscall.h>
90
91
int getentropy_urandom(void *buffer, size_t length)
92
{
93
	int random_fd = -1;
94
	ssize_t res = -1;
95
	size_t filled = 0;
96
97
	if( length > 256 )
98
	{
99
		errno = EIO;
100
		return -1;
101
	}
102
103
	random_fd = open("/dev/urandom", O_RDONLY | O_CLOEXEC);
104
105
	if( random_fd == -1 )
106
	{
107
		return -1;
108
	}
109
110
	while( filled < length )
111
	{
112
		res = read(random_fd, (char*)buffer + filled, length - filled);
113
114
		if( res == -1 )
115
		{
116
			// shouldn't actually happen acc. to man(4) random,
117
			// but you never know
118
			if( errno == EINTR )
119
				continue;
120
121
			return -1;
122
		}
123
		else if( res == 0 )
124
		{
125
			// no more bytes available? should not happen
126
			errno = EIO;
127
			return -1;
128
		}
129
130
		filled += res;
131
	}
132
133
	return 0;
134
}
135
136
int getentropy_getrandom(void *buffer, size_t length)
137
{
138
	int res;
139
	size_t filled = 0;
140
141
	if( length > 256 )
142
	{
143
		errno = EIO;
144
		return -1;
145
	}
146
147
	while( filled < length )
148
	{
149
#ifdef SYS_getrandom
150
		/*
151
		 * glibc does not contain a syscall wrapper for this in older
152
		 * versions
153
		 */
154
		res = syscall(SYS_getrandom, (char*)buffer + filled, length - filled, 0);
155
#else
156
#	warning no getrandom
157
		errno = ENOSYS;
158
		return -1;
159
#endif // SYS_getrandom
160
161
		if( res == -1 )
162
		{
163
			if( errno == EINTR )
164
				continue;
165
166
			return -1;
167
		}
168
		else if( res == 0 )
169
		{
170
			// no more bytes available? should not happen
171
			errno = EIO;
172
			return -1;
173
		}
174
175
		filled += res;
176
	}
177
178
	return 0;
179
}
180
181
int getentropy_emulate(void *buffer, size_t length)
182
{
183
	/*
184
	 * check at runtime whether we have a getrandom system call available,
185
	 * otherwise fall back to urandom approach. autoconf check for
186
	 * getrandom() does not work, because there's been no declaration for
187
	 * it for years.
188
	 */
189
	int res = getentropy_getrandom(buffer, length);
190
191
	if( res == -1 && errno == ENOSYS )
192
	{
193
		return getentropy_urandom(buffer, length);
194
	}
195
196
	return res;
197
}
198
199
static void
200
arc4random_buf (
201
	char *auth,
202
	int len
203
)
204
{
205
    int	    ret;
206
207
#if HAVE_GETENTROPY
208
    /* weak emulation of arc4random through the entropy libc */
209
    ret = getentropy (auth, len);
210
#else
211
    ret = getentropy_emulate (auth, len);
212
#endif /* HAVE_GETENTROPY */
213
    if (ret == 0)
214
	return;
215
216
    emulate_getrandom_buf (auth, len);
217
}
218
219
#endif /* !defined(HAVE_ARC4RANDOM_BUF) */
220
221
/*
222
 * MIT-MAGIC-COOKIE-1 is a sample authentication method implemented by
223
 * the SI.  It is not part of standard ICElib.
224
 */
225
226
227
char *
228
IceGenerateMagicCookie (
229
	int len
230
)
231
{
232
    char    *auth;
233
234
    if ((auth = malloc (len + 1)) == NULL)
235
	return (NULL);
236
237
    arc4random_buf (auth, len);
238
92
    auth[len] = '\0';
239
    auth[len] = '\0';
93
    return (auth);
240
    return (auth);
94
}
241
}

Return to bug 1025068