Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Macaroons plugin for Xrootd #762

Merged
merged 30 commits into from
Jul 27, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
fc542df
[XrdMacaroons] Create skeleton of Macaroon issuer.
bbockelm Jun 8, 2018
74eca6c
[XrdMacaroons] Implement generation of macaroon with activities.
bbockelm Jun 9, 2018
7988446
[XrdMacaroons] Add support for configuring macaroons plugin.
bbockelm Jun 12, 2018
da53ba1
[XrdMacaroons] Add simple license and readme files.
bbockelm Jun 12, 2018
b0d438a
[XrdMacaroons] Add outlines of an XrdAccAuthorize implementation for …
bbockelm Jun 12, 2018
d7d8fc9
[XrdMacaroons] Finish initial authorizor for macaroons.
bbockelm Jun 13, 2018
62a4c1d
[XrdMacaroons] Tweak behavior around READ_METADATA.
bbockelm Jun 14, 2018
7510cc1
[XrdMacaroons] Backport API use to libmacaroons 0.3.0.
bbockelm Jun 15, 2018
e1b4809
[XrdMacaroons] Update readme with some sample usage.
bbockelm Jun 15, 2018
4dd7324
[XrdMacaroons] Create RPM packaging for macaroons plugin
bbockelm Jun 15, 2018
b34c0e0
[XrdMacaroons] We need the development headers, not the runtime library.
bbockelm Jun 15, 2018
8411ff0
[XrdMacaroons] Add missing build dependency on openssl.
bbockelm Jun 17, 2018
cfd9580
[XrdMacaroons] Add missing build dep on json-c-devel.
bbockelm Jun 18, 2018
42ae5be
[XrdMacaroons] Open secret file with correct mode.
bbockelm Jun 18, 2018
51fe980
[XrdMacaroons] Cleanup TODO logging items.
bbockelm Jul 8, 2018
a1ec450
[XrdMacaroons] Serialize the XrdSecEntity name field in macaroon.
bbockelm Jul 8, 2018
3366ac7
[XrdMacaroons] Add multiple tracing levels to the module's logging.
bbockelm Jul 9, 2018
af2c141
[XrdMacaroons] Allow macaroon plugin to chain another authlib.
bbockelm Jul 9, 2018
4b542de
[XrdMacaroons] Forward remaining arguments to chained authlib.
bbockelm Jul 9, 2018
630cac2
[XrdMacaroons] Update RPM spec file for release.
bbockelm Jul 9, 2018
8b43f2d
[XrdMacaroons] Add concept of max duration of a macaroon lifetime.
bbockelm Jul 9, 2018
952e5d0
[XrdMacaroons] Check location header and record IDs as we use them.
bbockelm Jul 9, 2018
cf1d085
[XrdMacaroons] Bump RPM for 0.3.0 release.
bbockelm Jul 9, 2018
81de7e9
[XrdMacaroons] Rename macaroon-related files in preparation for merge.
bbockelm Jul 10, 2018
b51f8f6
[XrdMacaroons] Merge branch 'xrootd-macaroons-rename-v2' into xrootd-…
bbockelm Jul 17, 2018
ab7a336
[XrdMacaroons] Initial CMake integration of Macaroons.
bbockelm Jul 10, 2018
613dda2
[XrdMacaroons] Rename macaroon files to match Xrootd-style.
bbockelm Jul 10, 2018
011ad86
[XrdMacaroons] Additional build-related cleanup from merge.
bbockelm Jul 10, 2018
406d304
[XrdMacaroons] Only build Macaroons when library is present.
bbockelm Jul 17, 2018
c67fcac
[XrdMacaroons] Do not attempt to install libXrdMacaroons on debian.
bbockelm Jul 17, 2018
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
21 changes: 21 additions & 0 deletions cmake/FindMacaroons.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@

FIND_PATH(MACAROONS_INCLUDES macaroons.h
HINTS
${MACAROONS_DIR}
$ENV{MACAROONS_DIR}
/usr
PATH_SUFFIXES include
)

FIND_LIBRARY(MACAROONS_LIB macaroons
HINTS
${MACAROONS_DIR}
$ENV{MACAROONS_DIR}
/usr
PATH_SUFFIXES lib
PATH_SUFFIXES .libs
)

INCLUDE(FindPackageHandleStandardArgs)
FIND_PACKAGE_HANDLE_STANDARD_ARGS(Macaroons DEFAULT_MSG MACAROONS_INCLUDES MACAROONS_LIB)

20 changes: 10 additions & 10 deletions cmake/XRootDDefaults.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,14 @@ if( "${CMAKE_BUILD_TYPE}" STREQUAL "" )
endif()
endif()

define_default( PLUGIN_VERSION 4 )
define_default( ENABLE_FUSE TRUE )
define_default( ENABLE_CRYPTO TRUE )
define_default( ENABLE_KRB5 TRUE )
define_default( ENABLE_READLINE TRUE )
define_default( ENABLE_XRDCL TRUE )
define_default( ENABLE_TESTS FALSE )
define_default( ENABLE_HTTP TRUE )
define_default( ENABLE_CEPH TRUE )
define_default( ENABLE_PYTHON TRUE )
define_default( PLUGIN_VERSION 4 )
define_default( ENABLE_FUSE TRUE )
define_default( ENABLE_CRYPTO TRUE )
define_default( ENABLE_KRB5 TRUE )
define_default( ENABLE_READLINE TRUE )
define_default( ENABLE_XRDCL TRUE )
define_default( ENABLE_TESTS FALSE )
define_default( ENABLE_HTTP TRUE )
define_default( ENABLE_CEPH TRUE )
define_default( ENABLE_PYTHON TRUE )
define_default( XRD_PYTHON_REQ_VERSION 2.4 )
11 changes: 11 additions & 0 deletions cmake/XRootDFindLibs.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,17 @@ check_function_exists( curl_multi_wait HAVE_CURL_MULTI_WAIT )
compiler_define_if_found( HAVE_CURL_MULTI_WAIT HAVE_CURL_MULTI_WAIT )
endif()

find_package( Macaroons )
include (FindPkgConfig)
pkg_check_modules(JSON json-c)
pkg_check_modules(UUID uuid)

if( Macaroons_FOUND AND JSON_FOUND AND UUID_FOUND )
set( BUILD_MACAROONS TRUE )
else()
set( BUILD_MACAROONS FALSE )
endif()

if( ENABLE_CEPH )
find_package( ceph )
if( CEPH_FOUND )
Expand Down
22 changes: 12 additions & 10 deletions cmake/XRootDSummary.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,17 @@
# Print the configuration summary
#-------------------------------------------------------------------------------
set( TRUE_VAR TRUE )
component_status( READLINE ENABLE_READLINE READLINE_FOUND )
component_status( FUSE BUILD_FUSE FUSE_FOUND )
component_status( CRYPTO BUILD_CRYPTO OPENSSL_FOUND )
component_status( KRB5 BUILD_KRB5 KERBEROS5_FOUND )
component_status( XRDCL ENABLE_XRDCL TRUE_VAR )
component_status( TESTS BUILD_TESTS CPPUNIT_FOUND )
component_status( HTTP BUILD_HTTP OPENSSL_FOUND )
component_status( TPC BUILD_TPC CURL_FOUND )
component_status( CEPH BUILD_CEPH CEPH_FOUND )
component_status( PYTHON BUILD_PYTHON PYTHON_FOUND )
component_status( READLINE ENABLE_READLINE READLINE_FOUND )
component_status( FUSE BUILD_FUSE FUSE_FOUND )
component_status( CRYPTO BUILD_CRYPTO OPENSSL_FOUND )
component_status( KRB5 BUILD_KRB5 KERBEROS5_FOUND )
component_status( XRDCL ENABLE_XRDCL TRUE_VAR )
component_status( TESTS BUILD_TESTS CPPUNIT_FOUND )
component_status( HTTP BUILD_HTTP OPENSSL_FOUND )
component_status( TPC BUILD_TPC CURL_FOUND )
component_status( MACAROONS BUILD_MACAROONS MACAROONS_FOUND )
component_status( CEPH BUILD_CEPH CEPH_FOUND )
component_status( PYTHON BUILD_PYTHON PYTHON_FOUND )

message( STATUS "----------------------------------------" )
message( STATUS "Installation path: " ${CMAKE_INSTALL_PREFIX} )
Expand All @@ -28,6 +29,7 @@ message( STATUS "XrdCl: " ${STATUS_XRDCL} )
message( STATUS "Tests: " ${STATUS_TESTS} )
message( STATUS "HTTP support: " ${STATUS_HTTP} )
message( STATUS "HTTP TPC support: " ${STATUS_TPC} )
message( STATUS "Macaroons support: " ${STATUS_MACAROONS} )
message( STATUS "CEPH support: " ${STATUS_CEPH} )
message( STATUS "Python support: " ${STATUS_PYTHON} )
message( STATUS "----------------------------------------" )
4 changes: 4 additions & 0 deletions packaging/rhel/xrootd.spec.in
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,9 @@ BuildRequires: krb5-devel
BuildRequires: zlib-devel
BuildRequires: ncurses-devel
BuildRequires: libcurl-devel
BuildRequires: libuuid-devel
BuildRequires: libmacaroons-devel
BuildRequires: json-c-devel

BuildRequires: python2-devel
%if %{?fedora}%{!?fedora:0} >= 13
Expand Down Expand Up @@ -781,6 +784,7 @@ fi
%{_libdir}/libXrdHttp-4.so
%{_libdir}/libXrdHttpTPC-4.so
%{_libdir}/libXrdHttpUtils.so.*
%{_libdir}/libXrdMacaroons-4.so
%{_libdir}/libXrdN2No2p-4.so
%{_libdir}/libXrdOssSIgpfsT-4.so
%{_libdir}/libXrdServer.so.*
Expand Down
4 changes: 4 additions & 0 deletions src/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,10 @@ if( BUILD_HTTP )
include( XrdTpc )
endif()

if( BUILD_MACAROONS )
include( XrdMacaroons )
endif()

if( BUILD_CEPH )
include( XrdCeph )
endif()
Expand Down
54 changes: 54 additions & 0 deletions src/XrdMacaroons.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
include( XRootDCommon )

#-------------------------------------------------------------------------------
# Modules
#-------------------------------------------------------------------------------
set( LIB_XRD_MACAROONS XrdMacaroons-${PLUGIN_VERSION} )

#-------------------------------------------------------------------------------
# Shared library version
#-------------------------------------------------------------------------------

if( BUILD_MACAROONS )
include_directories(${MACAROONS_INCLUDES} ${JSON_INCLUDE_DIRS} ${UUID_INCLUDE_DIRS} ${OPENSSL_INCLUDE_DIR})

add_library(
${LIB_XRD_MACAROONS}
MODULE
XrdMacaroons/XrdMacaroons.cc
XrdMacaroons/XrdMacaroonsHandler.cc XrdMacaroons/XrdMacaroonsHandler.hh
XrdMacaroons/XrdMacaroonsAuthz.cc XrdMacaroons/XrdMacaroonsAuthz.hh
XrdMacaroons/XrdMacaroonsConfigure.cc)

target_link_libraries(
${LIB_XRD_MACAROONS} -ldl
XrdHttpUtils
XrdUtils
XrdServer
${MACAROONS_LIB}
${JSON_LIBRARIES}
${XROOTD_HTTP_LIB}
${UUID_LIBRARIES}
${OPENSSL_CRYPTO_LIBRARY})

if( MacOSX )
SET( MACAROONS_LINK_FLAGS "-Wl")
else()
SET( MACAROONS_LINK_FLAGS "-Wl,--version-script=${CMAKE_SOURCE_DIR}/src/XrdMacaroons/export-lib-symbols" )
endif()

set_target_properties(
${LIB_XRD_MACAROONS}
PROPERTIES
INTERFACE_LINK_LIBRARIES ""
LINK_INTERFACE_LIBRARIES ""
LINK_FLAGS "${MACAROONS_LINK_FLAGS}")

#-----------------------------------------------------------------------------
# Install
#-----------------------------------------------------------------------------
install(
TARGETS ${LIB_XRD_MACAROONS}
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR})

endif()
62 changes: 62 additions & 0 deletions src/XrdMacaroons/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@

Macaroon support for Xrootd
===========================

This plugin adds support for macaroon-style authorizations in XRootD, particularly
for the XrdHttp protocol implementation.

Configuration
=============

To enable, you need to add three lines to the configuration file:

```
ofs.authlib libXrdMacaroons.so
http.exthandler xrdmacaroons libXrdMacaroons.so
macaroons.secretkey /etc/xrootd/macaroon-secret
all.sitename Example_Site
```

You will need to change `all.sitename` accordingly. The secret key is a symmetric
key necessary to verify macaroons; the same key must be deployed to all XRootD
servers in your cluster.

The secret key must be base64-encoded. The most straightforward way to generate
this is the following:

```
openssl rand -base64 -out /etc/xrootd/macaroon-secret 64
```

Usage
=====

To generate a macaroon for personal use, you can run:

```
macaroon-init https://host.example.com//path/to/directory/ --validity 60 --activity DOWNLOAD,UPLOAD
```

(the `macaroon-init` CLI can be found as part of the `x509-scitokens-issuer-client` package). This
will generate a macaroon with 60 minutes of validity that has upload and download access to the path
specified at `/path/to/directory`, provided that your X509 identity has that access.

The output will look like the following:

```
Querying https://host.example.com//path/to/directory/ for new token.
Validity: PT60M, activities: DOWNLOAD,UPLOAD,READ_METADATA.
Successfully generated a new token:
{
"macaroon":"MDAxY2xvY2F0aW9uIFQyX1VTX05lYnJhc2thCjAwMzRpZGVudGlmaWVyIGMzODU3MjQ3LThjYzItNGI0YS04ZDUwLWNiZDYzN2U2MzJhMQowMDUyY2lkIGFjdGl2aXR5OlJFQURfTUVUQURBVEEsVVBMT0FELERPV05MT0FELERFTEVURSxNQU5BR0UsVVBEQVRFX01FVEFEQVRBLExJU1QKMDAyZmNpZCBhY3Rpdml0eTpET1dOTE9BRCxVUExPQUQsUkVBRF9NRVRBREFUQQowMDM2Y2lkIHBhdGg6L2hvbWUvY3NlNDk2L2Jib2NrZWxtL3RtcC94cm9vdGRfZXhwb3J0LwowMDI0Y2lkIGJlZm9yZToyMDE4LTA2LTE1VDE4OjE5OjI5WgowMDJmc2lnbmF0dXJlIFXI_x3v8Tq1jYcP-2WUvPV-BIewn5MHRODVu8UszyYkCg"
}
```

The contents of the `macaroon` key is your new security token. Anyone you share it with will be able to read and write from the same path.
You can use this token as a bearer token for HTTPS authorization. For example, it can authorize the following transfer:

```
curl -v
-H 'Authorization: Bearer MDAxY2xvY2F0aW9uIFQyX1VTX05lYnJhc2thCjAwMzRpZGVudGlmaWVyIGMzODU3MjQ3LThjYzItNGI0YS04ZDUwLWNiZDYzN2U2MzJhMQowMDUyY2lkIGFjdGl2aXR5OlJFQURfTUVUQURBVEEsVVBMT0FELERPV05MT0FELERFTEVURSxNQU5BR0UsVVBEQVRFX01FVEFEQVRBLExJU1QKMDAyZmNpZCBhY3Rpdml0eTpET1dOTE9BRCxVUExPQUQsUkVBRF9NRVRBREFUQQowMDM2Y2lkIHBhdGg6L2hvbWUvY3NlNDk2L2Jib2NrZWxtL3RtcC94cm9vdGRfZXhwb3J0LwowMDI0Y2lkIGJlZm9yZToyMDE4LTA2LTE1VDE4OjE5OjI5WgowMDJmc2lnbmF0dXJlIFXI_x3v8Tq1jYcP-2WUvPV-BIewn5MHRODVu8UszyYkCg' \
https://host.example.com//path/to/directory/hello_world
```
114 changes: 114 additions & 0 deletions src/XrdMacaroons/XrdMacaroons.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@

#include <stdexcept>
#include <dlfcn.h>

#include "XrdMacaroonsHandler.hh"
#include "XrdMacaroonsAuthz.hh"

#include "XrdOuc/XrdOucString.hh"
#include "XrdOuc/XrdOucPinPath.hh"
#include "XrdSys/XrdSysError.hh"
#include "XrdSys/XrdSysLogger.hh"
#include "XrdHttp/XrdHttpExtHandler.hh"
#include "XrdAcc/XrdAccAuthorize.hh"
#include "XrdVersion.hh"

XrdVERSIONINFO(XrdAccAuthorizeObject, XrdMacaroons);
XrdVERSIONINFO(XrdHttpGetExtHandler, XrdMacaroons);

// Trick to access compiled version and directly call for the default object
// is taken from xrootd-scitokens.
static XrdVERSIONINFODEF(compiledVer, XrdAccTest, XrdVNUMBER, XrdVERSION);
extern XrdAccAuthorize *XrdAccDefaultAuthorizeObject(XrdSysLogger *lp,
const char *cfn,
const char *parm,
XrdVersionInfo &myVer);


extern "C" {

XrdAccAuthorize *XrdAccAuthorizeObject(XrdSysLogger *log,
const char *config,
const char *parms)
{
XrdAccAuthorize *chain_authz;

if (parms && parms[0]) {
XrdOucString parms_str(parms);
XrdOucString chained_lib;
XrdSysError *err = new XrdSysError(log, "authlib");
int from = parms_str.tokenize(chained_lib, 0, ' ');
const char *chained_parms = NULL;
err->Emsg("Config", "Will chain library", chained_lib.c_str());
if (from > 0)
{
parms_str.erasefromstart(from);
if (parms_str.length())
{
err->Emsg("Config", "Will chain parameters", parms_str.c_str());
chained_parms = parms_str.c_str();
}
}
char resolvePath[2048];
bool usedAltPath{true};
if (!XrdOucPinPath(chained_lib.c_str(), usedAltPath, resolvePath, 2048)) {
err->Emsg("Config", "Failed to locate appropriately versioned chained auth library:", parms);
delete err;
return NULL;
}
void *handle_base = dlopen(resolvePath, RTLD_LOCAL|RTLD_NOW);
if (handle_base == NULL) {
err->Emsg("Config", "Failed to base plugin ", resolvePath, dlerror());
delete err;
return NULL;
}

XrdAccAuthorize *(*ep)(XrdSysLogger *, const char *, const char *);
ep = (XrdAccAuthorize *(*)(XrdSysLogger *, const char *, const char *))
(dlsym(handle_base, "XrdAccAuthorizeObject"));
if (!ep)
{
err->Emsg("Config", "Unable to chain second authlib after macaroons", parms);
delete err;
return NULL;
}
chain_authz = (*ep)(log, config, chained_parms);
}
else
{
chain_authz = XrdAccDefaultAuthorizeObject(log, config, parms, compiledVer);
}
try
{
return new Macaroons::Authz(log, config, chain_authz);
}
catch (std::runtime_error e)
{
XrdSysError err(log, "macaroons");
err.Emsg("Config", "Configuration of Macaroon authorization handler failed", e.what());
return NULL;
}
}


XrdHttpExtHandler *XrdHttpGetExtHandler(
XrdSysError *log, const char * config,
const char * parms, XrdOucEnv *env)
{
XrdAccAuthorize *def_authz = XrdAccDefaultAuthorizeObject(log->logger(),
config, parms, compiledVer);

log->Emsg("Initialize", "Creating new Macaroon handler object");
try
{
return new Macaroons::Handler(log, config, env, def_authz);
}
catch (std::runtime_error e)
{
log->Emsg("Config", "Generation of Macaroon handler failed", e.what());
return NULL;
}
}


}