mirror of
https://github.com/OpenVPN/openvpn.git
synced 2025-05-08 21:25:53 +08:00
build: integrate plugins build into core build
As disucssed[1], keep plugins in repository. 1, Proper automake/libtool build. 2. Move example plugins to samples/sample-plugins. 3. Plugins are installed at LIBDIR/openvpn/plugins. [1] http://comments.gmane.org/gmane.network.openvpn.devel/6436 Signed-off-by: Alon Bar-Lev <alon.barlev@gmail.com> Acked-by: David Sommerseth <davids@redhat.com> Message-Id: 1337035323-27465-1-git-send-email-alon.barlev@gmail.com URL: http://article.gmane.org/gmane.network.openvpn.devel/6591 Signed-off-by: David Sommerseth <davids@redhat.com>
This commit is contained in:
parent
8acdb7291c
commit
ce8271f5d4
63
configure.ac
63
configure.ac
@ -193,6 +193,27 @@ AC_ARG_ENABLE(
|
||||
[enable_pf="yes"]
|
||||
)
|
||||
|
||||
AC_ARG_ENABLE(
|
||||
[plugin-auth-pam],
|
||||
[AS_HELP_STRING([--disable-plugin-auth-pam], [disable auth-pam plugin @<:@default=yes@:>@])],
|
||||
,
|
||||
[enable_plugin_auth_pam="yes"]
|
||||
)
|
||||
|
||||
AC_ARG_ENABLE(
|
||||
[plugin-down-root],
|
||||
[AS_HELP_STRING([--disable-plugin-down-root], [disable down-root plugin @<:@default=yes@:>@])],
|
||||
,
|
||||
[enable_plugin_down_root="yes"]
|
||||
)
|
||||
|
||||
AC_ARG_ENABLE(
|
||||
[pam-dlopen],
|
||||
[AS_HELP_STRING([--enable-pam-dlopen], [dlopen libpam @<:@default=no@:>@])],
|
||||
,
|
||||
[enable_pam_dlopen="no"]
|
||||
)
|
||||
|
||||
AC_ARG_ENABLE(
|
||||
[strict],
|
||||
[AS_HELP_STRING([--enable-strict], [enable strict compiler warnings (debugging option) @<:@default=no@:>@])],
|
||||
@ -258,6 +279,14 @@ AC_ARG_WITH(
|
||||
[with_crypto_library="openssl"]
|
||||
)
|
||||
|
||||
AC_ARG_WITH(
|
||||
[plugindir],
|
||||
[AS_HELP_STRING([--with-plugindir], [plugin directory @<:@default=LIBDIR/openvpn@:>@])],
|
||||
,
|
||||
[with_plugindir="\$(libdir)/openvpn/plugins"]
|
||||
)
|
||||
|
||||
|
||||
AC_DEFINE_UNQUOTED([TARGET_ALIAS], ["${host}"], [A string representing our host])
|
||||
case "$host" in
|
||||
*-*-linux*)
|
||||
@ -624,6 +653,16 @@ AC_CHECK_LIB(
|
||||
)
|
||||
AC_SUBST([SELINUX_LIBS])
|
||||
|
||||
AC_ARG_VAR([LIBPAM_CFLAGS], [C compiler flags for libpam])
|
||||
AC_ARG_VAR([LIBPAM_LIBS], [linker flags for libpam])
|
||||
if test -z "${LIBPAM_LIBS}"; then
|
||||
AC_CHECK_LIB(
|
||||
[pam],
|
||||
[pam_start],
|
||||
[LIBPAM_LIBS="-lpam"]
|
||||
)
|
||||
fi
|
||||
|
||||
case "${with_mem_check}" in
|
||||
valgrind)
|
||||
AC_CHECK_HEADER(
|
||||
@ -894,6 +933,9 @@ if test "${enable_plugins}" = "yes"; then
|
||||
OPTIONAL_DL_LIBS="${DL_LIBS}"
|
||||
AC_DEFINE([ENABLE_PLUGIN], [1], [Enable systemd support])
|
||||
test "${enable_eurephia}" = "yes" && AC_DEFINE([ENABLE_EUREPHIA], [1], [Enable support for the eurephia plug-in])
|
||||
else
|
||||
enable_plugin_auth_pam="no"
|
||||
enable_plugin_down_root="no"
|
||||
fi
|
||||
|
||||
if test "${enable_iproute2}" = "yes"; then
|
||||
@ -945,6 +987,17 @@ if test "${WIN32}" = "yes"; then
|
||||
test -z "${MAN2HTML}" && AC_MSG_ERROR([man2html is required for win32])
|
||||
fi
|
||||
|
||||
if test "${enable_plugin_auth_pam}" = "yes"; then
|
||||
PLUGIN_AUTH_PAM_CFLAGS="${LIBPAM_CFLAGS}"
|
||||
if test "${enable_pam_dlopen}" = "yes"; then
|
||||
AC_DEFINE([USE_PAM_DLOPEN], [1], [dlopen libpam])
|
||||
PLUGIN_AUTH_PAM_LIBS="${DL_LIBS}"
|
||||
else
|
||||
test -z "${LIBPAM_LIBS}" && AC_MSG_ERROR([libpam required but missing])
|
||||
PLUGIN_AUTH_PAM_LIBS="${LIBPAM_LIBS}"
|
||||
fi
|
||||
fi
|
||||
|
||||
CONFIGURE_DEFINES="`set | grep '^enable_.*=' ; set | grep '^with_.*='`"
|
||||
AC_DEFINE_UNQUOTED([CONFIGURE_DEFINES], ["`echo ${CONFIGURE_DEFINES}`"], [Configuration settings])
|
||||
|
||||
@ -967,10 +1020,17 @@ AC_SUBST([OPTIONAL_LZO_LIBS])
|
||||
AC_SUBST([OPTIONAL_PKCS11_HELPER_CFLAGS])
|
||||
AC_SUBST([OPTIONAL_PKCS11_HELPER_LIBS])
|
||||
|
||||
AC_SUBST([PLUGIN_AUTH_PAM_CFLAGS])
|
||||
AC_SUBST([PLUGIN_AUTH_PAM_LIBS])
|
||||
|
||||
AM_CONDITIONAL([WIN32], [test "${WIN32}" = "yes"])
|
||||
AM_CONDITIONAL([GIT_CHECKOUT], [test "${GIT_CHECKOUT}" = "yes"])
|
||||
AM_CONDITIONAL([ENABLE_PLUGIN_AUTH_PAM], [test "${enable_plugin_auth_pam}" = "yes"])
|
||||
AM_CONDITIONAL([ENABLE_PLUGIN_DOWN_ROOT], [test "${enable_plugin_down_root}" = "yes"])
|
||||
|
||||
plugindir="${with_plugindir}"
|
||||
sampledir="\$(docdir)/sample"
|
||||
AC_SUBST([plugindir])
|
||||
AC_SUBST([sampledir])
|
||||
|
||||
AC_CONFIG_FILES([
|
||||
@ -987,6 +1047,9 @@ AC_CONFIG_FILES([
|
||||
src/compat/Makefile
|
||||
src/openvpn/Makefile
|
||||
src/openvpnserv/Makefile
|
||||
src/plugins/Makefile
|
||||
src/plugins/auth-pam/Makefile
|
||||
src/plugins/down-root/Makefile
|
||||
tests/Makefile
|
||||
sample/Makefile
|
||||
doc/Makefile
|
||||
|
@ -82,13 +82,6 @@ Development support for OpenVPN.
|
||||
%define VENDOR %_vendor
|
||||
%endif
|
||||
|
||||
#
|
||||
# Should we build the auth-pam module?
|
||||
#
|
||||
|
||||
%define build_auth_pam 1
|
||||
%{?without_pam:%define build_auth_pam 0}
|
||||
|
||||
#
|
||||
# Other definitions
|
||||
#
|
||||
@ -108,21 +101,10 @@ Development support for OpenVPN.
|
||||
--docdir="%{_docdir}/%{name}-%{version}" \
|
||||
%{?with_password_save:--enable-password-save} \
|
||||
%{!?without_lzo:--enable-lzo} \
|
||||
%{?with_pkcs11:--enable-pkcs11}
|
||||
%{?with_pkcs11:--enable-pkcs11} \
|
||||
%{?without_pam:--disable-plugin-auth-pam}
|
||||
%__make
|
||||
|
||||
# Build down-root plugin
|
||||
pushd src/plugins/down-root
|
||||
%__make
|
||||
popd
|
||||
|
||||
# Build auth-pam plugin
|
||||
%if %{build_auth_pam}
|
||||
pushd src/plugins/auth-pam
|
||||
%__make
|
||||
popd
|
||||
%endif
|
||||
|
||||
#
|
||||
# Installation section
|
||||
#
|
||||
@ -143,29 +125,8 @@ popd
|
||||
# Install /etc/openvpn
|
||||
%__install -c -d -m 755 "%{buildroot}/etc/%{name}"
|
||||
|
||||
#
|
||||
# Build /usr/share/openvpn
|
||||
#
|
||||
|
||||
%__mkdir_p %{buildroot}%{_datadir}/%{name}
|
||||
|
||||
#
|
||||
# Install the plugins
|
||||
#
|
||||
|
||||
%__mkdir_p "%{buildroot}%{_datadir}/%{name}/plugins/lib"
|
||||
|
||||
for pi in auth-pam down-root; do
|
||||
%__mv -f src/plugins/$pi/README src/plugins/README.$pi
|
||||
if [ -e src/plugins/$pi/openvpn-$pi.so ]; then
|
||||
%__install -c -m 755 src/plugins/$pi/openvpn-$pi.so "%{buildroot}%{_datadir}/openvpn/plugins/lib/openvpn-$pi.so"
|
||||
fi
|
||||
done
|
||||
|
||||
%__mv -f src/plugins/README src/plugins/README.plugins
|
||||
|
||||
# Install extra %doc stuff
|
||||
cp -r AUTHORS ChangeLog NEWS contrib/ sample/ src/plugins/README.* \
|
||||
cp -r AUTHORS ChangeLog NEWS contrib/ sample/ \
|
||||
"%{buildroot}/%{_docdir}/%{name}-%{version}"
|
||||
|
||||
#
|
||||
@ -218,7 +179,7 @@ fi
|
||||
%defattr(-,root,root)
|
||||
%{_mandir}
|
||||
%{_sbindir}/%{name}
|
||||
%{_datadir}/%{name}
|
||||
%{_libdir}/%{name}
|
||||
%{_docdir}/%{name}-%{version}
|
||||
%dir /etc/%{name}
|
||||
%if "%{VENDOR}" == "SuSE"
|
||||
|
@ -17,8 +17,11 @@ CLEANFILES = openvpn.8.html
|
||||
dist_doc_DATA = \
|
||||
management-notes.txt
|
||||
|
||||
dist_noinst_DATA = \
|
||||
README.plugins
|
||||
|
||||
if WIN32
|
||||
dist_noinst_DATA = openvpn.8
|
||||
dist_noinst_DATA += openvpn.8
|
||||
nodist_html_DATA = openvpn.8.html
|
||||
openvpn.8.html: $(srcdir)/openvpn.8
|
||||
$(MAN2HTML) < $(srcdir)/openvpn.8 > openvpn.8.html
|
||||
|
@ -13,6 +13,7 @@ MAINTAINERCLEANFILES = \
|
||||
$(srcdir)/Makefile.in
|
||||
|
||||
EXTRA_DIST = \
|
||||
sample-plugins \
|
||||
sample-config-files \
|
||||
sample-windows \
|
||||
sample-keys \
|
||||
|
15
sample/sample-plugins/simple/build
Executable file
15
sample/sample-plugins/simple/build
Executable file
@ -0,0 +1,15 @@
|
||||
#!/bin/sh
|
||||
|
||||
#
|
||||
# Build an OpenVPN plugin module on *nix. The argument should
|
||||
# be the base name of the C source file (without the .c).
|
||||
#
|
||||
|
||||
# This directory is where we will look for openvpn-plugin.h
|
||||
CPPFLAGS="${CPPFLAGS:--I../../..}"
|
||||
|
||||
CC="${CC:-gcc}"
|
||||
CFLAGS="${CFLAGS:--O2 -Wall -g}"
|
||||
|
||||
$CC $CPPFLAGS $CFLAGS -fPIC -c $1.c && \
|
||||
$CC $CFLAGS -fPIC -shared $LDFLAGS -Wl,-soname,$1.so -o $1.so $1.o -lc
|
18
sample/sample-plugins/simple/winbuild
Executable file
18
sample/sample-plugins/simple/winbuild
Executable file
@ -0,0 +1,18 @@
|
||||
#
|
||||
# Build an OpenVPN plugin module on Windows/MinGW.
|
||||
# The argument should be the base name of the C source file
|
||||
# (without the .c).
|
||||
#
|
||||
|
||||
# This directory is where we will look for openvpn-plugin.h
|
||||
INCLUDE="-I../../../include"
|
||||
|
||||
CC_FLAGS="-O2 -Wall"
|
||||
|
||||
gcc -DBUILD_DLL $CC_FLAGS $INCLUDE -c $1.c
|
||||
gcc --disable-stdcall-fixup -mdll -DBUILD_DLL -o junk.tmp -Wl,--base-file,base.tmp $1.o
|
||||
rm junk.tmp
|
||||
dlltool --dllname $1.dll --base-file base.tmp --output-exp temp.exp --input-def $1.def
|
||||
rm base.tmp
|
||||
gcc --enable-stdcall-fixup -mdll -DBUILD_DLL -o $1.dll $1.o -Wl,temp.exp
|
||||
rm temp.exp
|
@ -12,7 +12,4 @@
|
||||
MAINTAINERCLEANFILES = \
|
||||
$(srcdir)/Makefile.in
|
||||
|
||||
EXTRA_DIST = \
|
||||
plugins
|
||||
|
||||
SUBDIRS = compat openvpn openvpnserv
|
||||
SUBDIRS = compat openvpn openvpnserv plugins
|
||||
|
15
src/plugins/Makefile.am
Normal file
15
src/plugins/Makefile.am
Normal file
@ -0,0 +1,15 @@
|
||||
#
|
||||
# OpenVPN -- An application to securely tunnel IP networks
|
||||
# over a single UDP port, with support for SSL/TLS-based
|
||||
# session authentication and key exchange,
|
||||
# packet encryption, packet authentication, and
|
||||
# packet compression.
|
||||
#
|
||||
# Copyright (C) 2002-2010 OpenVPN Technologies, Inc. <sales@openvpn.net>
|
||||
# Copyright (C) 2006-2012 Alon Bar-Lev <alon.barlev@gmail.com>
|
||||
#
|
||||
|
||||
MAINTAINERCLEANFILES = \
|
||||
$(srcdir)/Makefile.in
|
||||
|
||||
SUBDIRS = auth-pam down-root
|
@ -1,32 +0,0 @@
|
||||
#
|
||||
# Build the OpenVPN auth-pam plugin module.
|
||||
#
|
||||
|
||||
# If PAM modules are not linked against libpam.so, set DLOPEN_PAM to 1. This
|
||||
# must be done on SUSE 9.1, at least.
|
||||
DLOPEN_PAM=0
|
||||
|
||||
ifeq ($(DLOPEN_PAM),1)
|
||||
LIBPAM=-ldl
|
||||
else
|
||||
LIBPAM=-lpam
|
||||
endif
|
||||
|
||||
# This directory is where we will look for openvpn-plugin.h
|
||||
CPPFLAGS=-I../../../include
|
||||
|
||||
CC=gcc
|
||||
CFLAGS=-O2 -Wall
|
||||
DEFS = -DDLOPEN_PAM=$(DLOPEN_PAM)
|
||||
|
||||
openvpn-auth-pam.so : auth-pam.o pamdl.o
|
||||
$(CC) $(CFLAGS) -fPIC -shared $(LDFLAGS) -Wl,-soname,openvpn-auth-pam.so -o openvpn-auth-pam.so auth-pam.o pamdl.o -lc $(LIBPAM)
|
||||
|
||||
auth-pam.o : auth-pam.c pamdl.h
|
||||
$(CC) $(CPPFLAGS) $(CFLAGS) $(DEFS) -fPIC -c auth-pam.c
|
||||
|
||||
pamdl.o : pamdl.c pamdl.h
|
||||
$(CC) $(CPPFLAGS) $(CFLAGS) $(DEFS) -fPIC -c pamdl.c
|
||||
|
||||
clean :
|
||||
-rm -f *.o *.so
|
27
src/plugins/auth-pam/Makefile.am
Normal file
27
src/plugins/auth-pam/Makefile.am
Normal file
@ -0,0 +1,27 @@
|
||||
#
|
||||
# OpenVPN (TM) PAM Auth Plugin -- OpenVPN Plugin
|
||||
#
|
||||
# Copyright (C) 2012 Alon Bar-Lev <alon.barlev@gmail.com>
|
||||
#
|
||||
|
||||
MAINTAINERCLEANFILES = \
|
||||
$(srcdir)/Makefile.in
|
||||
|
||||
AM_CFLAGS = \
|
||||
-I$(top_srcdir)/include
|
||||
$(PLUGIN_AUTH_PAM_CFLAGS)
|
||||
|
||||
if ENABLE_PLUGIN_AUTH_PAM
|
||||
plugin_LTLIBRARIES = openvpn-plugin-auth-pam.la
|
||||
dist_doc_DATA = README.auth-pam
|
||||
endif
|
||||
|
||||
openvpn_plugin_auth_pam_la_SOURCES = \
|
||||
auth-pam.c \
|
||||
pamdl.c pamdl.h \
|
||||
auth-pam.exports
|
||||
openvpn_plugin_auth_pam_la_LIBADD = \
|
||||
$(PLUGIN_AUTH_PAM_LIBS)
|
||||
openvpn_plugin_auth_pam_la_LDFLAGS = $(AM_LDFLAGS) \
|
||||
-export-symbols "$(srcdir)/auth-pam.exports" \
|
||||
-module -shared -avoid-version -no-undefined
|
@ -26,12 +26,14 @@
|
||||
* OpenVPN plugin module to do PAM authentication using a split
|
||||
* privilege model.
|
||||
*/
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
#endif
|
||||
|
||||
#if DLOPEN_PAM
|
||||
#include <dlfcn.h>
|
||||
#include "pamdl.h"
|
||||
#else
|
||||
#include <security/pam_appl.h>
|
||||
|
||||
#ifdef USE_PAM_DLOPEN
|
||||
#include "pamdl.h"
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
@ -46,7 +48,7 @@
|
||||
#include <signal.h>
|
||||
#include <syslog.h>
|
||||
|
||||
#include "openvpn-plugin.h"
|
||||
#include <openvpn-plugin.h>
|
||||
|
||||
#define DEBUG(verb) ((verb) >= 4)
|
||||
|
||||
@ -693,7 +695,7 @@ pam_server (int fd, const char *service, int verb, const struct name_value_list
|
||||
{
|
||||
struct user_pass up;
|
||||
int command;
|
||||
#if DLOPEN_PAM
|
||||
#ifdef USE_PAM_DLOPEN
|
||||
static const char pam_so[] = "libpam.so";
|
||||
#endif
|
||||
|
||||
@ -703,7 +705,7 @@ pam_server (int fd, const char *service, int verb, const struct name_value_list
|
||||
if (DEBUG (verb))
|
||||
fprintf (stderr, "AUTH-PAM: BACKGROUND: INIT service='%s'\n", service);
|
||||
|
||||
#if DLOPEN_PAM
|
||||
#ifdef USE_PAM_DLOPEN
|
||||
/*
|
||||
* Load PAM shared object
|
||||
*/
|
||||
@ -794,7 +796,7 @@ pam_server (int fd, const char *service, int verb, const struct name_value_list
|
||||
}
|
||||
done:
|
||||
|
||||
#if DLOPEN_PAM
|
||||
#ifdef USE_PAM_DLOPEN
|
||||
dlclose_pam ();
|
||||
#endif
|
||||
if (DEBUG (verb))
|
||||
|
4
src/plugins/auth-pam/auth-pam.exports
Normal file
4
src/plugins/auth-pam/auth-pam.exports
Normal file
@ -0,0 +1,4 @@
|
||||
openvpn_plugin_open_v1
|
||||
openvpn_plugin_func_v1
|
||||
openvpn_plugin_close_v1
|
||||
openvpn_plugin_abort_v1
|
@ -1,4 +1,8 @@
|
||||
#if DLOPEN_PAM
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
#endif
|
||||
|
||||
#ifdef USE_PAM_DLOPEN
|
||||
/*
|
||||
* If you want to dynamically load libpam using dlopen() or something,
|
||||
* then dlopen( ' this shared object ' ); It takes care of exporting
|
||||
@ -73,7 +77,7 @@ int pam_set_item(pam_handle_t *pamh, int item_type, const void *item)
|
||||
return real_pam_set_item(pamh, item_type, item);
|
||||
}
|
||||
|
||||
int pam_get_item(pam_handle_t *pamh, int item_type, const void **item)
|
||||
int pam_get_item(const pam_handle_t *pamh, int item_type, const void **item)
|
||||
{
|
||||
int (*real_pam_get_item)(const pam_handle_t *, int, const void **);
|
||||
RESOLVE_PAM_FUNCTION(pam_get_item, int,
|
||||
|
@ -1,6 +1,4 @@
|
||||
#if DLOPEN_PAM
|
||||
#include <security/pam_appl.h>
|
||||
|
||||
#ifdef USE_PAM_DLOPEN
|
||||
/* Dynamically load and unload the PAM library */
|
||||
int dlopen_pam (const char *so);
|
||||
void dlclose_pam (void);
|
||||
|
@ -1,18 +0,0 @@
|
||||
#
|
||||
# Build the OpenVPN down-root plugin module.
|
||||
#
|
||||
|
||||
# This directory is where we will look for openvpn-plugin.h
|
||||
CPPFLAGS=-I../../../include
|
||||
|
||||
CC=gcc
|
||||
CFLAGS=-O2 -Wall
|
||||
|
||||
down-root.so : down-root.o
|
||||
$(CC) $(CFLAGS) -fPIC -shared $(LDFLAGS) -Wl,-soname,openvpn-down-root.so -o openvpn-down-root.so down-root.o -lc
|
||||
|
||||
down-root.o : down-root.c
|
||||
$(CC) $(CPPFLAGS) $(CFLAGS) -fPIC -c down-root.c
|
||||
|
||||
clean :
|
||||
-rm -f *.o *.so
|
23
src/plugins/down-root/Makefile.am
Normal file
23
src/plugins/down-root/Makefile.am
Normal file
@ -0,0 +1,23 @@
|
||||
#
|
||||
# OpenVPN (TM) Down Root Plugin -- OpenVPN Plugin
|
||||
#
|
||||
# Copyright (C) 2012 Alon Bar-Lev <alon.barlev@gmail.com>
|
||||
#
|
||||
|
||||
MAINTAINERCLEANFILES = \
|
||||
$(srcdir)/Makefile.in
|
||||
|
||||
AM_CFLAGS = \
|
||||
-I$(top_srcdir)/include
|
||||
|
||||
if ENABLE_PLUGIN_DOWN_ROOT
|
||||
plugin_LTLIBRARIES = openvpn-plugin-down-root.la
|
||||
dist_doc_DATA = README.down-root
|
||||
endif
|
||||
|
||||
openvpn_plugin_down_root_la_SOURCES = \
|
||||
down-root.c \
|
||||
down-root.exports
|
||||
openvpn_plugin_down_root_la_LDFLAGS = $(AM_LDFLAGS) \
|
||||
-export-symbols "$(srcdir)/down-root.exports" \
|
||||
-module -shared -avoid-version -no-undefined
|
@ -26,6 +26,10 @@
|
||||
* OpenVPN plugin module to do privileged down-script execution.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
@ -37,7 +41,7 @@
|
||||
#include <signal.h>
|
||||
#include <syslog.h>
|
||||
|
||||
#include "openvpn-plugin.h"
|
||||
#include <openvpn-plugin.h>
|
||||
|
||||
#define DEBUG(verb) ((verb) >= 7)
|
||||
|
||||
|
4
src/plugins/down-root/down-root.exports
Normal file
4
src/plugins/down-root/down-root.exports
Normal file
@ -0,0 +1,4 @@
|
||||
openvpn_plugin_open_v1
|
||||
openvpn_plugin_func_v1
|
||||
openvpn_plugin_close_v1
|
||||
openvpn_plugin_abort_v1
|
Loading…
x
Reference in New Issue
Block a user