charon: Set CLOEXEC flag on daemon PID file and /dev/(u)random source FDs
[strongswan.git] / src / libstrongswan / plugins / random / random_plugin.c
1 /*
2 * Copyright (C) 2008 Martin Willi
3 * Hochschule fuer Technik Rapperswil
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License as published by the
7 * Free Software Foundation; either version 2 of the License, or (at your
8 * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
9 *
10 * This program is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
12 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
13 * for more details.
14 */
15
16 #include "random_plugin.h"
17
18 #include <unistd.h>
19 #include <sys/types.h>
20 #include <sys/stat.h>
21 #include <fcntl.h>
22 #include <errno.h>
23
24 #include <library.h>
25 #include <utils/debug.h>
26 #include "random_rng.h"
27
28 #ifndef DEV_RANDOM
29 # define DEV_RANDOM "/dev/random"
30 #endif
31
32 #ifndef DEV_URANDOM
33 # define DEV_URANDOM "/dev/urandom"
34 #endif
35
36 typedef struct private_random_plugin_t private_random_plugin_t;
37
38 /**
39 * private data of random_plugin
40 */
41 struct private_random_plugin_t {
42
43 /**
44 * public functions
45 */
46 random_plugin_t public;
47 };
48
49 /** /dev/random file descriptor */
50 static int dev_random = -1;
51 /** /dev/urandom file descriptor */
52 static int dev_urandom = -1;
53
54 /** Is strong randomness equivalent to true randomness? */
55 static bool strong_equals_true = FALSE;
56
57 /**
58 * See header.
59 */
60 int random_plugin_get_dev_random()
61 {
62 return dev_random;
63 }
64
65 /**
66 * See header.
67 */
68 int random_plugin_get_dev_urandom()
69 {
70 return dev_urandom;
71 }
72
73 /**
74 * See header.
75 */
76 bool random_plugin_get_strong_equals_true()
77 {
78 return strong_equals_true;
79 }
80
81 /**
82 * Open a random device file
83 */
84 static bool open_dev(char *file, int *fd)
85 {
86 *fd = open(file, O_RDONLY);
87 if (*fd == -1)
88 {
89 DBG1(DBG_LIB, "opening \"%s\" failed: %s", file, strerror(errno));
90 return FALSE;
91 }
92 if (fcntl(*fd, F_SETFD, FD_CLOEXEC) == -1)
93 {
94 DBG1(DBG_LIB, "setting FD_CLOEXEC for \"%s\" failed: %s",
95 file, strerror(errno));
96 }
97 return TRUE;
98 }
99
100 METHOD(plugin_t, get_name, char*,
101 private_random_plugin_t *this)
102 {
103 return "random";
104 }
105
106 METHOD(plugin_t, get_features, int,
107 private_random_plugin_t *this, plugin_feature_t *features[])
108 {
109 static plugin_feature_t f[] = {
110 PLUGIN_REGISTER(RNG, random_rng_create),
111 PLUGIN_PROVIDE(RNG, RNG_STRONG),
112 PLUGIN_PROVIDE(RNG, RNG_TRUE),
113 };
114 *features = f;
115 return countof(f);
116 }
117
118 METHOD(plugin_t, destroy, void,
119 private_random_plugin_t *this)
120 {
121 if (dev_random != -1)
122 {
123 close(dev_random);
124 }
125 if (dev_urandom != -1)
126 {
127 close(dev_urandom);
128 }
129 free(this);
130 }
131
132 /*
133 * see header file
134 */
135 plugin_t *random_plugin_create()
136 {
137 private_random_plugin_t *this;
138 char *urandom_file, *random_file;
139
140 INIT(this,
141 .public = {
142 .plugin = {
143 .get_name = _get_name,
144 .get_features = _get_features,
145 .destroy = _destroy,
146 },
147 },
148 );
149
150 strong_equals_true = lib->settings->get_bool(lib->settings,
151 "%s.plugins.random.strong_equals_true", FALSE, lib->ns);
152 urandom_file = lib->settings->get_str(lib->settings,
153 "%s.plugins.random.urandom", DEV_URANDOM, lib->ns);
154 random_file = lib->settings->get_str(lib->settings,
155 "%s.plugins.random.random", DEV_RANDOM, lib->ns);
156 if (!open_dev(urandom_file, &dev_urandom) ||
157 !open_dev(random_file, &dev_random))
158 {
159 destroy(this);
160 return NULL;
161 }
162
163 return &this->public.plugin;
164 }
165