OpenVAS Scanner  7.0.0~git
genrand.c
Go to the documentation of this file.
1 /* Portions Copyright (C) 2009-2019 Greenbone Networks GmbH
2  * Based on work Copyright (C) Jeremy Allison 2001
3  *
4  * SPDX-License-Identifier: GPL-2.0-or-later
5  *
6  * This program is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU General Public License
8  * as published by the Free Software Foundation; either version 2
9  * of the License, or (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
19  */
20 
27 /*
28  Modified for OpenVAS by Preeti Subramanian <spreeti@secpod.com>
29  MODIFICATION: This file has only those functions that cater to the
30  requirements of OpenVAS, remaining functions are removed
31  * BOOL is changed to bool
32  * sys_open is changed to open
33  * sys_getpid is changed to getpid
34  * In do_reseed function, adding secret file contents of smb
35  passwd file not required(removed) and add in the root
36  encrypted password note required(removed)
37 */
38 #include "byteorder.h"
39 #include "md4.h"
40 #include "proto.h"
41 #include "smb.h"
42 
43 #include <pwd.h>
44 #include <time.h>
45 #include <unistd.h>
46 #ifndef HAVE_UCBINCLUDE
47 #include <fcntl.h>
48 #else
49 /* Solaris */
50 #include "/usr/ucbinclude/fcntl.h"
51 #endif
52 
53 #ifndef uint32
54 #define uint32 uint32_t
55 #endif
56 
57 typedef unsigned int bool;
58 #define False 0
59 #define True 1
60 
61 static unsigned char smb_arc4_state[258];
62 static uint32 counter;
63 
69 /* zero a structure */
70 #define ZERO_STRUCT(x) memset ((char *) &(x), 0, sizeof (x))
71 
72 static bool done_reseed_ntlmssp = False;
73 static void (*reseed_callback_ntlmssp) (int *newseed);
74 
75 /****************************************************************
76  Copy any user given reseed data.
77 *****************************************************************/
78 
79 static void
80 get_rand_reseed_data_ntlmssp (int *reseed_data)
81 {
83  {
84  reseed_callback_ntlmssp (reseed_data);
85  }
86  else
87  {
88  *reseed_data = 0;
89  }
90 }
91 
92 /****************************************************************
93  Get a 16 byte hash from the contents of a file.
94  Note that the hash is not initialised.
95 *****************************************************************/
96 
97 static void
98 do_filehash_ntlmssp (const char *fname, unsigned char *the_hash)
99 {
100  unsigned char buf[1011]; /* deliberate weird size */
101  unsigned char tmp_md4[16];
102  int fd, n;
103 
104  fd = open (fname, O_RDONLY, 0);
105  if (fd == -1)
106  return;
107 
108  while ((n = read (fd, (char *) buf, sizeof (buf))) > 0)
109  {
110  mdfour_ntlmssp (tmp_md4, buf, n);
111  for (n = 0; n < 16; n++)
112  the_hash[n] ^= tmp_md4[n];
113  }
114  close (fd);
115 }
116 
117 /**************************************************************
118  Try and get a good random number seed. Try a number of
119  different factors. Firstly, try /dev/urandom - use if exists.
120 
121  We use /dev/urandom as a read of /dev/random can block if
122  the entropy pool dries up. This leads clients to timeout
123  or be very slow on connect.
124 
125  If we can't use /dev/urandom then seed the stream random generator
126  above...
127 **************************************************************/
128 
129 static int
130 do_reseed_ntlmssp (bool use_fd, int fd)
131 {
132  unsigned char seed_inbuf[40];
133  uint32 v1, v2;
134  struct timeval tval;
135  pid_t mypid;
136  int reseed_data = 0;
137 
138  if (use_fd)
139  {
140  if (fd != -1)
141  return fd;
142  fd = open ("/dev/urandom", O_RDONLY, 0);
143  if (fd >= 0)
144  return fd;
145  }
146 
147  /* Add in some secret file contents */
148  memset (seed_inbuf, '\0', sizeof (seed_inbuf));
149  do_filehash_ntlmssp ("/etc/shadow", &seed_inbuf[0]);
150  /*
151  * Add the counter, time of day, and pid.
152  */
153 
154  GetTimeOfDay_ntlmssp (&tval);
155  mypid = getpid ();
156  v1 = (counter++) + mypid + tval.tv_sec;
157  v2 = (counter++) * mypid + tval.tv_usec;
158 
159  SIVAL (seed_inbuf, 32, v1 ^ IVAL (seed_inbuf, 32));
160  SIVAL (seed_inbuf, 36, v2 ^ IVAL (seed_inbuf, 36));
161 
162  /*
163  * Add any user-given reseed data.
164  */
165 
166  get_rand_reseed_data_ntlmssp (&reseed_data);
167  if (reseed_data)
168  {
169  size_t i;
170  for (i = 0; i < sizeof (seed_inbuf); i++)
171  seed_inbuf[i] ^= ((char *) (&reseed_data))[i % sizeof (reseed_data)];
172  }
173 
174  smb_arc4_init_ntlmssp (smb_arc4_state, seed_inbuf, sizeof (seed_inbuf));
175 
176  return -1;
177 }
178 
179 /*******************************************************************
180  Interface to the (hopefully) good crypto random number generator.
181 ********************************************************************/
182 
183 void
184 generate_random_buffer_ntlmssp (unsigned char *out, int len)
185 {
186  static int urand_fd = -1;
187  unsigned char md4_buf[64];
188  unsigned char tmp_buf[16];
189  unsigned char *p;
190 
191  if (!done_reseed_ntlmssp)
192  {
193  urand_fd = do_reseed_ntlmssp (True, urand_fd);
195  }
196 
197  if (urand_fd != -1 && len > 0)
198  {
199  if (read (urand_fd, out, len) == len)
200  return; /* len bytes of random data read from urandom. */
201 
202  /* Read of urand error, drop back to non urand method. */
203  close (urand_fd);
204  urand_fd = -1;
205  do_reseed_ntlmssp (False, -1);
207  }
208 
209  /*
210  * Generate random numbers in chunks of 64 bytes,
211  * then md4 them & copy to the output buffer.
212  * This way the raw state of the stream is never externally
213  * seen.
214  */
215 
216  p = out;
217  while (len > 0)
218  {
219  int copy_len = len > 16 ? 16 : len;
220 
221  bzero (md4_buf, sizeof (md4_buf));
222  smb_arc4_crypt_ntlmssp (smb_arc4_state, md4_buf, sizeof (md4_buf));
223  mdfour_ntlmssp (tmp_buf, md4_buf, sizeof (md4_buf));
224  memcpy (p, tmp_buf, copy_len);
225  p += copy_len;
226  len -= copy_len;
227  }
228 }
mdfour_ntlmssp
void mdfour_ntlmssp(unsigned char *out, const unsigned char *in, int n)
Definition: md4.c:174
do_reseed_ntlmssp
static int do_reseed_ntlmssp(bool use_fd, int fd)
Definition: genrand.c:130
byteorder.h
Unix SMB/CIFS implementation. SMB Byte handling.
True
#define True
Definition: genrand.c:59
timeval
struct timeval timeval(unsigned long val)
Definition: nasl_builtin_synscan.c:105
get_rand_reseed_data_ntlmssp
static void get_rand_reseed_data_ntlmssp(int *reseed_data)
Definition: genrand.c:80
SIVAL
#define SIVAL(buf, pos, val)
Definition: byteorder.h:130
smb_arc4_crypt_ntlmssp
void smb_arc4_crypt_ntlmssp(unsigned char arc4_state_inout[258], unsigned char *data, size_t len)
Definition: arc4.c:58
smb_arc4_state
static unsigned char smb_arc4_state[258]
Definition: genrand.c:61
smb.h
Unix SMB/CIFS implementation.
generate_random_buffer_ntlmssp
void generate_random_buffer_ntlmssp(unsigned char *out, int len)
Definition: genrand.c:184
proto.h
done_reseed_ntlmssp
static bool done_reseed_ntlmssp
Definition: genrand.c:72
smb_arc4_init_ntlmssp
void smb_arc4_init_ntlmssp(unsigned char arc4_state_out[258], const unsigned char *key, size_t keylen)
Definition: arc4.c:27
counter
static uint32 counter
Definition: genrand.c:62
do_filehash_ntlmssp
static void do_filehash_ntlmssp(const char *fname, unsigned char *the_hash)
Definition: genrand.c:98
reseed_callback_ntlmssp
static void(* reseed_callback_ntlmssp)(int *newseed)
Definition: genrand.c:73
False
#define False
Definition: genrand.c:58
md4.h
Unix SMB/CIFS implementation.
uint32
#define uint32
Definition: genrand.c:54
IVAL
#define IVAL(buf, pos)
Definition: byteorder.h:121
GetTimeOfDay_ntlmssp
void GetTimeOfDay_ntlmssp(struct timeval *tval)
Definition: time.c:102
bool
unsigned int bool
Definition: genrand.c:57