OpenVPN: Update to version 2.3.2. Solves TLS security bug.
[tomato.git] / release / src / router / openvpn / src / openvpn / platform.c
blob16d4daca6f305379bdf5498c657de6d65fededc7
1 /*
2 * OpenVPN -- An application to securely tunnel IP networks
3 * over a single TCP/UDP port, with support for SSL/TLS-based
4 * session authentication and key exchange,
5 * packet encryption, packet authentication, and
6 * packet compression.
8 * Copyright (C) 2002-2010 OpenVPN Technologies, Inc. <sales@openvpn.net>
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License version 2
12 * as published by the Free Software Foundation.
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
19 * You should have received a copy of the GNU General Public License
20 * along with this program (see the file COPYING included with this
21 * distribution); if not, write to the Free Software Foundation, Inc.,
22 * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
25 #ifdef HAVE_CONFIG_H
26 #include "config.h"
27 #elif defined(_MSC_VER)
28 #include "config-msvc.h"
29 #endif
31 #include "syshead.h"
33 #include "buffer.h"
34 #include "error.h"
35 #include "win32.h"
37 #include "memdbg.h"
39 #include "platform.h"
41 /* Redefine the top level directory of the filesystem
42 to restrict access to files for security */
43 void
44 platform_chroot (const char *path)
46 if (path)
48 #ifdef HAVE_CHROOT
49 const char *top = "/";
50 if (chroot (path))
51 msg (M_ERR, "chroot to '%s' failed", path);
52 if (platform_chdir (top))
53 msg (M_ERR, "cd to '%s' failed", top);
54 msg (M_INFO, "chroot to '%s' and cd to '%s' succeeded", path, top);
55 #else
56 msg (M_FATAL, "Sorry but I can't chroot to '%s' because this operating system doesn't appear to support the chroot() system call", path);
57 #endif
61 /* Get/Set UID of process */
63 bool
64 platform_user_get (const char *username, struct platform_state_user *state)
66 bool ret = false;
67 CLEAR (*state);
68 if (username)
70 #if defined(HAVE_GETPWNAM) && defined(HAVE_SETUID)
71 state->pw = getpwnam (username);
72 if (!state->pw)
73 msg (M_ERR, "failed to find UID for user %s", username);
74 state->username = username;
75 ret = true;
76 #else
77 msg (M_FATAL, "cannot get UID for user %s -- platform lacks getpwname() or setuid() system calls", username);
78 #endif
80 return ret;
83 void
84 platform_user_set (const struct platform_state_user *state)
86 #if defined(HAVE_GETPWNAM) && defined(HAVE_SETUID)
87 if (state->username && state->pw)
89 if (setuid (state->pw->pw_uid))
90 msg (M_ERR, "setuid('%s') failed", state->username);
91 msg (M_INFO, "UID set to %s", state->username);
93 #endif
96 /* Get/Set GID of process */
98 bool
99 platform_group_get (const char *groupname, struct platform_state_group *state)
101 bool ret = false;
102 CLEAR (*state);
103 if (groupname)
105 #if defined(HAVE_GETGRNAM) && defined(HAVE_SETGID)
106 state->gr = getgrnam (groupname);
107 if (!state->gr)
108 msg (M_ERR, "failed to find GID for group %s", groupname);
109 state->groupname = groupname;
110 ret = true;
111 #else
112 msg (M_FATAL, "cannot get GID for group %s -- platform lacks getgrnam() or setgid() system calls", groupname);
113 #endif
115 return ret;
118 void
119 platform_group_set (const struct platform_state_group *state)
121 #if defined(HAVE_GETGRNAM) && defined(HAVE_SETGID)
122 if (state->groupname && state->gr)
124 if (setgid (state->gr->gr_gid))
125 msg (M_ERR, "setgid('%s') failed", state->groupname);
126 msg (M_INFO, "GID set to %s", state->groupname);
127 #ifdef HAVE_SETGROUPS
129 gid_t gr_list[1];
130 gr_list[0] = state->gr->gr_gid;
131 if (setgroups (1, gr_list))
132 msg (M_ERR, "setgroups('%s') failed", state->groupname);
134 #endif
136 #endif
139 /* Change process priority */
140 void
141 platform_nice (int niceval)
143 if (niceval)
145 #ifdef HAVE_NICE
146 errno = 0;
147 if (nice (niceval) < 0 && errno != 0)
148 msg (M_WARN | M_ERRNO, "WARNING: nice %d failed: %s", niceval, strerror(errno));
149 else
150 msg (M_INFO, "nice %d succeeded", niceval);
151 #else
152 msg (M_WARN, "WARNING: nice %d failed (function not implemented)", niceval);
153 #endif
157 /* Get current PID */
158 unsigned int
159 platform_getpid ()
161 #ifdef WIN32
162 return (unsigned int) GetCurrentProcessId ();
163 #else
164 #ifdef HAVE_GETPID
165 return (unsigned int) getpid ();
166 #else
167 return 0;
168 #endif
169 #endif
172 /* Disable paging */
173 void
174 platform_mlockall(bool print_msg)
176 #ifdef HAVE_MLOCKALL
177 if (mlockall (MCL_CURRENT | MCL_FUTURE))
178 msg (M_WARN | M_ERRNO, "WARNING: mlockall call failed");
179 else if (print_msg)
180 msg (M_INFO, "mlockall call succeeded");
181 #else
182 msg (M_WARN, "WARNING: mlockall call failed (function not implemented)");
183 #endif
187 * Wrapper for chdir library function
190 platform_chdir (const char* dir)
192 #ifdef HAVE_CHDIR
193 #ifdef WIN32
194 int res;
195 struct gc_arena gc = gc_new ();
196 res = _wchdir (wide_string (dir, &gc));
197 gc_free (&gc);
198 return res;
199 #else
200 return chdir (dir);
201 #endif
202 #else
203 return -1;
204 #endif
208 * convert execve() return into a success/failure value
210 bool
211 platform_system_ok (int stat)
213 #ifdef WIN32
214 return stat == 0;
215 #else
216 return stat != -1 && WIFEXITED (stat) && WEXITSTATUS (stat) == 0;
217 #endif
221 platform_access (const char *path, int mode)
223 #ifdef WIN32
224 struct gc_arena gc = gc_new ();
225 int ret = _waccess (wide_string (path, &gc), mode & ~X_OK);
226 gc_free (&gc);
227 return ret;
228 #else
229 return access (path, mode);
230 #endif
234 * Go to sleep for n milliseconds.
236 void
237 platform_sleep_milliseconds (unsigned int n)
239 #ifdef WIN32
240 Sleep (n);
241 #else
242 struct timeval tv;
243 tv.tv_sec = n / 1000;
244 tv.tv_usec = (n % 1000) * 1000;
245 select (0, NULL, NULL, NULL, &tv);
246 #endif
250 * Go to sleep indefinitely.
252 void
253 platform_sleep_until_signal (void)
255 #ifdef WIN32
256 ASSERT (0);
257 #else
258 select (0, NULL, NULL, NULL, NULL);
259 #endif
262 /* delete a file, return true if succeeded */
263 bool
264 platform_unlink (const char *filename)
266 #if defined(WIN32)
267 struct gc_arena gc = gc_new ();
268 BOOL ret = DeleteFileW (wide_string (filename, &gc));
269 gc_free (&gc);
270 return (ret != 0);
271 #elif defined(HAVE_UNLINK)
272 return (unlink (filename) == 0);
273 #else
274 return false;
275 #endif
278 FILE *
279 platform_fopen (const char *path, const char *mode)
281 #ifdef WIN32
282 struct gc_arena gc = gc_new ();
283 FILE *f = _wfopen (wide_string (path, &gc), wide_string (mode, &gc));
284 gc_free (&gc);
285 return f;
286 #else
287 return fopen(path, mode);
288 #endif
292 platform_open (const char *path, int flags, int mode)
294 #ifdef WIN32
295 struct gc_arena gc = gc_new ();
296 int fd = _wopen (wide_string (path, &gc), flags, mode);
297 gc_free (&gc);
298 return fd;
299 #else
300 return open(path, flags, mode);
301 #endif
305 platform_stat (const char *path, platform_stat_t *buf)
307 #ifdef WIN32
308 struct gc_arena gc = gc_new ();
309 int res = _wstat (wide_string (path, &gc), buf);
310 gc_free (&gc);
311 return res;
312 #else
313 return stat(path, buf);
314 #endif