Branch data Line data Source code
1 : : /**
2 : : * \file lib/fko_rand_value.c
3 : : *
4 : : * \ Generate a 16-byte random numeric value.
5 : : */
6 : :
7 : : /* Fwknop is developed primarily by the people listed in the file 'AUTHORS'.
8 : : * Copyright (C) 2009-2015 fwknop developers and contributors. For a full
9 : : * list of contributors, see the file 'CREDITS'.
10 : : *
11 : : * License (GNU General Public License):
12 : : *
13 : : * This program is free software; you can redistribute it and/or
14 : : * modify it under the terms of the GNU General Public License
15 : : * as published by the Free Software Foundation; either version 2
16 : : * of the License, or (at your option) any later version.
17 : : *
18 : : * This program is distributed in the hope that it will be useful,
19 : : * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 : : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 : : * GNU General Public License for more details.
22 : : *
23 : : * You should have received a copy of the GNU General Public License
24 : : * along with this program; if not, write to the Free Software
25 : : * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
26 : : * USA
27 : : *
28 : : *****************************************************************************
29 : : */
30 : : #include "fko_common.h"
31 : : #include "fko.h"
32 : :
33 : : #ifdef WIN32
34 : : #include <sys/timeb.h>
35 : : #include <time.h>
36 : : #else
37 : : #ifdef HAVE_SYS_TIME_H
38 : : #include <sys/time.h>
39 : : #ifdef TIME_WITH_SYS_TIME
40 : : #include <time.h>
41 : : #endif
42 : : #endif
43 : :
44 : : #define RAND_FILE "/dev/urandom"
45 : : #endif
46 : :
47 : : /* Set/Generate the SPA data random value string.
48 : : */
49 : : int
50 : 866231 : fko_set_rand_value(fko_ctx_t ctx, const char * const new_val)
51 : : {
52 : : #ifdef WIN32
53 : : struct _timeb tb;
54 : : #else
55 : : FILE *rfd;
56 : : struct timeval tv;
57 : : size_t amt_read;
58 : : #endif
59 : : unsigned long seed;
60 : : char *tmp_buf;
61 : :
62 : : #if HAVE_LIBFIU
63 [ + + ]: 866231 : fiu_return_on("fko_set_rand_value_init", FKO_ERROR_CTX_NOT_INITIALIZED);
64 : : #endif
65 : :
66 : : /* Context must be initialized.
67 : : */
68 [ + + ][ + - ]: 866228 : if(!CTX_INITIALIZED(ctx))
69 : : return FKO_ERROR_CTX_NOT_INITIALIZED;
70 : :
71 : : /* If a valid value was given, use it and return happy.
72 : : */
73 [ + + ]: 866214 : if(new_val != NULL)
74 : : {
75 : :
76 : : #if HAVE_LIBFIU
77 [ + + ]: 25 : fiu_return_on("fko_set_rand_value_lenval", FKO_ERROR_INVALID_DATA_RAND_LEN_VALIDFAIL);
78 : : #endif
79 [ + + ]: 23 : if(strnlen(new_val, FKO_RAND_VAL_SIZE+1) != FKO_RAND_VAL_SIZE)
80 : : return(FKO_ERROR_INVALID_DATA_RAND_LEN_VALIDFAIL);
81 : :
82 [ + - ]: 13 : if(ctx->rand_val != NULL)
83 : 13 : free(ctx->rand_val);
84 : :
85 : : #if HAVE_LIBFIU
86 [ + - ]: 13 : fiu_return_on("fko_set_rand_value_strdup", FKO_ERROR_MEMORY_ALLOCATION);
87 : : #endif
88 : 13 : ctx->rand_val = strdup(new_val);
89 [ + - ]: 13 : if(ctx->rand_val == NULL)
90 : : return(FKO_ERROR_MEMORY_ALLOCATION);
91 : :
92 : 13 : ctx->state |= FKO_DATA_MODIFIED;
93 : :
94 : 13 : return(FKO_SUCCESS);
95 : : }
96 : :
97 : : #ifdef WIN32
98 : : _ftime_s(&tb);
99 : : seed = ((tb.time * 1000) + tb.millitm) & 0xFFFFFFFF;
100 : : #else
101 : : /* Attempt to read seed data from /dev/urandom. If that does not
102 : : * work, then fall back to a time-based method (less secure, but
103 : : * probably more portable).
104 : : */
105 [ + + ]: 866189 : if((rfd = fopen(RAND_FILE, "r")) != NULL)
106 : : {
107 : : /* Read seed from /dev/urandom
108 : : */
109 : 866165 : amt_read = fread(&seed, 4, 1, rfd);
110 : 866165 : fclose(rfd);
111 : :
112 : : #if HAVE_LIBFIU
113 [ + + ]: 866165 : fiu_return_on("fko_set_rand_value_read", FKO_ERROR_FILESYSTEM_OPERATION);
114 : : #endif
115 [ + - ]: 866162 : if (amt_read != 1)
116 : : return(FKO_ERROR_FILESYSTEM_OPERATION);
117 : : }
118 : : else
119 : : {
120 : : /* Seed based on time (current usecs).
121 : : */
122 : 24 : gettimeofday(&tv, NULL);
123 : :
124 : 24 : seed = tv.tv_usec;
125 : : }
126 : : #endif
127 : :
128 : 866186 : srand(seed);
129 : :
130 [ + + ]: 866186 : if(ctx->rand_val != NULL)
131 : 113 : free(ctx->rand_val);
132 : :
133 : : #if HAVE_LIBFIU
134 [ + + ]: 866186 : fiu_return_on("fko_set_rand_value_calloc1", FKO_ERROR_MEMORY_ALLOCATION);
135 : : #endif
136 : 866183 : ctx->rand_val = calloc(1, FKO_RAND_VAL_SIZE+1);
137 [ + + ]: 866183 : if(ctx->rand_val == NULL)
138 : : return(FKO_ERROR_MEMORY_ALLOCATION);
139 : :
140 : : #if HAVE_LIBFIU
141 [ + + ]: 866153 : fiu_return_on("fko_set_rand_value_calloc2", FKO_ERROR_MEMORY_ALLOCATION);
142 : : #endif
143 : 866150 : tmp_buf = calloc(1, FKO_RAND_VAL_SIZE+1);
144 [ + + ]: 866150 : if(tmp_buf == NULL)
145 : : return(FKO_ERROR_MEMORY_ALLOCATION);
146 : :
147 : 866121 : snprintf(ctx->rand_val, FKO_RAND_VAL_SIZE, "%u", rand());
148 : :
149 [ + + ]: 1732963 : while(strnlen(ctx->rand_val, FKO_RAND_VAL_SIZE+1) < FKO_RAND_VAL_SIZE)
150 : : {
151 : 866842 : snprintf(tmp_buf, FKO_RAND_VAL_SIZE, "%u", rand());
152 : 866842 : strlcat(ctx->rand_val, tmp_buf, FKO_RAND_VAL_SIZE+1);
153 : : }
154 : :
155 : 866121 : free(tmp_buf);
156 : :
157 : 866121 : ctx->state |= FKO_DATA_MODIFIED;
158 : :
159 : 866121 : return(FKO_SUCCESS);
160 : : }
161 : :
162 : : /* Return the current rand value.
163 : : */
164 : : int
165 : 3974 : fko_get_rand_value(fko_ctx_t ctx, char **rand_value)
166 : : {
167 : : /* Must be initialized
168 : : */
169 [ + + ][ + - ]: 3974 : if(!CTX_INITIALIZED(ctx))
170 : : return(FKO_ERROR_CTX_NOT_INITIALIZED);
171 : :
172 [ + + ]: 3822 : if(rand_value == NULL)
173 : : return(FKO_ERROR_INVALID_DATA);
174 : :
175 : 3754 : *rand_value = ctx->rand_val;
176 : :
177 : 3754 : return(FKO_SUCCESS);
178 : : }
179 : :
180 : : /***EOF***/
|