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