mirror of
https://gitlab.com/openconnect/ocserv.git
synced 2026-10-12 01:26:48 +08:00
Added session resumption to TLS server.
This commit is contained in:
@@ -446,6 +446,9 @@
|
|||||||
/* The size of `short', as computed by sizeof. */
|
/* The size of `short', as computed by sizeof. */
|
||||||
#undef SIZEOF_SHORT
|
#undef SIZEOF_SHORT
|
||||||
|
|
||||||
|
/* The size of `unsigned long', as computed by sizeof. */
|
||||||
|
#undef SIZEOF_UNSIGNED_LONG
|
||||||
|
|
||||||
/* Define to l, ll, u, ul, ull, etc., as suitable for constants of type
|
/* Define to l, ll, u, ul, ull, etc., as suitable for constants of type
|
||||||
'size_t'. */
|
'size_t'. */
|
||||||
#undef SIZE_T_SUFFIX
|
#undef SIZE_T_SUFFIX
|
||||||
|
|||||||
@@ -15,6 +15,8 @@ if [ test "$GCC" = "yes" ];then
|
|||||||
CFLAGS="$CFLAGS -Wall"
|
CFLAGS="$CFLAGS -Wall"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
AC_CHECK_SIZEOF([unsigned long])
|
||||||
|
|
||||||
PKG_CHECK_MODULES([LIBGNUTLS], [gnutls >= 3.0.0])
|
PKG_CHECK_MODULES([LIBGNUTLS], [gnutls >= 3.0.0])
|
||||||
|
|
||||||
LIBS="$oldlibs -lgdbm"
|
LIBS="$oldlibs -lgdbm"
|
||||||
|
|||||||
+7
-1
@@ -21,7 +21,7 @@
|
|||||||
# the same distribution terms as the rest of that program.
|
# the same distribution terms as the rest of that program.
|
||||||
#
|
#
|
||||||
# Generated by gnulib-tool.
|
# Generated by gnulib-tool.
|
||||||
# Reproduce by: gnulib-tool --import --dir=. --lib=libgnu --source-base=gl --m4-base=gl/m4 --doc-base=doc --tests-base=gl/tests --aux-dir=build-aux --no-conditional-dependencies --no-libtool --macro-prefix=gl gettime memmem
|
# Reproduce by: gnulib-tool --import --dir=. --lib=libgnu --source-base=gl --m4-base=gl/m4 --doc-base=doc --tests-base=gl/tests --aux-dir=build-aux --no-conditional-dependencies --no-libtool --macro-prefix=gl gettime hash-pjw-bare memmem
|
||||||
|
|
||||||
AUTOMAKE_OPTIONS = 1.5 gnits
|
AUTOMAKE_OPTIONS = 1.5 gnits
|
||||||
|
|
||||||
@@ -64,6 +64,12 @@ EXTRA_libgnu_a_SOURCES += gettimeofday.c
|
|||||||
|
|
||||||
## end gnulib module gettimeofday
|
## end gnulib module gettimeofday
|
||||||
|
|
||||||
|
## begin gnulib module hash-pjw-bare
|
||||||
|
|
||||||
|
libgnu_a_SOURCES += hash-pjw-bare.h hash-pjw-bare.c
|
||||||
|
|
||||||
|
## end gnulib module hash-pjw-bare
|
||||||
|
|
||||||
## begin gnulib module memchr
|
## begin gnulib module memchr
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,42 @@
|
|||||||
|
/* hash-pjw-bare.c -- compute a hash value from a provided buffer.
|
||||||
|
|
||||||
|
Copyright (C) 2012-2013 Free Software Foundation, Inc.
|
||||||
|
|
||||||
|
This program is free software: you can redistribute it and/or modify it
|
||||||
|
under the terms of the GNU General Public License as published
|
||||||
|
by the Free Software Foundation; either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||||
|
|
||||||
|
#include <config.h>
|
||||||
|
|
||||||
|
#include "hash-pjw-bare.h"
|
||||||
|
|
||||||
|
#include <limits.h>
|
||||||
|
|
||||||
|
#define SIZE_BITS (sizeof (size_t) * CHAR_BIT)
|
||||||
|
|
||||||
|
/* Return a hash of the N bytes of X using the method described by
|
||||||
|
Bruno Haible in http://www.haible.de/bruno/hashfunc.html.
|
||||||
|
Note that while many hash functions reduce their result via modulo
|
||||||
|
to a 0..table_size-1 range, this function does not do that. */
|
||||||
|
|
||||||
|
size_t
|
||||||
|
hash_pjw_bare (const void *x, size_t n)
|
||||||
|
{
|
||||||
|
const unsigned char *s = x;
|
||||||
|
size_t h = 0;
|
||||||
|
unsigned i;
|
||||||
|
|
||||||
|
for (i = 0; i < n; i++)
|
||||||
|
h = s[i] + ((h << 9) | (h >> (SIZE_BITS - 9)));
|
||||||
|
|
||||||
|
return h;
|
||||||
|
}
|
||||||
@@ -0,0 +1,24 @@
|
|||||||
|
/* hash-pjw-bare.h -- declaration for a simple hash function
|
||||||
|
Copyright (C) 2012-2013 Free Software Foundation, Inc.
|
||||||
|
|
||||||
|
This program is free software: you can redistribute it and/or modify it
|
||||||
|
under the terms of the GNU General Public License as published
|
||||||
|
by the Free Software Foundation; either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||||
|
|
||||||
|
#include <stddef.h>
|
||||||
|
|
||||||
|
/* Compute a hash code for a buffer starting at X and of size N,
|
||||||
|
and return the hash code. Note that unlike hash_pjw(), it does not
|
||||||
|
return it modulo a table size.
|
||||||
|
The result is platform dependent: it depends on the size of the 'size_t'
|
||||||
|
type and on the signedness of the 'char' type. */
|
||||||
|
extern size_t hash_pjw_bare (const void *x, size_t n) _GL_ATTRIBUTE_PURE;
|
||||||
@@ -27,12 +27,13 @@
|
|||||||
|
|
||||||
|
|
||||||
# Specification in the form of a command-line invocation:
|
# Specification in the form of a command-line invocation:
|
||||||
# gnulib-tool --import --dir=. --lib=libgnu --source-base=gl --m4-base=gl/m4 --doc-base=doc --tests-base=gl/tests --aux-dir=build-aux --no-conditional-dependencies --no-libtool --macro-prefix=gl gettime memmem
|
# gnulib-tool --import --dir=. --lib=libgnu --source-base=gl --m4-base=gl/m4 --doc-base=doc --tests-base=gl/tests --aux-dir=build-aux --no-conditional-dependencies --no-libtool --macro-prefix=gl gettime hash-pjw-bare memmem
|
||||||
|
|
||||||
# Specification in the form of a few gnulib-tool.m4 macro invocations:
|
# Specification in the form of a few gnulib-tool.m4 macro invocations:
|
||||||
gl_LOCAL_DIR([])
|
gl_LOCAL_DIR([])
|
||||||
gl_MODULES([
|
gl_MODULES([
|
||||||
gettime
|
gettime
|
||||||
|
hash-pjw-bare
|
||||||
memmem
|
memmem
|
||||||
])
|
])
|
||||||
gl_AVOID([])
|
gl_AVOID([])
|
||||||
|
|||||||
@@ -44,6 +44,7 @@ AC_DEFUN([gl_EARLY],
|
|||||||
# Code from module extern-inline:
|
# Code from module extern-inline:
|
||||||
# Code from module gettime:
|
# Code from module gettime:
|
||||||
# Code from module gettimeofday:
|
# Code from module gettimeofday:
|
||||||
|
# Code from module hash-pjw-bare:
|
||||||
# Code from module include_next:
|
# Code from module include_next:
|
||||||
# Code from module memchr:
|
# Code from module memchr:
|
||||||
# Code from module memmem:
|
# Code from module memmem:
|
||||||
@@ -253,6 +254,8 @@ AC_DEFUN([gl_FILE_LIST], [
|
|||||||
build-aux/snippet/warn-on-use.h
|
build-aux/snippet/warn-on-use.h
|
||||||
lib/gettime.c
|
lib/gettime.c
|
||||||
lib/gettimeofday.c
|
lib/gettimeofday.c
|
||||||
|
lib/hash-pjw-bare.c
|
||||||
|
lib/hash-pjw-bare.h
|
||||||
lib/memchr.c
|
lib/memchr.c
|
||||||
lib/memchr.valgrind
|
lib/memchr.valgrind
|
||||||
lib/memmem.c
|
lib/memmem.c
|
||||||
|
|||||||
+1
-1
@@ -39,7 +39,7 @@
|
|||||||
Ideally we should test __BIONIC__ here, but it is only defined after
|
Ideally we should test __BIONIC__ here, but it is only defined after
|
||||||
<sys/cdefs.h> has been included; hence test __ANDROID__ instead. */
|
<sys/cdefs.h> has been included; hence test __ANDROID__ instead. */
|
||||||
#if defined __ANDROID__ \
|
#if defined __ANDROID__ \
|
||||||
&& defined _SYS_TYPES_H_ && !defined _SSIZE_T_DEFINED_
|
&& defined _SYS_TYPES_H_ && !defined __need_size_t
|
||||||
# @INCLUDE_NEXT@ @NEXT_STDINT_H@
|
# @INCLUDE_NEXT@ @NEXT_STDINT_H@
|
||||||
#else
|
#else
|
||||||
|
|
||||||
|
|||||||
+97
-99
@@ -17,37 +17,34 @@
|
|||||||
|
|
||||||
/* Written by Paul Eggert. */
|
/* Written by Paul Eggert. */
|
||||||
|
|
||||||
|
#ifndef _@GUARD_PREFIX@_SYS_TIME_H
|
||||||
|
|
||||||
#if __GNUC__ >= 3
|
#if __GNUC__ >= 3
|
||||||
@PRAGMA_SYSTEM_HEADER@
|
@PRAGMA_SYSTEM_HEADER@
|
||||||
#endif
|
#endif
|
||||||
@PRAGMA_COLUMNS@
|
@PRAGMA_COLUMNS@
|
||||||
|
|
||||||
#if defined _@GUARD_PREFIX@_SYS_TIME_H
|
/* The include_next requires a split double-inclusion guard. */
|
||||||
|
#if @HAVE_SYS_TIME_H@
|
||||||
|
# @INCLUDE_NEXT@ @NEXT_SYS_TIME_H@
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Simply delegate to the system's header, without adding anything. */
|
#ifndef _@GUARD_PREFIX@_SYS_TIME_H
|
||||||
# if @HAVE_SYS_TIME_H@
|
#define _@GUARD_PREFIX@_SYS_TIME_H
|
||||||
# @INCLUDE_NEXT@ @NEXT_SYS_TIME_H@
|
|
||||||
# endif
|
|
||||||
|
|
||||||
#else
|
#if ! @HAVE_SYS_TIME_H@
|
||||||
|
# include <time.h>
|
||||||
# define _@GUARD_PREFIX@_SYS_TIME_H
|
#endif
|
||||||
|
|
||||||
# if @HAVE_SYS_TIME_H@
|
|
||||||
# @INCLUDE_NEXT@ @NEXT_SYS_TIME_H@
|
|
||||||
# else
|
|
||||||
# include <time.h>
|
|
||||||
# endif
|
|
||||||
|
|
||||||
/* On native Windows with MSVC, get the 'struct timeval' type.
|
/* On native Windows with MSVC, get the 'struct timeval' type.
|
||||||
Also, on native Windows with a 64-bit time_t, where we are overriding the
|
Also, on native Windows with a 64-bit time_t, where we are overriding the
|
||||||
'struct timeval' type, get all declarations of system functions whose
|
'struct timeval' type, get all declarations of system functions whose
|
||||||
signature contains 'struct timeval'. */
|
signature contains 'struct timeval'. */
|
||||||
# if (defined _MSC_VER || @REPLACE_STRUCT_TIMEVAL@) && @HAVE_WINSOCK2_H@ && !defined _GL_INCLUDING_WINSOCK2_H
|
#if (defined _MSC_VER || @REPLACE_STRUCT_TIMEVAL@) && @HAVE_WINSOCK2_H@ && !defined _GL_INCLUDING_WINSOCK2_H
|
||||||
# define _GL_INCLUDING_WINSOCK2_H
|
# define _GL_INCLUDING_WINSOCK2_H
|
||||||
# include <winsock2.h>
|
# include <winsock2.h>
|
||||||
# undef _GL_INCLUDING_WINSOCK2_H
|
# undef _GL_INCLUDING_WINSOCK2_H
|
||||||
# endif
|
#endif
|
||||||
|
|
||||||
/* The definitions of _GL_FUNCDECL_RPL etc. are copied here. */
|
/* The definitions of _GL_FUNCDECL_RPL etc. are copied here. */
|
||||||
|
|
||||||
@@ -55,112 +52,112 @@
|
|||||||
|
|
||||||
/* The definition of _GL_WARN_ON_USE is copied here. */
|
/* The definition of _GL_WARN_ON_USE is copied here. */
|
||||||
|
|
||||||
# ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if !@HAVE_STRUCT_TIMEVAL@ || @REPLACE_STRUCT_TIMEVAL@
|
||||||
|
|
||||||
|
# if @REPLACE_STRUCT_TIMEVAL@
|
||||||
|
# define timeval rpl_timeval
|
||||||
# endif
|
# endif
|
||||||
|
|
||||||
# if !@HAVE_STRUCT_TIMEVAL@ || @REPLACE_STRUCT_TIMEVAL@
|
# if !GNULIB_defined_struct_timeval
|
||||||
|
|
||||||
# if @REPLACE_STRUCT_TIMEVAL@
|
|
||||||
# define timeval rpl_timeval
|
|
||||||
# endif
|
|
||||||
|
|
||||||
# if !GNULIB_defined_struct_timeval
|
|
||||||
struct timeval
|
struct timeval
|
||||||
{
|
{
|
||||||
time_t tv_sec;
|
time_t tv_sec;
|
||||||
long int tv_usec;
|
long int tv_usec;
|
||||||
};
|
};
|
||||||
# define GNULIB_defined_struct_timeval 1
|
# define GNULIB_defined_struct_timeval 1
|
||||||
# endif
|
|
||||||
|
|
||||||
# endif
|
# endif
|
||||||
|
|
||||||
# ifdef __cplusplus
|
#endif
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
# endif
|
#endif
|
||||||
|
|
||||||
# if @GNULIB_GETTIMEOFDAY@
|
#if @GNULIB_GETTIMEOFDAY@
|
||||||
# if @REPLACE_GETTIMEOFDAY@
|
# if @REPLACE_GETTIMEOFDAY@
|
||||||
# if !(defined __cplusplus && defined GNULIB_NAMESPACE)
|
# if !(defined __cplusplus && defined GNULIB_NAMESPACE)
|
||||||
# undef gettimeofday
|
# undef gettimeofday
|
||||||
# define gettimeofday rpl_gettimeofday
|
# define gettimeofday rpl_gettimeofday
|
||||||
# endif
|
# endif
|
||||||
_GL_FUNCDECL_RPL (gettimeofday, int,
|
_GL_FUNCDECL_RPL (gettimeofday, int,
|
||||||
(struct timeval *restrict, void *restrict)
|
(struct timeval *restrict, void *restrict)
|
||||||
_GL_ARG_NONNULL ((1)));
|
_GL_ARG_NONNULL ((1)));
|
||||||
_GL_CXXALIAS_RPL (gettimeofday, int,
|
_GL_CXXALIAS_RPL (gettimeofday, int,
|
||||||
(struct timeval *restrict, void *restrict));
|
(struct timeval *restrict, void *restrict));
|
||||||
# else
|
# else
|
||||||
# if !@HAVE_GETTIMEOFDAY@
|
# if !@HAVE_GETTIMEOFDAY@
|
||||||
_GL_FUNCDECL_SYS (gettimeofday, int,
|
_GL_FUNCDECL_SYS (gettimeofday, int,
|
||||||
(struct timeval *restrict, void *restrict)
|
(struct timeval *restrict, void *restrict)
|
||||||
_GL_ARG_NONNULL ((1)));
|
_GL_ARG_NONNULL ((1)));
|
||||||
# endif
|
# endif
|
||||||
/* Need to cast, because on glibc systems, by default, the second argument is
|
/* Need to cast, because on glibc systems, by default, the second argument is
|
||||||
struct timezone *. */
|
struct timezone *. */
|
||||||
_GL_CXXALIAS_SYS_CAST (gettimeofday, int,
|
_GL_CXXALIAS_SYS_CAST (gettimeofday, int,
|
||||||
(struct timeval *restrict, void *restrict));
|
(struct timeval *restrict, void *restrict));
|
||||||
# endif
|
# endif
|
||||||
_GL_CXXALIASWARN (gettimeofday);
|
_GL_CXXALIASWARN (gettimeofday);
|
||||||
# elif defined GNULIB_POSIXCHECK
|
#elif defined GNULIB_POSIXCHECK
|
||||||
# undef gettimeofday
|
# undef gettimeofday
|
||||||
# if HAVE_RAW_DECL_GETTIMEOFDAY
|
# if HAVE_RAW_DECL_GETTIMEOFDAY
|
||||||
_GL_WARN_ON_USE (gettimeofday, "gettimeofday is unportable - "
|
_GL_WARN_ON_USE (gettimeofday, "gettimeofday is unportable - "
|
||||||
"use gnulib module gettimeofday for portability");
|
"use gnulib module gettimeofday for portability");
|
||||||
# endif
|
|
||||||
# endif
|
# endif
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Hide some function declarations from <winsock2.h>. */
|
/* Hide some function declarations from <winsock2.h>. */
|
||||||
|
|
||||||
# if defined _MSC_VER && @HAVE_WINSOCK2_H@
|
#if defined _MSC_VER && @HAVE_WINSOCK2_H@
|
||||||
# if !defined _@GUARD_PREFIX@_UNISTD_H
|
# if !defined _@GUARD_PREFIX@_UNISTD_H
|
||||||
# if !(defined __cplusplus && defined GNULIB_NAMESPACE)
|
# if !(defined __cplusplus && defined GNULIB_NAMESPACE)
|
||||||
# undef close
|
# undef close
|
||||||
# define close close_used_without_including_unistd_h
|
# define close close_used_without_including_unistd_h
|
||||||
# else
|
# else
|
||||||
_GL_WARN_ON_USE (close,
|
_GL_WARN_ON_USE (close,
|
||||||
"close() used without including <unistd.h>");
|
"close() used without including <unistd.h>");
|
||||||
# endif
|
# endif
|
||||||
# if !(defined __cplusplus && defined GNULIB_NAMESPACE)
|
# if !(defined __cplusplus && defined GNULIB_NAMESPACE)
|
||||||
# undef gethostname
|
# undef gethostname
|
||||||
# define gethostname gethostname_used_without_including_unistd_h
|
# define gethostname gethostname_used_without_including_unistd_h
|
||||||
# else
|
# else
|
||||||
_GL_WARN_ON_USE (gethostname,
|
_GL_WARN_ON_USE (gethostname,
|
||||||
"gethostname() used without including <unistd.h>");
|
"gethostname() used without including <unistd.h>");
|
||||||
# endif
|
|
||||||
# endif
|
# endif
|
||||||
# if !defined _@GUARD_PREFIX@_SYS_SOCKET_H
|
# endif
|
||||||
# if !(defined __cplusplus && defined GNULIB_NAMESPACE)
|
# if !defined _@GUARD_PREFIX@_SYS_SOCKET_H
|
||||||
# undef socket
|
# if !(defined __cplusplus && defined GNULIB_NAMESPACE)
|
||||||
# define socket socket_used_without_including_sys_socket_h
|
# undef socket
|
||||||
# undef connect
|
# define socket socket_used_without_including_sys_socket_h
|
||||||
# define connect connect_used_without_including_sys_socket_h
|
# undef connect
|
||||||
# undef accept
|
# define connect connect_used_without_including_sys_socket_h
|
||||||
# define accept accept_used_without_including_sys_socket_h
|
# undef accept
|
||||||
# undef bind
|
# define accept accept_used_without_including_sys_socket_h
|
||||||
# define bind bind_used_without_including_sys_socket_h
|
# undef bind
|
||||||
# undef getpeername
|
# define bind bind_used_without_including_sys_socket_h
|
||||||
# define getpeername getpeername_used_without_including_sys_socket_h
|
# undef getpeername
|
||||||
# undef getsockname
|
# define getpeername getpeername_used_without_including_sys_socket_h
|
||||||
# define getsockname getsockname_used_without_including_sys_socket_h
|
# undef getsockname
|
||||||
# undef getsockopt
|
# define getsockname getsockname_used_without_including_sys_socket_h
|
||||||
# define getsockopt getsockopt_used_without_including_sys_socket_h
|
# undef getsockopt
|
||||||
# undef listen
|
# define getsockopt getsockopt_used_without_including_sys_socket_h
|
||||||
# define listen listen_used_without_including_sys_socket_h
|
# undef listen
|
||||||
# undef recv
|
# define listen listen_used_without_including_sys_socket_h
|
||||||
# define recv recv_used_without_including_sys_socket_h
|
# undef recv
|
||||||
# undef send
|
# define recv recv_used_without_including_sys_socket_h
|
||||||
# define send send_used_without_including_sys_socket_h
|
# undef send
|
||||||
# undef recvfrom
|
# define send send_used_without_including_sys_socket_h
|
||||||
# define recvfrom recvfrom_used_without_including_sys_socket_h
|
# undef recvfrom
|
||||||
# undef sendto
|
# define recvfrom recvfrom_used_without_including_sys_socket_h
|
||||||
# define sendto sendto_used_without_including_sys_socket_h
|
# undef sendto
|
||||||
# undef setsockopt
|
# define sendto sendto_used_without_including_sys_socket_h
|
||||||
# define setsockopt setsockopt_used_without_including_sys_socket_h
|
# undef setsockopt
|
||||||
# undef shutdown
|
# define setsockopt setsockopt_used_without_including_sys_socket_h
|
||||||
# define shutdown shutdown_used_without_including_sys_socket_h
|
# undef shutdown
|
||||||
# else
|
# define shutdown shutdown_used_without_including_sys_socket_h
|
||||||
|
# else
|
||||||
_GL_WARN_ON_USE (socket,
|
_GL_WARN_ON_USE (socket,
|
||||||
"socket() used without including <sys/socket.h>");
|
"socket() used without including <sys/socket.h>");
|
||||||
_GL_WARN_ON_USE (connect,
|
_GL_WARN_ON_USE (connect,
|
||||||
@@ -189,17 +186,18 @@ _GL_WARN_ON_USE (gettimeofday, "gettimeofday is unportable - "
|
|||||||
"setsockopt() used without including <sys/socket.h>");
|
"setsockopt() used without including <sys/socket.h>");
|
||||||
_GL_WARN_ON_USE (shutdown,
|
_GL_WARN_ON_USE (shutdown,
|
||||||
"shutdown() used without including <sys/socket.h>");
|
"shutdown() used without including <sys/socket.h>");
|
||||||
# endif
|
|
||||||
# endif
|
|
||||||
# if !defined _@GUARD_PREFIX@_SYS_SELECT_H
|
|
||||||
# if !(defined __cplusplus && defined GNULIB_NAMESPACE)
|
|
||||||
# undef select
|
|
||||||
# define select select_used_without_including_sys_select_h
|
|
||||||
# else
|
|
||||||
_GL_WARN_ON_USE (select,
|
|
||||||
"select() used without including <sys/select.h>");
|
|
||||||
# endif
|
|
||||||
# endif
|
# endif
|
||||||
# endif
|
# endif
|
||||||
|
# if !defined _@GUARD_PREFIX@_SYS_SELECT_H
|
||||||
|
# if !(defined __cplusplus && defined GNULIB_NAMESPACE)
|
||||||
|
# undef select
|
||||||
|
# define select select_used_without_including_sys_select_h
|
||||||
|
# else
|
||||||
|
_GL_WARN_ON_USE (select,
|
||||||
|
"select() used without including <sys/select.h>");
|
||||||
|
# endif
|
||||||
|
# endif
|
||||||
|
#endif
|
||||||
|
|
||||||
#endif /* _@GUARD_PREFIX@_SYS_TIME_H */
|
#endif /* _@GUARD_PREFIX@_SYS_TIME_H */
|
||||||
|
#endif /* _@GUARD_PREFIX@_SYS_TIME_H */
|
||||||
|
|||||||
+3
-2
@@ -1,4 +1,4 @@
|
|||||||
AM_CPPFLAGS = -I$(srcdir)../gl/ -I$(builddir)../gl/ \
|
AM_CPPFLAGS = -I$(srcdir)/../gl/ -I$(builddir)/../gl/ \
|
||||||
-I$(srcdir)/ -I$(builddir)/../ -I$(srcdir)/../libopts
|
-I$(srcdir)/ -I$(builddir)/../ -I$(srcdir)/../libopts
|
||||||
|
|
||||||
EXTRA_DIST = ocserv.1 sample.config
|
EXTRA_DIST = ocserv.1 sample.config
|
||||||
@@ -8,7 +8,8 @@ bin_PROGRAMS = ocserv
|
|||||||
ocserv_SOURCES = main.c main-auth.c worker-vpn.c worker-auth.c tlslib.c \
|
ocserv_SOURCES = main.c main-auth.c worker-vpn.c worker-auth.c tlslib.c \
|
||||||
cookies.c http-parser/http_parser.c \
|
cookies.c http-parser/http_parser.c \
|
||||||
vpn.h cookies.h tlslib.h http-parser/http_parser.h log.c tun.c tun.h \
|
vpn.h cookies.h tlslib.h http-parser/http_parser.h log.c tun.c tun.h \
|
||||||
config.c worker-auth.h pam.c pam.h
|
config.c worker-auth.h pam.c pam.h worker-resume.c worker.h hash.h \
|
||||||
|
hashtable.h main-resume.c
|
||||||
|
|
||||||
ocserv_SOURCES += ocserv-args.def ocserv-args.c ocserv-args.h
|
ocserv_SOURCES += ocserv-args.def ocserv-args.c ocserv-args.h
|
||||||
|
|
||||||
|
|||||||
+80
@@ -0,0 +1,80 @@
|
|||||||
|
#ifndef _LINUX_HASH_H
|
||||||
|
#define _LINUX_HASH_H
|
||||||
|
/* Fast hashing routine for ints, longs and pointers.
|
||||||
|
(C) 2002 Nadia Yvette Chambers, IBM */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Knuth recommends primes in approximately golden ratio to the maximum
|
||||||
|
* integer representable by a machine word for multiplicative hashing.
|
||||||
|
* Chuck Lever verified the effectiveness of this technique:
|
||||||
|
* http://www.citi.umich.edu/techreports/reports/citi-tr-00-1.pdf
|
||||||
|
*
|
||||||
|
* These primes are chosen to be bit-sparse, that is operations on
|
||||||
|
* them can use shifts and additions instead of multiplications for
|
||||||
|
* machines where multiplications are slow.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
/* 2^31 + 2^29 - 2^25 + 2^22 - 2^19 - 2^16 + 1 */
|
||||||
|
#define GOLDEN_RATIO_PRIME_32 0x9e370001UL
|
||||||
|
/* 2^63 + 2^61 - 2^57 + 2^54 - 2^51 - 2^18 + 1 */
|
||||||
|
#define GOLDEN_RATIO_PRIME_64 0x9e37fffffffc0001UL
|
||||||
|
|
||||||
|
#if SIZEOF_UNSIGNED_LONG == 4
|
||||||
|
#define GOLDEN_RATIO_PRIME GOLDEN_RATIO_PRIME_32
|
||||||
|
#define hash_long(val, bits) hash_32(val, bits)
|
||||||
|
#elif SIZEOF_UNSIGNED_LONG == 8
|
||||||
|
#define hash_long(val, bits) hash_64(val, bits)
|
||||||
|
#define GOLDEN_RATIO_PRIME GOLDEN_RATIO_PRIME_64
|
||||||
|
#else
|
||||||
|
#error Wordsize not 32 or 64
|
||||||
|
#endif
|
||||||
|
|
||||||
|
static inline uint64_t hash_64(uint64_t val, unsigned int bits)
|
||||||
|
{
|
||||||
|
uint64_t hash = val;
|
||||||
|
|
||||||
|
/* Sigh, gcc can't optimise this alone like it does for 32 bits. */
|
||||||
|
uint64_t n = hash;
|
||||||
|
n <<= 18;
|
||||||
|
hash -= n;
|
||||||
|
n <<= 33;
|
||||||
|
hash -= n;
|
||||||
|
n <<= 3;
|
||||||
|
hash += n;
|
||||||
|
n <<= 3;
|
||||||
|
hash -= n;
|
||||||
|
n <<= 4;
|
||||||
|
hash += n;
|
||||||
|
n <<= 2;
|
||||||
|
hash += n;
|
||||||
|
|
||||||
|
/* High bits are more random, so use them. */
|
||||||
|
return hash >> (64 - bits);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline uint32_t hash_32(uint32_t val, unsigned int bits)
|
||||||
|
{
|
||||||
|
/* On some cpus multiply is faster, on others gcc will do shifts */
|
||||||
|
uint32_t hash = val * GOLDEN_RATIO_PRIME_32;
|
||||||
|
|
||||||
|
/* High bits are more random, so use them. */
|
||||||
|
return hash >> (32 - bits);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline unsigned long hash_ptr(const void *ptr, unsigned int bits)
|
||||||
|
{
|
||||||
|
return hash_long((unsigned long)ptr, bits);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline uint32_t hash32_ptr(const void *ptr)
|
||||||
|
{
|
||||||
|
unsigned long val = (unsigned long)ptr;
|
||||||
|
|
||||||
|
#if SIZEOF_UNSIGNED_LONG == 8
|
||||||
|
val ^= (val >> 32);
|
||||||
|
#endif
|
||||||
|
return (uint32_t)val;
|
||||||
|
}
|
||||||
|
#endif /* _LINUX_HASH_H */
|
||||||
+231
@@ -0,0 +1,231 @@
|
|||||||
|
/*
|
||||||
|
* Statically sized hash table implementation
|
||||||
|
* (C) 2012 Sasha Levin <levinsasha928@gmail.com>
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _LINUX_HASHTABLE_H
|
||||||
|
#define _LINUX_HASHTABLE_H
|
||||||
|
|
||||||
|
#include <list.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ilog2 - log of base 2 of 32-bit or a 64-bit unsigned value
|
||||||
|
* @n - parameter
|
||||||
|
*
|
||||||
|
* constant-capable log of base 2 calculation
|
||||||
|
* - this can be used to initialise global variables from constant data, hence
|
||||||
|
* the massive ternary operator construction
|
||||||
|
*
|
||||||
|
* selects the appropriately-sized optimised version depending on sizeof(n)
|
||||||
|
*/
|
||||||
|
#define hash_ilog2(n) \
|
||||||
|
( \
|
||||||
|
__builtin_constant_p(n) ? ( \
|
||||||
|
(n) < 1 ? -1 : \
|
||||||
|
(n) & (1ULL << 63) ? 63 : \
|
||||||
|
(n) & (1ULL << 62) ? 62 : \
|
||||||
|
(n) & (1ULL << 61) ? 61 : \
|
||||||
|
(n) & (1ULL << 60) ? 60 : \
|
||||||
|
(n) & (1ULL << 59) ? 59 : \
|
||||||
|
(n) & (1ULL << 58) ? 58 : \
|
||||||
|
(n) & (1ULL << 57) ? 57 : \
|
||||||
|
(n) & (1ULL << 56) ? 56 : \
|
||||||
|
(n) & (1ULL << 55) ? 55 : \
|
||||||
|
(n) & (1ULL << 54) ? 54 : \
|
||||||
|
(n) & (1ULL << 53) ? 53 : \
|
||||||
|
(n) & (1ULL << 52) ? 52 : \
|
||||||
|
(n) & (1ULL << 51) ? 51 : \
|
||||||
|
(n) & (1ULL << 50) ? 50 : \
|
||||||
|
(n) & (1ULL << 49) ? 49 : \
|
||||||
|
(n) & (1ULL << 48) ? 48 : \
|
||||||
|
(n) & (1ULL << 47) ? 47 : \
|
||||||
|
(n) & (1ULL << 46) ? 46 : \
|
||||||
|
(n) & (1ULL << 45) ? 45 : \
|
||||||
|
(n) & (1ULL << 44) ? 44 : \
|
||||||
|
(n) & (1ULL << 43) ? 43 : \
|
||||||
|
(n) & (1ULL << 42) ? 42 : \
|
||||||
|
(n) & (1ULL << 41) ? 41 : \
|
||||||
|
(n) & (1ULL << 40) ? 40 : \
|
||||||
|
(n) & (1ULL << 39) ? 39 : \
|
||||||
|
(n) & (1ULL << 38) ? 38 : \
|
||||||
|
(n) & (1ULL << 37) ? 37 : \
|
||||||
|
(n) & (1ULL << 36) ? 36 : \
|
||||||
|
(n) & (1ULL << 35) ? 35 : \
|
||||||
|
(n) & (1ULL << 34) ? 34 : \
|
||||||
|
(n) & (1ULL << 33) ? 33 : \
|
||||||
|
(n) & (1ULL << 32) ? 32 : \
|
||||||
|
(n) & (1ULL << 31) ? 31 : \
|
||||||
|
(n) & (1ULL << 30) ? 30 : \
|
||||||
|
(n) & (1ULL << 29) ? 29 : \
|
||||||
|
(n) & (1ULL << 28) ? 28 : \
|
||||||
|
(n) & (1ULL << 27) ? 27 : \
|
||||||
|
(n) & (1ULL << 26) ? 26 : \
|
||||||
|
(n) & (1ULL << 25) ? 25 : \
|
||||||
|
(n) & (1ULL << 24) ? 24 : \
|
||||||
|
(n) & (1ULL << 23) ? 23 : \
|
||||||
|
(n) & (1ULL << 22) ? 22 : \
|
||||||
|
(n) & (1ULL << 21) ? 21 : \
|
||||||
|
(n) & (1ULL << 20) ? 20 : \
|
||||||
|
(n) & (1ULL << 19) ? 19 : \
|
||||||
|
(n) & (1ULL << 18) ? 18 : \
|
||||||
|
(n) & (1ULL << 17) ? 17 : \
|
||||||
|
(n) & (1ULL << 16) ? 16 : \
|
||||||
|
(n) & (1ULL << 15) ? 15 : \
|
||||||
|
(n) & (1ULL << 14) ? 14 : \
|
||||||
|
(n) & (1ULL << 13) ? 13 : \
|
||||||
|
(n) & (1ULL << 12) ? 12 : \
|
||||||
|
(n) & (1ULL << 11) ? 11 : \
|
||||||
|
(n) & (1ULL << 10) ? 10 : \
|
||||||
|
(n) & (1ULL << 9) ? 9 : \
|
||||||
|
(n) & (1ULL << 8) ? 8 : \
|
||||||
|
(n) & (1ULL << 7) ? 7 : \
|
||||||
|
(n) & (1ULL << 6) ? 6 : \
|
||||||
|
(n) & (1ULL << 5) ? 5 : \
|
||||||
|
(n) & (1ULL << 4) ? 4 : \
|
||||||
|
(n) & (1ULL << 3) ? 3 : \
|
||||||
|
(n) & (1ULL << 2) ? 2 : \
|
||||||
|
(n) & (1ULL << 1) ? 1 : \
|
||||||
|
(n) & (1ULL << 0) ? 0 : \
|
||||||
|
-1 \
|
||||||
|
) : \
|
||||||
|
-1 \
|
||||||
|
)
|
||||||
|
|
||||||
|
#define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0]))
|
||||||
|
|
||||||
|
#define DEFINE_HASHTABLE(name, bits) \
|
||||||
|
struct hlist_head name[1 << (bits)] = \
|
||||||
|
{ [0 ... ((1 << (bits)) - 1)] = HLIST_HEAD_INIT }
|
||||||
|
|
||||||
|
#define DECLARE_HASHTABLE(name, bits) \
|
||||||
|
struct hlist_head name[1 << (bits)]
|
||||||
|
|
||||||
|
#define HASH_SIZE(name) (ARRAY_SIZE(name))
|
||||||
|
#define HASH_BITS(name) hash_ilog2(HASH_SIZE(name))
|
||||||
|
|
||||||
|
/* Use hash_32 when possible to allow for fast 32bit hashing in 64bit kernels. */
|
||||||
|
#define hash_min(val, bits) \
|
||||||
|
(sizeof(val) <= 4 ? hash_32(val, bits) : hash_long(val, bits))
|
||||||
|
|
||||||
|
static inline void __hash_init(struct hlist_head *ht, unsigned int sz)
|
||||||
|
{
|
||||||
|
unsigned int i;
|
||||||
|
|
||||||
|
for (i = 0; i < sz; i++)
|
||||||
|
INIT_HLIST_HEAD(&ht[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* hash_init - initialize a hash table
|
||||||
|
* @hashtable: hashtable to be initialized
|
||||||
|
*
|
||||||
|
* Calculates the size of the hashtable from the given parameter, otherwise
|
||||||
|
* same as hash_init_size.
|
||||||
|
*
|
||||||
|
* This has to be a macro since HASH_BITS() will not work on pointers since
|
||||||
|
* it calculates the size during preprocessing.
|
||||||
|
*/
|
||||||
|
#define hash_init(hashtable) __hash_init(hashtable, HASH_SIZE(hashtable))
|
||||||
|
|
||||||
|
/**
|
||||||
|
* hash_add - add an object to a hashtable
|
||||||
|
* @hashtable: hashtable to add to
|
||||||
|
* @node: the &struct hlist_node of the object to be added
|
||||||
|
* @key: the key of the object to be added
|
||||||
|
*/
|
||||||
|
#define hash_add(hashtable, node, key) \
|
||||||
|
hlist_add_head(node, &hashtable[hash_min(key, HASH_BITS(hashtable))])
|
||||||
|
|
||||||
|
/**
|
||||||
|
* hash_hashed - check whether an object is in any hashtable
|
||||||
|
* @node: the &struct hlist_node of the object to be checked
|
||||||
|
*/
|
||||||
|
static inline unsigned hash_hashed(struct hlist_node *node)
|
||||||
|
{
|
||||||
|
return !hlist_unhashed(node);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline unsigned __hash_empty(struct hlist_head *ht, unsigned int sz)
|
||||||
|
{
|
||||||
|
unsigned int i;
|
||||||
|
|
||||||
|
for (i = 0; i < sz; i++)
|
||||||
|
if (!hlist_empty(&ht[i]))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* hash_empty - check whether a hashtable is empty
|
||||||
|
* @hashtable: hashtable to check
|
||||||
|
*
|
||||||
|
* This has to be a macro since HASH_BITS() will not work on pointers since
|
||||||
|
* it calculates the size during preprocessing.
|
||||||
|
*/
|
||||||
|
#define hash_empty(hashtable) __hash_empty(hashtable, HASH_SIZE(hashtable))
|
||||||
|
|
||||||
|
/**
|
||||||
|
* hash_del - remove an object from a hashtable
|
||||||
|
* @node: &struct hlist_node of the object to remove
|
||||||
|
*/
|
||||||
|
static inline void hash_del(struct hlist_node *node)
|
||||||
|
{
|
||||||
|
hlist_del_init(node);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* hash_for_each - iterate over a hashtable
|
||||||
|
* @name: hashtable to iterate
|
||||||
|
* @bkt: integer to use as bucket loop cursor
|
||||||
|
* @node: the &struct list_head to use as a loop cursor for each entry
|
||||||
|
* @obj: the type * to use as a loop cursor for each entry
|
||||||
|
* @member: the name of the hlist_node within the struct
|
||||||
|
*/
|
||||||
|
#define hash_for_each(name, bkt, node, obj, member) \
|
||||||
|
for ((bkt) = 0, node = NULL; node == NULL && (bkt) < HASH_SIZE(name); (bkt)++)\
|
||||||
|
hlist_for_each_entry(obj, node, &name[bkt], member)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* hash_for_each_safe - iterate over a hashtable safe against removal of
|
||||||
|
* hash entry
|
||||||
|
* @name: hashtable to iterate
|
||||||
|
* @bkt: integer to use as bucket loop cursor
|
||||||
|
* @node: the &struct list_head to use as a loop cursor for each entry
|
||||||
|
* @tmp: a &struct used for temporary storage
|
||||||
|
* @obj: the type * to use as a loop cursor for each entry
|
||||||
|
* @member: the name of the hlist_node within the struct
|
||||||
|
*/
|
||||||
|
#define hash_for_each_safe(name, bkt, node, tmp, obj, member) \
|
||||||
|
for ((bkt) = 0, node = NULL; node == NULL && (bkt) < HASH_SIZE(name); (bkt)++)\
|
||||||
|
hlist_for_each_entry_safe(obj, node, tmp, &name[bkt], member)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* hash_for_each_possible - iterate over all possible objects hashing to the
|
||||||
|
* same bucket
|
||||||
|
* @name: hashtable to iterate
|
||||||
|
* @obj: the type * to use as a loop cursor for each entry
|
||||||
|
* @node: the &struct list_head to use as a loop cursor for each entry
|
||||||
|
* @member: the name of the hlist_node within the struct
|
||||||
|
* @key: the key of the objects to iterate over
|
||||||
|
*/
|
||||||
|
#define hash_for_each_possible(name, obj, node, member, key) \
|
||||||
|
hlist_for_each_entry(obj, node, &name[hash_min(key, HASH_BITS(name))], member)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* hash_for_each_possible_safe - iterate over all possible objects hashing to the
|
||||||
|
* same bucket safe against removals
|
||||||
|
* @name: hashtable to iterate
|
||||||
|
* @obj: the type * to use as a loop cursor for each entry
|
||||||
|
* @node: the &struct list_head to use as a loop cursor for each entry
|
||||||
|
* @tmp: a &struct used for temporary storage
|
||||||
|
* @member: the name of the hlist_node within the struct
|
||||||
|
* @key: the key of the objects to iterate over
|
||||||
|
*/
|
||||||
|
#define hash_for_each_possible_safe(name, obj, node, tmp, member, key) \
|
||||||
|
hlist_for_each_entry_safe(obj, node, tmp, \
|
||||||
|
&name[hash_min(key, HASH_BITS(name))], member)
|
||||||
|
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
#ifndef WORKER_AUTH_H
|
#ifndef IPC_H
|
||||||
#define WORKER_AUTH_H
|
#define IPC_H
|
||||||
|
|
||||||
#include <config.h>
|
#include <config.h>
|
||||||
#include <syslog.h>
|
#include <syslog.h>
|
||||||
@@ -9,11 +9,16 @@
|
|||||||
#include <net/if.h>
|
#include <net/if.h>
|
||||||
#include <vpn.h>
|
#include <vpn.h>
|
||||||
#include <cookies.h>
|
#include <cookies.h>
|
||||||
|
#include <tlslib.h>
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
AUTH_REQ = 1,
|
AUTH_REQ = 1,
|
||||||
AUTH_COOKIE_REQ,
|
AUTH_COOKIE_REQ,
|
||||||
AUTH_REP,
|
AUTH_REP,
|
||||||
|
RESUME_STORE_REQ,
|
||||||
|
RESUME_DELETE_REQ,
|
||||||
|
RESUME_FETCH_REQ,
|
||||||
|
RESUME_FETCH_REP,
|
||||||
CMD_TERMINATE,
|
CMD_TERMINATE,
|
||||||
} cmd_request_t;
|
} cmd_request_t;
|
||||||
|
|
||||||
@@ -22,6 +27,11 @@ typedef enum {
|
|||||||
REP_AUTH_FAILED = 1,
|
REP_AUTH_FAILED = 1,
|
||||||
} cmd_auth_reply_t;
|
} cmd_auth_reply_t;
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
REP_RESUME_OK = 0,
|
||||||
|
REP_RESUME_FAILED = 1,
|
||||||
|
} cmd_resume_reply_t;
|
||||||
|
|
||||||
/* AUTH_COOKIE_REQ */
|
/* AUTH_COOKIE_REQ */
|
||||||
struct __attribute__ ((__packed__)) cmd_auth_cookie_req_st {
|
struct __attribute__ ((__packed__)) cmd_auth_cookie_req_st {
|
||||||
uint8_t cookie[COOKIE_SIZE];
|
uint8_t cookie[COOKIE_SIZE];
|
||||||
@@ -47,10 +57,25 @@ struct __attribute__ ((__packed__)) cmd_auth_reply_st {
|
|||||||
char user[MAX_USERNAME_SIZE];
|
char user[MAX_USERNAME_SIZE];
|
||||||
};
|
};
|
||||||
|
|
||||||
int auth_cookie(worker_st *ws, void* cookie, size_t cookie_size);
|
/* RESUME_FETCH_REQ + RESUME_DELETE_REQ */
|
||||||
|
struct __attribute__ ((__packed__)) cmd_resume_fetch_req_st {
|
||||||
|
uint8_t session_id_size;
|
||||||
|
uint8_t session_id[GNUTLS_MAX_SESSION_ID];
|
||||||
|
};
|
||||||
|
|
||||||
int get_auth_handler(worker_st *server);
|
/* RESUME_STORE_REQ */
|
||||||
int post_old_auth_handler(worker_st *server);
|
struct __attribute__ ((__packed__)) cmd_resume_store_req_st {
|
||||||
int post_new_auth_handler(worker_st *server);
|
uint8_t session_id_size;
|
||||||
|
uint8_t session_id[GNUTLS_MAX_SESSION_ID];
|
||||||
|
uint16_t session_data_size;
|
||||||
|
uint8_t session_data[MAX_SESSION_DATA_SIZE];
|
||||||
|
};
|
||||||
|
|
||||||
|
/* RESUME_FETCH_REP */
|
||||||
|
struct __attribute__ ((__packed__)) cmd_resume_fetch_reply_st {
|
||||||
|
uint8_t reply;
|
||||||
|
uint16_t session_data_size;
|
||||||
|
uint8_t session_data[MAX_SESSION_DATA_SIZE];
|
||||||
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
+171
@@ -575,4 +575,175 @@ static inline void list_splice_tail_init(struct list_head *list,
|
|||||||
n = list_entry(pos->member.next, typeof(*pos), member)
|
n = list_entry(pos->member.next, typeof(*pos), member)
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Double linked lists with a single pointer list head.
|
||||||
|
* Mostly useful for hash tables where the two pointer list head is
|
||||||
|
* too wasteful.
|
||||||
|
* You lose the ability to access the tail in O(1).
|
||||||
|
*/
|
||||||
|
|
||||||
|
struct hlist_head {
|
||||||
|
struct hlist_node *first;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct hlist_node {
|
||||||
|
struct hlist_node *next, **pprev;
|
||||||
|
};
|
||||||
|
|
||||||
|
#define HLIST_HEAD_INIT { .first = NULL }
|
||||||
|
#define HLIST_HEAD(name) struct hlist_head name = { .first = NULL }
|
||||||
|
#define INIT_HLIST_HEAD(ptr) ((ptr)->first = NULL)
|
||||||
|
static inline void INIT_HLIST_NODE(struct hlist_node *h)
|
||||||
|
{
|
||||||
|
h->next = NULL;
|
||||||
|
h->pprev = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline int hlist_unhashed(const struct hlist_node *h)
|
||||||
|
{
|
||||||
|
return !h->pprev;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline int hlist_empty(const struct hlist_head *h)
|
||||||
|
{
|
||||||
|
return !h->first;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void __hlist_del(struct hlist_node *n)
|
||||||
|
{
|
||||||
|
struct hlist_node *next = n->next;
|
||||||
|
struct hlist_node **pprev = n->pprev;
|
||||||
|
*pprev = next;
|
||||||
|
if (next)
|
||||||
|
next->pprev = pprev;
|
||||||
|
}
|
||||||
|
|
||||||
|
#define LIST_POISON1 NULL
|
||||||
|
#define LIST_POISON2 NULL
|
||||||
|
|
||||||
|
static inline void hlist_del(struct hlist_node *n)
|
||||||
|
{
|
||||||
|
__hlist_del(n);
|
||||||
|
n->next = LIST_POISON1;
|
||||||
|
n->pprev = LIST_POISON2;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void hlist_del_init(struct hlist_node *n)
|
||||||
|
{
|
||||||
|
if (!hlist_unhashed(n)) {
|
||||||
|
__hlist_del(n);
|
||||||
|
INIT_HLIST_NODE(n);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void hlist_add_head(struct hlist_node *n, struct hlist_head *h)
|
||||||
|
{
|
||||||
|
struct hlist_node *first = h->first;
|
||||||
|
n->next = first;
|
||||||
|
if (first)
|
||||||
|
first->pprev = &n->next;
|
||||||
|
h->first = n;
|
||||||
|
n->pprev = &h->first;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* next must be != NULL */
|
||||||
|
static inline void hlist_add_before(struct hlist_node *n,
|
||||||
|
struct hlist_node *next)
|
||||||
|
{
|
||||||
|
n->pprev = next->pprev;
|
||||||
|
n->next = next;
|
||||||
|
next->pprev = &n->next;
|
||||||
|
*(n->pprev) = n;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void hlist_add_after(struct hlist_node *n,
|
||||||
|
struct hlist_node *next)
|
||||||
|
{
|
||||||
|
next->next = n->next;
|
||||||
|
n->next = next;
|
||||||
|
next->pprev = &n->next;
|
||||||
|
|
||||||
|
if(next->next)
|
||||||
|
next->next->pprev = &next->next;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* after that we'll appear to be on some hlist and hlist_del will work */
|
||||||
|
static inline void hlist_add_fake(struct hlist_node *n)
|
||||||
|
{
|
||||||
|
n->pprev = &n->next;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Move a list from one list head to another. Fixup the pprev
|
||||||
|
* reference of the first entry if it exists.
|
||||||
|
*/
|
||||||
|
static inline void hlist_move_list(struct hlist_head *old,
|
||||||
|
struct hlist_head *new)
|
||||||
|
{
|
||||||
|
new->first = old->first;
|
||||||
|
if (new->first)
|
||||||
|
new->first->pprev = &new->first;
|
||||||
|
old->first = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
#define hlist_entry(ptr, type, member) container_of(ptr,type,member)
|
||||||
|
|
||||||
|
#define hlist_for_each(pos, head) \
|
||||||
|
for (pos = (head)->first; pos ; pos = pos->next)
|
||||||
|
|
||||||
|
#define hlist_for_each_safe(pos, n, head) \
|
||||||
|
for (pos = (head)->first; pos && ({ n = pos->next; 1; }); \
|
||||||
|
pos = n)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* hlist_for_each_entry - iterate over list of given type
|
||||||
|
* @tpos: the type * to use as a loop cursor.
|
||||||
|
* @pos: the &struct hlist_node to use as a loop cursor.
|
||||||
|
* @head: the head for your list.
|
||||||
|
* @member: the name of the hlist_node within the struct.
|
||||||
|
*/
|
||||||
|
#define hlist_for_each_entry(tpos, pos, head, member) \
|
||||||
|
for (pos = (head)->first; \
|
||||||
|
pos && \
|
||||||
|
({ tpos = hlist_entry(pos, typeof(*tpos), member); 1;}); \
|
||||||
|
pos = pos->next)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* hlist_for_each_entry_continue - iterate over a hlist continuing after current point
|
||||||
|
* @tpos: the type * to use as a loop cursor.
|
||||||
|
* @pos: the &struct hlist_node to use as a loop cursor.
|
||||||
|
* @member: the name of the hlist_node within the struct.
|
||||||
|
*/
|
||||||
|
#define hlist_for_each_entry_continue(tpos, pos, member) \
|
||||||
|
for (pos = (pos)->next; \
|
||||||
|
pos && \
|
||||||
|
({ tpos = hlist_entry(pos, typeof(*tpos), member); 1;}); \
|
||||||
|
pos = pos->next)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* hlist_for_each_entry_from - iterate over a hlist continuing from current point
|
||||||
|
* @tpos: the type * to use as a loop cursor.
|
||||||
|
* @pos: the &struct hlist_node to use as a loop cursor.
|
||||||
|
* @member: the name of the hlist_node within the struct.
|
||||||
|
*/
|
||||||
|
#define hlist_for_each_entry_from(tpos, pos, member) \
|
||||||
|
for (; pos && \
|
||||||
|
({ tpos = hlist_entry(pos, typeof(*tpos), member); 1;}); \
|
||||||
|
pos = pos->next)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* hlist_for_each_entry_safe - iterate over list of given type safe against removal of list entry
|
||||||
|
* @tpos: the type * to use as a loop cursor.
|
||||||
|
* @pos: the &struct hlist_node to use as a loop cursor.
|
||||||
|
* @n: another &struct hlist_node to use as temporary storage
|
||||||
|
* @head: the head for your list.
|
||||||
|
* @member: the name of the hlist_node within the struct.
|
||||||
|
*/
|
||||||
|
#define hlist_for_each_entry_safe(tpos, pos, n, head, member) \
|
||||||
|
for (pos = (head)->first; \
|
||||||
|
pos && ({ n = pos->next; 1; }) && \
|
||||||
|
({ tpos = hlist_entry(pos, typeof(*tpos), member); 1;}); \
|
||||||
|
pos = n)
|
||||||
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
+76
-28
@@ -34,15 +34,17 @@
|
|||||||
#include <gnutls/gnutls.h>
|
#include <gnutls/gnutls.h>
|
||||||
#include <gnutls/crypto.h>
|
#include <gnutls/crypto.h>
|
||||||
#include <tlslib.h>
|
#include <tlslib.h>
|
||||||
#include <worker-auth.h>
|
#include "ipc.h"
|
||||||
|
|
||||||
#include <vpn.h>
|
#include <vpn.h>
|
||||||
#include <cookies.h>
|
#include <cookies.h>
|
||||||
#include <tun.h>
|
#include <tun.h>
|
||||||
|
#include <main.h>
|
||||||
#include <list.h>
|
#include <list.h>
|
||||||
#include "pam.h"
|
#include "pam.h"
|
||||||
|
|
||||||
static int send_auth_reply(cmd_auth_reply_t r, struct proc_list_st* proc, struct lease_st* lease)
|
static int send_auth_reply(main_server_st* s, struct proc_list_st* proc,
|
||||||
|
cmd_auth_reply_t r, struct lease_st* lease)
|
||||||
{
|
{
|
||||||
struct iovec iov[6];
|
struct iovec iov[6];
|
||||||
uint8_t cmd[2];
|
uint8_t cmd[2];
|
||||||
@@ -96,14 +98,13 @@ static int send_auth_reply(cmd_auth_reply_t r, struct proc_list_st* proc, struct
|
|||||||
return(sendmsg(proc->fd, &hdr, 0));
|
return(sendmsg(proc->fd, &hdr, 0));
|
||||||
}
|
}
|
||||||
|
|
||||||
static int handle_auth_cookie_req(const struct cfg_st *config, struct tun_st *tun,
|
static int handle_auth_cookie_req(main_server_st* s, struct proc_list_st* proc,
|
||||||
const struct cmd_auth_cookie_req_st * req, struct lease_st **lease,
|
const struct cmd_auth_cookie_req_st * req, struct lease_st **lease)
|
||||||
struct proc_list_st* proc)
|
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
struct stored_cookie_st sc;
|
struct stored_cookie_st sc;
|
||||||
|
|
||||||
ret = retrieve_cookie(config, req->cookie, sizeof(req->cookie), &sc);
|
ret = retrieve_cookie(s->config, req->cookie, sizeof(req->cookie), &sc);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@@ -114,7 +115,7 @@ struct stored_cookie_st sc;
|
|||||||
memcpy(proc->username, sc.username, sizeof(proc->username));
|
memcpy(proc->username, sc.username, sizeof(proc->username));
|
||||||
memcpy(proc->session_id, sc.session_id, sizeof(proc->session_id));
|
memcpy(proc->session_id, sc.session_id, sizeof(proc->session_id));
|
||||||
|
|
||||||
ret = open_tun(config, tun, lease);
|
ret = open_tun(s->config, s->tun, lease);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
ret = -1; /* sorry */
|
ret = -1; /* sorry */
|
||||||
|
|
||||||
@@ -122,7 +123,7 @@ struct stored_cookie_st sc;
|
|||||||
}
|
}
|
||||||
|
|
||||||
static
|
static
|
||||||
int generate_and_store_vals(const struct cfg_st* config, struct proc_list_st* proc)
|
int generate_and_store_vals(main_server_st *s, struct proc_list_st* proc)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
struct stored_cookie_st sc;
|
struct stored_cookie_st sc;
|
||||||
@@ -135,51 +136,50 @@ struct stored_cookie_st sc;
|
|||||||
return -2;
|
return -2;
|
||||||
|
|
||||||
memset(&sc, 0, sizeof(sc));
|
memset(&sc, 0, sizeof(sc));
|
||||||
sc.expiration = time(0) + config->cookie_validity;
|
sc.expiration = time(0) + s->config->cookie_validity;
|
||||||
|
|
||||||
memcpy(sc.username, proc->username, sizeof(sc.username));
|
memcpy(sc.username, proc->username, sizeof(sc.username));
|
||||||
memcpy(sc.session_id, proc->session_id, sizeof(sc.session_id));
|
memcpy(sc.session_id, proc->session_id, sizeof(sc.session_id));
|
||||||
|
|
||||||
ret = store_cookie(config, proc->cookie, sizeof(proc->cookie), &sc);
|
ret = store_cookie(s->config, proc->cookie, sizeof(proc->cookie), &sc);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int handle_auth_req(const struct cfg_st *config, struct tun_st *tun,
|
static int handle_auth_req(main_server_st *s, struct proc_list_st* proc,
|
||||||
const struct cmd_auth_req_st * req, struct lease_st **lease,
|
const struct cmd_auth_req_st * req, struct lease_st **lease)
|
||||||
char username[MAX_USERNAME_SIZE])
|
|
||||||
{
|
{
|
||||||
int ret = -1;
|
int ret = -1;
|
||||||
unsigned username_set = 0;
|
unsigned username_set = 0;
|
||||||
|
|
||||||
if (config->auth_types & AUTH_TYPE_PAM) {
|
if (req->user_pass_present != 0 && s->config->auth_types & AUTH_TYPE_PAM) {
|
||||||
ret = pam_auth_user(req->user, req->pass);
|
ret = pam_auth_user(req->user, req->pass);
|
||||||
if (ret != 0)
|
if (ret != 0)
|
||||||
ret = -1;
|
ret = -1;
|
||||||
|
|
||||||
memcpy(username, req->user, MAX_USERNAME_SIZE);
|
memcpy(proc->username, req->user, MAX_USERNAME_SIZE);
|
||||||
username_set = 1;
|
username_set = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (config->auth_types & AUTH_TYPE_CERTIFICATE) {
|
if (s->config->auth_types & AUTH_TYPE_CERTIFICATE) {
|
||||||
if (req->tls_auth_ok != 0) {
|
if (req->tls_auth_ok != 0) {
|
||||||
ret = 0;
|
ret = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (username_set == 0)
|
if (username_set == 0)
|
||||||
memcpy(username, req->cert_user, MAX_USERNAME_SIZE);
|
memcpy(proc->username, req->cert_user, MAX_USERNAME_SIZE);
|
||||||
else {
|
else {
|
||||||
if (strcmp(username, req->cert_user) != 0) {
|
if (strcmp(proc->username, req->cert_user) != 0) {
|
||||||
syslog(LOG_INFO, "User '%s' presented a certificate from user '%s'", username, req->cert_user);
|
syslog(LOG_INFO, "User '%s' presented a certificate from user '%s'", proc->username, req->cert_user);
|
||||||
ret = -1;
|
ret = -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ret == 0) { /* open tun */
|
if (ret == 0) { /* open tun */
|
||||||
ret = open_tun(config, tun, lease);
|
ret = open_tun(s->config, s->tun, lease);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
ret = -1; /* sorry */
|
ret = -1; /* sorry */
|
||||||
}
|
}
|
||||||
@@ -187,17 +187,19 @@ unsigned username_set = 0;
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
int handle_commands(const struct cfg_st *config, struct tun_st *tun,
|
int handle_commands(main_server_st *s, struct proc_list_st* proc)
|
||||||
struct proc_list_st* proc)
|
|
||||||
{
|
{
|
||||||
struct iovec iov[2];
|
struct iovec iov[2];
|
||||||
char buf[128];
|
char buf[128];
|
||||||
|
int e;
|
||||||
uint8_t cmd;
|
uint8_t cmd;
|
||||||
struct msghdr hdr;
|
struct msghdr hdr;
|
||||||
struct lease_st *lease;
|
struct lease_st *lease;
|
||||||
union {
|
union {
|
||||||
struct cmd_auth_req_st auth;
|
struct cmd_auth_req_st auth;
|
||||||
struct cmd_auth_cookie_req_st cauth;
|
struct cmd_auth_cookie_req_st cauth;
|
||||||
|
struct cmd_resume_store_req_st sresume;
|
||||||
|
struct cmd_resume_fetch_req_st fresume;
|
||||||
} cmd_data;
|
} cmd_data;
|
||||||
int ret, cmd_data_len;
|
int ret, cmd_data_len;
|
||||||
const char* peer_ip;
|
const char* peer_ip;
|
||||||
@@ -218,7 +220,8 @@ int handle_commands(const struct cfg_st *config, struct tun_st *tun,
|
|||||||
|
|
||||||
ret = recvmsg( proc->fd, &hdr, 0);
|
ret = recvmsg( proc->fd, &hdr, 0);
|
||||||
if (ret == -1) {
|
if (ret == -1) {
|
||||||
syslog(LOG_ERR, "Cannot obtain data from command socket (pid: %d, peer: %s).", proc->pid, peer_ip);
|
e = errno;
|
||||||
|
syslog(LOG_ERR, "Cannot obtain data from command socket (pid: %d, peer: %s): %s", proc->pid, peer_ip, strerror(e));
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -229,6 +232,51 @@ int handle_commands(const struct cfg_st *config, struct tun_st *tun,
|
|||||||
cmd_data_len = ret - 1;
|
cmd_data_len = ret - 1;
|
||||||
|
|
||||||
switch(cmd) {
|
switch(cmd) {
|
||||||
|
case RESUME_STORE_REQ:
|
||||||
|
if (cmd_data_len != sizeof(cmd_data.sresume)) {
|
||||||
|
syslog(LOG_ERR, "Error in received message length (pid: %d, peer: %s).", proc->pid, peer_ip);
|
||||||
|
return -2;
|
||||||
|
}
|
||||||
|
ret = handle_resume_store_req(s, proc, &cmd_data.sresume);
|
||||||
|
if (ret < 0) {
|
||||||
|
syslog(LOG_DEBUG, "Could not store resumption data (pid: %d, peer: %s).", proc->pid, peer_ip);
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
case RESUME_DELETE_REQ:
|
||||||
|
if (cmd_data_len != sizeof(cmd_data.fresume)) {
|
||||||
|
syslog(LOG_ERR, "Error in received message length (pid: %d, peer: %s).", proc->pid, peer_ip);
|
||||||
|
return -2;
|
||||||
|
}
|
||||||
|
ret = handle_resume_delete_req(s, proc, &cmd_data.fresume);
|
||||||
|
if (ret < 0) {
|
||||||
|
syslog(LOG_DEBUG, "Could not delete resumption data (pid: %d, peer: %s).", proc->pid, peer_ip);
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
case RESUME_FETCH_REQ: {
|
||||||
|
struct cmd_resume_fetch_reply_st reply;
|
||||||
|
|
||||||
|
if (cmd_data_len != sizeof(cmd_data.fresume)) {
|
||||||
|
syslog(LOG_ERR, "Error in received message length (pid: %d, peer: %s).", proc->pid, peer_ip);
|
||||||
|
return -2;
|
||||||
|
}
|
||||||
|
ret = handle_resume_fetch_req(s, proc, &cmd_data.fresume, &reply);
|
||||||
|
if (ret < 0) {
|
||||||
|
syslog(LOG_DEBUG, "Could not fetch resumption data (pid: %d, peer: %s).", proc->pid, peer_ip);
|
||||||
|
ret = send_resume_fetch_reply(s, proc, REP_RESUME_FAILED, NULL);
|
||||||
|
} else
|
||||||
|
ret = send_resume_fetch_reply(s, proc, REP_RESUME_OK, &reply);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ret < 0) {
|
||||||
|
syslog(LOG_ERR, "Could not send reply cmd (pid: %d, peer: %s).", proc->pid, peer_ip);
|
||||||
|
return -2;
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
case AUTH_REQ:
|
case AUTH_REQ:
|
||||||
case AUTH_COOKIE_REQ:
|
case AUTH_COOKIE_REQ:
|
||||||
|
|
||||||
@@ -238,26 +286,26 @@ int handle_commands(const struct cfg_st *config, struct tun_st *tun,
|
|||||||
return -2;
|
return -2;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = handle_auth_req(config, tun, &cmd_data.auth, &lease, proc->username);
|
ret = handle_auth_req(s, proc, &cmd_data.auth, &lease);
|
||||||
} else {
|
} else {
|
||||||
if (cmd_data_len != sizeof(cmd_data.cauth)) {
|
if (cmd_data_len != sizeof(cmd_data.cauth)) {
|
||||||
syslog(LOG_ERR, "Error in received message length (pid: %d, peer: %s).", proc->pid, peer_ip);
|
syslog(LOG_ERR, "Error in received message length (pid: %d, peer: %s).", proc->pid, peer_ip);
|
||||||
return -2;
|
return -2;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = handle_auth_cookie_req(config, tun, &cmd_data.cauth, &lease, proc);
|
ret = handle_auth_cookie_req(s, proc, &cmd_data.cauth, &lease);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ret == 0) {
|
if (ret == 0) {
|
||||||
if (cmd == AUTH_REQ) {
|
if (cmd == AUTH_REQ) {
|
||||||
/* generate and store cookie */
|
/* generate and store cookie */
|
||||||
ret = generate_and_store_vals(config, proc);
|
ret = generate_and_store_vals(s, proc);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
return -2;
|
return -2;
|
||||||
}
|
}
|
||||||
|
|
||||||
syslog(LOG_INFO, "User '%s' authenticated", proc->username);
|
syslog(LOG_INFO, "User '%s' authenticated", proc->username);
|
||||||
ret = send_auth_reply(REP_AUTH_OK, proc, lease);
|
ret = send_auth_reply(s, proc, REP_AUTH_OK, lease);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
syslog(LOG_ERR, "Could not send reply cmd (pid: %d, peer: %s).", proc->pid, peer_ip);
|
syslog(LOG_ERR, "Could not send reply cmd (pid: %d, peer: %s).", proc->pid, peer_ip);
|
||||||
return -2;
|
return -2;
|
||||||
@@ -270,7 +318,7 @@ int handle_commands(const struct cfg_st *config, struct tun_st *tun,
|
|||||||
lease->fd = -1;
|
lease->fd = -1;
|
||||||
} else {
|
} else {
|
||||||
syslog(LOG_INFO, "Failed authentication attempt for user '%s'", proc->username);
|
syslog(LOG_INFO, "Failed authentication attempt for user '%s'", proc->username);
|
||||||
ret = send_auth_reply( REP_AUTH_FAILED, proc, NULL);
|
ret = send_auth_reply( s, proc, REP_AUTH_FAILED, NULL);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
syslog(LOG_ERR, "Could not send reply cmd (pid: %d, peer: %s).", proc->pid, peer_ip);
|
syslog(LOG_ERR, "Could not send reply cmd (pid: %d, peer: %s).", proc->pid, peer_ip);
|
||||||
return -2;
|
return -2;
|
||||||
|
|||||||
@@ -0,0 +1,165 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2013 Nikos Mavrogiannopoulos
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <config.h>
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/select.h>
|
||||||
|
#include <sys/wait.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <sys/socket.h>
|
||||||
|
#include <netdb.h>
|
||||||
|
#include <signal.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <sys/ioctl.h>
|
||||||
|
#include <gnutls/gnutls.h>
|
||||||
|
#include <gnutls/crypto.h>
|
||||||
|
#include <tlslib.h>
|
||||||
|
#include "ipc.h"
|
||||||
|
#include <hash.h>
|
||||||
|
#include <hash-pjw-bare.h>
|
||||||
|
|
||||||
|
#include <vpn.h>
|
||||||
|
#include <main.h>
|
||||||
|
#include <tlslib.h>
|
||||||
|
|
||||||
|
int send_resume_fetch_reply(main_server_st* s, struct proc_list_st * proc,
|
||||||
|
cmd_resume_reply_t r, struct cmd_resume_fetch_reply_st * reply)
|
||||||
|
{
|
||||||
|
struct iovec iov[3];
|
||||||
|
uint8_t cmd = RESUME_FETCH_REP;
|
||||||
|
struct msghdr hdr;
|
||||||
|
|
||||||
|
memset(&hdr, 0, sizeof(hdr));
|
||||||
|
|
||||||
|
iov[0].iov_base = &cmd;
|
||||||
|
iov[0].iov_len = 1;
|
||||||
|
hdr.msg_iovlen++;
|
||||||
|
|
||||||
|
iov[1].iov_base = reply;
|
||||||
|
iov[1].iov_len = sizeof(*reply);
|
||||||
|
hdr.msg_iovlen++;
|
||||||
|
|
||||||
|
iov[2].iov_base = reply;
|
||||||
|
iov[2].iov_len = sizeof(*reply);
|
||||||
|
hdr.msg_iovlen++;
|
||||||
|
|
||||||
|
hdr.msg_iov = iov;
|
||||||
|
|
||||||
|
return(sendmsg(proc->fd, &hdr, 0));
|
||||||
|
}
|
||||||
|
|
||||||
|
int handle_resume_delete_req(main_server_st* s, struct proc_list_st * proc,
|
||||||
|
const struct cmd_resume_fetch_req_st * req)
|
||||||
|
{
|
||||||
|
size_t key;
|
||||||
|
tls_cache_st* cache;
|
||||||
|
struct hlist_node *pos, *tmp;
|
||||||
|
key = hash_pjw_bare(req->session_id, req->session_id_size);
|
||||||
|
|
||||||
|
hash_for_each_possible_safe(s->tls_db->entry, cache, pos, tmp, list, key) {
|
||||||
|
if (req->session_id_size == cache->session_id_size &&
|
||||||
|
memcmp (req->session_id, cache->session_id, req->session_id_size) == 0) {
|
||||||
|
|
||||||
|
cache->session_data_size = 0;
|
||||||
|
cache->session_id_size = 0;
|
||||||
|
|
||||||
|
hash_del(&cache->list);
|
||||||
|
free(cache);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
static int ip_cmp(const struct sockaddr_storage *s1, const struct sockaddr_storage *s2, size_t n)
|
||||||
|
{
|
||||||
|
if (((struct sockaddr*)s1)->sa_family == AF_INET) {
|
||||||
|
return memcmp(SA_IN_P(s1), SA_IN_P(s2), sizeof(struct in_addr));
|
||||||
|
} else { /* inet6 */
|
||||||
|
return memcmp(SA_IN6_P(s1), SA_IN6_P(s2), sizeof(struct in6_addr));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int handle_resume_fetch_req(main_server_st* s, struct proc_list_st * proc,
|
||||||
|
const struct cmd_resume_fetch_req_st * req,
|
||||||
|
struct cmd_resume_fetch_reply_st * rep)
|
||||||
|
{
|
||||||
|
size_t key;
|
||||||
|
tls_cache_st* cache;
|
||||||
|
struct hlist_node *pos;
|
||||||
|
|
||||||
|
key = hash_pjw_bare(req->session_id, req->session_id_size);
|
||||||
|
rep->reply = REP_RESUME_FAILED;
|
||||||
|
|
||||||
|
hash_for_each_possible(s->tls_db->entry, cache, pos, list, key) {
|
||||||
|
if (req->session_id_size == cache->session_id_size &&
|
||||||
|
memcmp (req->session_id, cache->session_id, req->session_id_size) == 0) {
|
||||||
|
|
||||||
|
if (proc->remote_addr_len == cache->remote_addr_len &&
|
||||||
|
ip_cmp(&proc->remote_addr, &cache->remote_addr, proc->remote_addr_len) == 0) {
|
||||||
|
|
||||||
|
rep->reply = REP_RESUME_OK;
|
||||||
|
|
||||||
|
memcpy(rep->session_data, cache->session_data, cache->session_data_size);
|
||||||
|
rep->session_data_size = cache->session_data_size;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
int handle_resume_store_req(main_server_st* s, struct proc_list_st * proc,
|
||||||
|
const struct cmd_resume_store_req_st * req)
|
||||||
|
{
|
||||||
|
tls_cache_st* cache;
|
||||||
|
size_t key;
|
||||||
|
|
||||||
|
if (req->session_id_size > GNUTLS_MAX_SESSION_ID)
|
||||||
|
return -1;
|
||||||
|
if (req->session_data_size > MAX_SESSION_DATA_SIZE)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
key = hash_pjw_bare(req->session_id, req->session_id_size);
|
||||||
|
|
||||||
|
cache = malloc(sizeof(*cache));
|
||||||
|
if (cache == NULL)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
cache->session_id_size = req->session_id_size;
|
||||||
|
cache->session_data_size = req->session_data_size;
|
||||||
|
cache->remote_addr_len = proc->remote_addr_len;
|
||||||
|
|
||||||
|
memcpy(cache->session_id, req->session_id, req->session_id_size);
|
||||||
|
memcpy(cache->session_data, req->session_data, req->session_data_size);
|
||||||
|
memcpy(&cache->remote_addr, &proc->remote_addr, proc->remote_addr_len);
|
||||||
|
|
||||||
|
hash_add(s->tls_db->entry, &cache->list, key);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
+11
-2
@@ -34,8 +34,9 @@
|
|||||||
|
|
||||||
#include <gnutls/x509.h>
|
#include <gnutls/x509.h>
|
||||||
#include <tlslib.h>
|
#include <tlslib.h>
|
||||||
#include <worker-auth.h>
|
#include "ipc.h"
|
||||||
|
|
||||||
|
#include <main.h>
|
||||||
#include <vpn.h>
|
#include <vpn.h>
|
||||||
#include <cookies.h>
|
#include <cookies.h>
|
||||||
#include <tun.h>
|
#include <tun.h>
|
||||||
@@ -352,9 +353,12 @@ int main(int argc, char** argv)
|
|||||||
struct worker_st ws;
|
struct worker_st ws;
|
||||||
struct cfg_st config;
|
struct cfg_st config;
|
||||||
unsigned active_clients = 0;
|
unsigned active_clients = 0;
|
||||||
|
main_server_st s;
|
||||||
|
tls_cache_db_st* tls_db;
|
||||||
|
|
||||||
INIT_LIST_HEAD(&clist.list);
|
INIT_LIST_HEAD(&clist.list);
|
||||||
tun_st_init(&tun);
|
tun_st_init(&tun);
|
||||||
|
tls_cache_init(&config, &tls_db);
|
||||||
|
|
||||||
signal(SIGINT, handle_term);
|
signal(SIGINT, handle_term);
|
||||||
signal(SIGTERM, handle_term);
|
signal(SIGTERM, handle_term);
|
||||||
@@ -374,6 +378,11 @@ int main(int argc, char** argv)
|
|||||||
fprintf(stderr, "Error in arguments\n");
|
fprintf(stderr, "Error in arguments\n");
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
s.config = &config;
|
||||||
|
s.tun = &tun;
|
||||||
|
s.tls_db = tls_db;
|
||||||
|
|
||||||
/* Listen to network ports */
|
/* Listen to network ports */
|
||||||
ret = listen_ports(&config, &llist, config.name, config.port, SOCK_STREAM);
|
ret = listen_ports(&config, &llist, config.name, config.port, SOCK_STREAM);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
@@ -562,7 +571,7 @@ fork_failed:
|
|||||||
ctmp = list_entry(pos, struct proc_list_st, list);
|
ctmp = list_entry(pos, struct proc_list_st, list);
|
||||||
|
|
||||||
if (FD_ISSET(ctmp->fd, &rd)) {
|
if (FD_ISSET(ctmp->fd, &rd)) {
|
||||||
ret = handle_commands(&config, &tun, ctmp);
|
ret = handle_commands(&s, ctmp);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
if (ret == -2) {
|
if (ret == -2) {
|
||||||
/* received a bad command from worker */
|
/* received a bad command from worker */
|
||||||
|
|||||||
+49
@@ -0,0 +1,49 @@
|
|||||||
|
#ifndef MAIN_H
|
||||||
|
# define MAIN_H
|
||||||
|
|
||||||
|
#include <vpn.h>
|
||||||
|
#include <tlslib.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/socket.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <net/if.h>
|
||||||
|
|
||||||
|
int cmd_parser (int argc, char **argv, struct cfg_st* config);
|
||||||
|
|
||||||
|
struct proc_list_st {
|
||||||
|
struct list_head list;
|
||||||
|
int fd;
|
||||||
|
pid_t pid;
|
||||||
|
struct sockaddr_storage remote_addr; /* peer address */
|
||||||
|
socklen_t remote_addr_len;
|
||||||
|
char username[MAX_USERNAME_SIZE]; /* the owner */
|
||||||
|
uint8_t cookie[COOKIE_SIZE]; /* the cookie associate with the session */
|
||||||
|
uint8_t session_id[GNUTLS_MAX_SESSION_ID];
|
||||||
|
|
||||||
|
/* the tun lease this process has */
|
||||||
|
struct lease_st* lease;
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef struct main_server_st {
|
||||||
|
struct cfg_st *config;
|
||||||
|
struct tun_st *tun;
|
||||||
|
tls_cache_db_st *tls_db;
|
||||||
|
} main_server_st;
|
||||||
|
|
||||||
|
int handle_commands(main_server_st *s, struct proc_list_st* cur);
|
||||||
|
|
||||||
|
|
||||||
|
int send_resume_fetch_reply(main_server_st* s, struct proc_list_st* proc,
|
||||||
|
cmd_resume_reply_t r, struct cmd_resume_fetch_reply_st * reply);
|
||||||
|
|
||||||
|
int handle_resume_delete_req(main_server_st* s, struct proc_list_st* proc,
|
||||||
|
const struct cmd_resume_fetch_req_st * req);
|
||||||
|
|
||||||
|
int handle_resume_fetch_req(main_server_st* s, struct proc_list_st* proc,
|
||||||
|
const struct cmd_resume_fetch_req_st * req,
|
||||||
|
struct cmd_resume_fetch_reply_st * rep);
|
||||||
|
|
||||||
|
int handle_resume_store_req(main_server_st* s, struct proc_list_st *proc,
|
||||||
|
const struct cmd_resume_store_req_st * req);
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -115,3 +115,16 @@ void tls_fatal_close(gnutls_session_t session,
|
|||||||
gnutls_alert_send(session, GNUTLS_AL_FATAL, a);
|
gnutls_alert_send(session, GNUTLS_AL_FATAL, a);
|
||||||
gnutls_deinit(session);
|
gnutls_deinit(session);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void tls_cache_init(struct cfg_st* config, tls_cache_db_st** _db)
|
||||||
|
{
|
||||||
|
tls_cache_db_st * db;
|
||||||
|
|
||||||
|
db = malloc(sizeof(*db));
|
||||||
|
if (db == NULL)
|
||||||
|
exit(1);
|
||||||
|
|
||||||
|
hash_init(db->entry);
|
||||||
|
|
||||||
|
*_db = db;
|
||||||
|
}
|
||||||
|
|||||||
@@ -2,6 +2,10 @@
|
|||||||
#define TLS_H
|
#define TLS_H
|
||||||
|
|
||||||
#include <gnutls/gnutls.h>
|
#include <gnutls/gnutls.h>
|
||||||
|
#include <vpn.h>
|
||||||
|
#include <hashtable.h>
|
||||||
|
|
||||||
|
#define MAX_SESSION_DATA_SIZE (4*1024)
|
||||||
|
|
||||||
#define tls_puts(s, str) tls_send(s, str, sizeof(str)-1)
|
#define tls_puts(s, str) tls_send(s, str, sizeof(str)-1)
|
||||||
|
|
||||||
@@ -28,4 +32,29 @@ void tls_close(gnutls_session_t session);
|
|||||||
void tls_fatal_close(gnutls_session_t session,
|
void tls_fatal_close(gnutls_session_t session,
|
||||||
gnutls_alert_description_t a);
|
gnutls_alert_description_t a);
|
||||||
|
|
||||||
|
#define MAX_SESSION_DATA_SIZE (4*1024)
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
/* does not allow resumption from different address
|
||||||
|
* than the original */
|
||||||
|
struct sockaddr_storage remote_addr;
|
||||||
|
socklen_t remote_addr_len;
|
||||||
|
|
||||||
|
char session_id[GNUTLS_MAX_SESSION_ID];
|
||||||
|
unsigned int session_id_size;
|
||||||
|
|
||||||
|
char session_data[MAX_SESSION_DATA_SIZE];
|
||||||
|
unsigned int session_data_size;
|
||||||
|
|
||||||
|
struct hlist_node list;
|
||||||
|
} tls_cache_st;
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
DECLARE_HASHTABLE(entry, 7);
|
||||||
|
} tls_cache_db_st;
|
||||||
|
|
||||||
|
void tls_cache_init(struct cfg_st* config, tls_cache_db_st** db);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -143,25 +143,6 @@ const char *human_addr(const struct sockaddr *sa, socklen_t salen,
|
|||||||
void __attribute__ ((format(printf, 3, 4)))
|
void __attribute__ ((format(printf, 3, 4)))
|
||||||
oclog(const worker_st * server, int priority, const char *fmt, ...);
|
oclog(const worker_st * server, int priority, const char *fmt, ...);
|
||||||
|
|
||||||
int cmd_parser (int argc, char **argv, struct cfg_st* config);
|
|
||||||
|
|
||||||
struct proc_list_st {
|
|
||||||
struct list_head list;
|
|
||||||
int fd;
|
|
||||||
pid_t pid;
|
|
||||||
struct sockaddr_storage remote_addr; /* peer address */
|
|
||||||
socklen_t remote_addr_len;
|
|
||||||
char username[MAX_USERNAME_SIZE]; /* the owner */
|
|
||||||
uint8_t cookie[COOKIE_SIZE]; /* the cookie associate with the session */
|
|
||||||
uint8_t session_id[GNUTLS_MAX_SESSION_ID];
|
|
||||||
|
|
||||||
/* the tun lease this process has */
|
|
||||||
struct lease_st* lease;
|
|
||||||
};
|
|
||||||
|
|
||||||
int handle_commands(const struct cfg_st *config, struct tun_st *tun,
|
|
||||||
struct proc_list_st* proc);
|
|
||||||
|
|
||||||
/* Helper casts */
|
/* Helper casts */
|
||||||
#define SA_IN_P(p) (&((struct sockaddr_in *)(p))->sin_addr)
|
#define SA_IN_P(p) (&((struct sockaddr_in *)(p))->sin_addr)
|
||||||
#define SA_IN_U8_P(p) ((uint8_t*)(&((struct sockaddr_in *)(p))->sin_addr))
|
#define SA_IN_U8_P(p) ((uint8_t*)(&((struct sockaddr_in *)(p))->sin_addr))
|
||||||
|
|||||||
+2
-1
@@ -34,7 +34,8 @@
|
|||||||
#include <limits.h>
|
#include <limits.h>
|
||||||
|
|
||||||
#include <vpn.h>
|
#include <vpn.h>
|
||||||
#include <worker-auth.h>
|
#include "ipc.h"
|
||||||
|
#include <worker.h>
|
||||||
#include <cookies.h>
|
#include <cookies.h>
|
||||||
#include <tlslib.h>
|
#include <tlslib.h>
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,236 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2013 Nikos Mavrogiannopoulos
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <config.h>
|
||||||
|
|
||||||
|
#include <gnutls/gnutls.h>
|
||||||
|
#include <gnutls/crypto.h>
|
||||||
|
#include <gnutls/x509.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdarg.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <limits.h>
|
||||||
|
|
||||||
|
#include <vpn.h>
|
||||||
|
#include "ipc.h"
|
||||||
|
#include <cookies.h>
|
||||||
|
#include <tlslib.h>
|
||||||
|
|
||||||
|
|
||||||
|
static int send_resume_fetch_req(worker_st * ws, const struct cmd_resume_fetch_req_st* r,
|
||||||
|
int delete)
|
||||||
|
{
|
||||||
|
struct iovec iov[2];
|
||||||
|
uint8_t cmd;
|
||||||
|
struct msghdr hdr;
|
||||||
|
|
||||||
|
memset(&hdr, 0, sizeof(hdr));
|
||||||
|
|
||||||
|
if (delete != 0)
|
||||||
|
cmd = RESUME_DELETE_REQ;
|
||||||
|
else
|
||||||
|
cmd = RESUME_FETCH_REQ;
|
||||||
|
|
||||||
|
iov[0].iov_base = &cmd;
|
||||||
|
iov[0].iov_len = 1;
|
||||||
|
|
||||||
|
iov[1].iov_base = (void*)r;
|
||||||
|
iov[1].iov_len = sizeof(*r);
|
||||||
|
|
||||||
|
hdr.msg_iov = iov;
|
||||||
|
hdr.msg_iovlen = 2;
|
||||||
|
|
||||||
|
return(sendmsg(ws->cmd_fd, &hdr, 0));
|
||||||
|
}
|
||||||
|
|
||||||
|
static int send_resume_store_req(worker_st * ws, const struct cmd_resume_store_req_st* r)
|
||||||
|
{
|
||||||
|
struct iovec iov[2];
|
||||||
|
uint8_t cmd;
|
||||||
|
struct msghdr hdr;
|
||||||
|
|
||||||
|
memset(&hdr, 0, sizeof(hdr));
|
||||||
|
|
||||||
|
cmd = RESUME_STORE_REQ;
|
||||||
|
|
||||||
|
iov[0].iov_base = &cmd;
|
||||||
|
iov[0].iov_len = 1;
|
||||||
|
|
||||||
|
iov[1].iov_base = (void*)r;
|
||||||
|
iov[1].iov_len = sizeof(*r);
|
||||||
|
|
||||||
|
hdr.msg_iov = iov;
|
||||||
|
hdr.msg_iovlen = 2;
|
||||||
|
|
||||||
|
return(sendmsg(ws->cmd_fd, &hdr, 0));
|
||||||
|
}
|
||||||
|
|
||||||
|
static int recv_resume_fetch_reply(worker_st *ws, struct cmd_resume_fetch_reply_st* resp)
|
||||||
|
{
|
||||||
|
struct iovec iov[2];
|
||||||
|
uint8_t cmd = 0;
|
||||||
|
struct msghdr hdr;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
iov[0].iov_base = &cmd;
|
||||||
|
iov[0].iov_len = 1;
|
||||||
|
|
||||||
|
iov[1].iov_base = resp;
|
||||||
|
iov[1].iov_len = sizeof(*resp);
|
||||||
|
|
||||||
|
memset(&hdr, 0, sizeof(hdr));
|
||||||
|
hdr.msg_iov = iov;
|
||||||
|
hdr.msg_iovlen = 2;
|
||||||
|
|
||||||
|
ret = recvmsg( ws->cmd_fd, &hdr, 0);
|
||||||
|
if (ret < sizeof(*resp)+1) {
|
||||||
|
oclog(ws, LOG_ERR, "Received incorrect data (%d, expected %d) from main", ret, (int)sizeof(*resp)+1);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (cmd != RESUME_FETCH_REP) {
|
||||||
|
oclog(ws, LOG_ERR, "Received unexpected response (%d, expected %d) from main", (int)cmd, (int)RESUME_FETCH_REP);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch(resp->reply) {
|
||||||
|
case REP_RESUME_OK:
|
||||||
|
return 0;
|
||||||
|
default:
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* sends an authentication request to main thread and waits for
|
||||||
|
* a reply.
|
||||||
|
* Returns 0 on success.
|
||||||
|
*/
|
||||||
|
static gnutls_datum_t resume_db_fetch(void *dbf, gnutls_datum_t key)
|
||||||
|
{
|
||||||
|
worker_st *ws = dbf;
|
||||||
|
struct cmd_resume_fetch_req_st areq;
|
||||||
|
struct cmd_resume_fetch_reply_st *arep;
|
||||||
|
gnutls_datum_t r = { NULL, 0 };
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
if (key.size > GNUTLS_MAX_SESSION_ID) {
|
||||||
|
oclog(ws, LOG_DEBUG, "Session ID size exceeds the maximum %u", key.size);
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
areq.session_id_size = key.size;
|
||||||
|
memcpy(areq.session_id, key.data, key.size);
|
||||||
|
|
||||||
|
oclog(ws, LOG_DEBUG, "Sending resumption request");
|
||||||
|
|
||||||
|
ret = send_resume_fetch_req(ws, &areq, 0);
|
||||||
|
if (ret < 0)
|
||||||
|
return r;
|
||||||
|
|
||||||
|
arep = malloc(sizeof(*arep));
|
||||||
|
if (arep == NULL)
|
||||||
|
return r;
|
||||||
|
|
||||||
|
ret = recv_resume_fetch_reply(ws, arep);
|
||||||
|
if (ret < 0) {
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
r.data = gnutls_malloc(arep->session_data_size);
|
||||||
|
if (r.data == NULL)
|
||||||
|
goto cleanup;
|
||||||
|
|
||||||
|
r.size = arep->session_data_size;
|
||||||
|
memcpy(r.data, arep->session_data, r.size);
|
||||||
|
|
||||||
|
cleanup:
|
||||||
|
free(arep);
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int
|
||||||
|
resume_db_store (void *dbf, gnutls_datum_t key, gnutls_datum_t data)
|
||||||
|
{
|
||||||
|
worker_st *ws = dbf;
|
||||||
|
struct cmd_resume_store_req_st areq;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
if (data.size > MAX_SESSION_DATA_SIZE) {
|
||||||
|
oclog(ws, LOG_DEBUG, "Session data size exceeds the maximum %u", data.size);
|
||||||
|
return GNUTLS_E_DB_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (key.size > GNUTLS_MAX_SESSION_ID) {
|
||||||
|
oclog(ws, LOG_DEBUG, "Session ID size exceeds the maximum %u", key.size);
|
||||||
|
return GNUTLS_E_DB_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
areq.session_id_size = key.size;
|
||||||
|
areq.session_data_size = data.size;
|
||||||
|
|
||||||
|
memcpy(areq.session_id, key.data, key.size);
|
||||||
|
memcpy(areq.session_data, data.data, data.size);
|
||||||
|
|
||||||
|
ret = send_resume_store_req(ws, &areq);
|
||||||
|
if (ret < 0) {
|
||||||
|
return GNUTLS_E_DB_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* sends an authentication request to main thread and waits for
|
||||||
|
* a reply.
|
||||||
|
* Returns 0 on success.
|
||||||
|
*/
|
||||||
|
static int resume_db_delete(void *dbf, gnutls_datum_t key)
|
||||||
|
{
|
||||||
|
worker_st *ws = dbf;
|
||||||
|
struct cmd_resume_fetch_req_st areq;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
if (key.size > GNUTLS_MAX_SESSION_ID) {
|
||||||
|
oclog(ws, LOG_DEBUG, "Session ID size exceeds the maximum %u", key.size);
|
||||||
|
return GNUTLS_E_DB_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
areq.session_id_size = key.size;
|
||||||
|
memcpy(areq.session_id, key.data, key.size);
|
||||||
|
|
||||||
|
oclog(ws, LOG_DEBUG, "Sending resumption request");
|
||||||
|
|
||||||
|
ret = send_resume_fetch_req(ws, &areq, 1);
|
||||||
|
if (ret < 0)
|
||||||
|
return GNUTLS_E_DB_ERROR;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void set_resume_db_funcs(gnutls_session_t session)
|
||||||
|
{
|
||||||
|
gnutls_db_set_retrieve_function (session, resume_db_fetch);
|
||||||
|
gnutls_db_set_remove_function (session, resume_db_delete);
|
||||||
|
gnutls_db_set_store_function (session, resume_db_store);
|
||||||
|
}
|
||||||
+4
-2
@@ -42,8 +42,9 @@
|
|||||||
#include <time.h>
|
#include <time.h>
|
||||||
|
|
||||||
#include <vpn.h>
|
#include <vpn.h>
|
||||||
#include <worker-auth.h>
|
#include "ipc.h"
|
||||||
#include <cookies.h>
|
#include <cookies.h>
|
||||||
|
#include <worker.h>
|
||||||
#include <tlslib.h>
|
#include <tlslib.h>
|
||||||
|
|
||||||
#include <http-parser/http_parser.h>
|
#include <http-parser/http_parser.h>
|
||||||
@@ -283,7 +284,6 @@ gnutls_datum_t sid = { ws->session_id, sizeof(ws->session_id) };
|
|||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
ret =
|
ret =
|
||||||
gnutls_credentials_set(session, GNUTLS_CRD_CERTIFICATE,
|
gnutls_credentials_set(session, GNUTLS_CRD_CERTIFICATE,
|
||||||
ws->creds->xcred);
|
ws->creds->xcred);
|
||||||
@@ -342,7 +342,9 @@ void vpn_server(struct worker_st* ws)
|
|||||||
|
|
||||||
gnutls_certificate_server_set_request(session, ws->config->cert_req);
|
gnutls_certificate_server_set_request(session, ws->config->cert_req);
|
||||||
gnutls_transport_set_ptr(session, (gnutls_transport_ptr_t) (long)ws->conn_fd);
|
gnutls_transport_set_ptr(session, (gnutls_transport_ptr_t) (long)ws->conn_fd);
|
||||||
|
set_resume_db_funcs(session);
|
||||||
gnutls_session_set_ptr(session, ws);
|
gnutls_session_set_ptr(session, ws);
|
||||||
|
gnutls_db_set_ptr (session, ws);
|
||||||
|
|
||||||
do {
|
do {
|
||||||
ret = gnutls_handshake(session);
|
ret = gnutls_handshake(session);
|
||||||
|
|||||||
@@ -0,0 +1,22 @@
|
|||||||
|
#ifndef WORKER_H
|
||||||
|
#define WORKER_H
|
||||||
|
|
||||||
|
#include <config.h>
|
||||||
|
#include <syslog.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/socket.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <net/if.h>
|
||||||
|
#include <vpn.h>
|
||||||
|
#include <cookies.h>
|
||||||
|
#include <tlslib.h>
|
||||||
|
|
||||||
|
int auth_cookie(worker_st *ws, void* cookie, size_t cookie_size);
|
||||||
|
|
||||||
|
int get_auth_handler(worker_st *server);
|
||||||
|
int post_old_auth_handler(worker_st *server);
|
||||||
|
int post_new_auth_handler(worker_st *server);
|
||||||
|
|
||||||
|
void set_resume_db_funcs(gnutls_session_t);
|
||||||
|
|
||||||
|
#endif
|
||||||
Reference in New Issue
Block a user