major source structure and module name changes

This commit is contained in:
soochoi
2006-06-07 16:34:19 +00:00
parent 5c75241b4b
commit 1fa6f07e83
651 changed files with 0 additions and 0 deletions

View File

@@ -0,0 +1,37 @@
#######################################################################
#
# Copyright (C) 2006 Novell, 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 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.
#
# Author: Juan Carlos Luciani <jluciani@novell.com>
#
#######################################################################
SUBDIRS = $(TARGET_OS)
DIST_SUBDIRS = linux
CFILES =
EXTRA_DIST = $(CFILES) *.h
.PHONY: package package-clean package-install package-uninstall
package package-clean package-install package-uninstall:
$(MAKE) -C $(TARGET_OS) $@
maintainer-clean-local:
rm -f Makefile.in

View File

@@ -0,0 +1,108 @@
/***********************************************************************
*
* README for mod_authn_casa
*
***********************************************************************/
INTRODUCTION
mod_authn_casa is an Apache 2.2 Basic Authentication Provider that
can be configured to validate Basic Credentials carrying CASA
Authentication Tokens.
Clients sending CASA Authentication Tokens as part of the Basic Credentials
will format them in the following manner: "username:CasaAuthenticationToken",
where the username is set to "CasaPrincipal" and the CasaAuthenticationToken
is the token string obtained from the CASA Get Authentication Token API..
CONFIGURATION
To use mod_authn_casa as an authentication provider for a specific location
you must first tell Apache that it must load the module, you do this by
placing the module or a link to the module in the Apache server's modules
folder and by placing the following line in the server's httpd.conf file:
LoadModule authn_casa_module modules/mod_authn_casa.so
The following lines show how Apache is configured to use mod_authn_casa
for authenticating requests issued to mod_example:
<Location /example-info>
SetHandler example-handler
AuthType Basic
AuthName "CASA-Authentication"
AuthBasicProvider casa
Require valid-user
</Location>
Note that the name specified in the AuthName directive should match the name
configured under CASA for the authentication realm used by CASA to obtain
identity information for the service.
mod_authn_casa supports the following configuration directives:
UsernameCheck - This is a per-directory or per-location directive which
configures whether or not mod_authn_casa must verify that
the username is set to "CasaPrincipal". Possible values
for this directive are 'on' or 'off'. Default is 'off'.
To enable UsernameChack for a particular location using
CASA Authentication, include the following line inside
the location configuration block:
UsernameCheck on
CLIENT PROGRAMMING NOTES
HTTP Clients sending requests to a location being protected by the CASA
Authentication Provider must obtain an Authentication Token from the CASA
Client for authenticating to the Service identified as the "location" being
accessed in the HTTP Server. In the case of mod_example, the service name
would be "example-info". Once the client obtains an Authentication Token
from the CASA Client it must then include it in the HTTP Basic Authentication
header that it must include in the HTTP Request. The HTTP Basic Authentication
credentials should be in the following form:
Base64("CasaPrincipal":"AuthenticationToken")
SERVER PROGRAMMING NOTES
Apache modules being protected by the CASA Authentication Provider can obtain
the following information about the authenticated identity:
username - This is accessed via the r->user variable or by examining the IdentityId
environment variable associated with the request block. The username is the
user's unique id within the authentication realm. When the authentication realm
is an LDAP database, the username consists of the user's fdn.
Name of the source of identity data (Authentication Realm) - This is accessed by
examining the IdentityDataSourceName environment variable associated with the
request block.
URL to the source of identity data - This is accessed by examining the
IdentityDataSourceUrl environment variable associated with the request block.
Attributes of the authenticated identity - The attributes are set as environment
variables associated with the request block. The environment variable names match
the names of the attributes. The attributes associated with the authenticated
identity and expressed as environment variables are configured at the time that
the service is enabled for CASA Authentication.
Note that environment variables are contained in the r->subprocess_env table.
SECURITY CONSIDERATIONS
CASA Authenticatication Tokens when compromised can be used to either impersonate
a user or to obtain identity information about the user. Because of this it is
important that the tokens be secured by applications making use of them. It is
recommended that the tokens be transmitted using HTTPS.

View File

@@ -0,0 +1,13 @@
/***********************************************************************
*
* TODO for mod_authn_casa
*
***********************************************************************/
INTRODUCTION
This file contains a list of the items still outstanding for mod_authn_casa.
OUTSTANDING ITEMS
None.

View File

@@ -0,0 +1,111 @@
#######################################################################
#
# Copyright (C) 2006 Novell, 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 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.
#
# Author: Juan Carlos Luciani <jluciani@novell.com>
#
#######################################################################
if DEBUG
TARGET_CFG = Debug
CFLAGS += -v -w
else
TARGET_CFG = Release
endif
SUBDIRS =
DIST_SUBDIRS =
CASAROOT = ../../../../..
CASALIBDIR = $(CASAROOT)/$(LIB)
APACHEROOT = /home/jluciani/dev-local/apache2.2
# handle Mono secondary dependencies
export MONO_PATH := $(MONO_PATH)
PLATFORMINDEPENDENTSOURCEDIR = ..
PLATFORMDEPENDENTSOURCEDIR = .
MODULE_NAME = mod_authn_casa
MODULE_EXT = so
CFILES = ../mod_authn_casa.c
CSFILES_CSC :=
INCLUDES = -I. -I$(CASAROOT)/include -I$(APACHEROOT)/include
RESOURCES =
DEFINES = -Wno-format-extra-args -fno-strict-aliasing
CFLAGS += $(INCLUDES) $(DEFINES) -D_LARGEFILE64_SOURCE
LIBS = -lpthread -lcasa_s_authtoken -lapr-1 -laprutil-1
LDFLAGS = -Bsymbolic -shared -Wl,-soname=$(MODULE_NAME).$(MODULE_EXT) -L$(CASALIBDIR)/$(TARGET_CFG) -L$(APACHEROOT)/lib -Xlinker -rpath -Xlinker /opt/novell/CASA/lib
OBJDIR = ./$(TARGET_CFG)/$(LIB)
OBJS = $(addprefix $(OBJDIR)/, $(CFILES:%.c=%.o))
EXTRA_DIST = $(CFILES)
CUR_DIR := $(shell pwd)
all: $(OBJDIR)/$(MODULE_NAME).$(MODULE_EXT)
#
# Pattern based rules.
#
vpath %.c $(PLATFORMDEPENDENTSOURCEDIR) $(PLATFORMINDEPENDENTSOURCEDIR)
vpath %.cpp $(PLATFORMDEPENDENTSOURCEDIR) $(PLATFORMINDEPENDENTSOURCEDIR)
$(OBJDIR)/%.o: %.c
$(CC) -c $(CFLAGS) -o $@ $<
$(OBJDIR)/%.o: %.cpp
$(CC) -c $(CFLAGS) -o $@ $<
$(OBJDIR)/$(MODULE_NAME).$(MODULE_EXT): $(OBJDIR) $(OBJS)
@echo [======== Linking $@ ========]
$(LINK) -o $@ $(LDFLAGS) $(OBJS) $(LIBS)
cp -f $(OBJDIR)/$(MODULE_NAME).$(MODULE_EXT) $(CASALIBDIR)/$(TARGET_CFG)/$(MODULE_NAME).$(MODULE_EXT)
$(OBJDIR):
[ -d $(OBJDIR) ] || mkdir -p $(OBJDIR)
[ -d $(CASALIBDIR) ] || mkdir -p $(CASALIBDIR)
[ -d $(CASALIBDIR)/$(TARGET_CFG) ] || mkdir -p $(CASALIBDIR)/$(TARGET_CFG)
install-exec-local: $(OBJDIR)/$(MODULE_NAME).$(MODULE_EXT)
$(mkinstalldirs) $(DESTDIR)$(libdir)
$(INSTALL_PROGRAM) $(OBJDIR)/$(MODULE_NAME).$(MODULE_EXT) $(DESTDIR)$(libdir)/
uninstall-local:
cd $(DESTDIR)$(libdir); rm -f $(OBJDIR)/$(MODULE_NAME).$(MODULE_EXT)
rmdir $(DESTDIR)$(libdir)
#installcheck-local: install
# $(mkinstalldirs) $(DESTDIR)$(libdir)
# $(INSTALL_PROGRAM) $(DESTDIR)$(libdir)
# cd $(DESTDIR)$(libdir); $(MONO)
clean-local:
#cd $(TARGET_CFG); rm -rf *.dbg *.exe *.dll *.o *.so; cd ..; rmdir $(OBJDIR)
rm -rf $(TARGET_CFG)
distclean-local:
maintainer-clean-local:
rm -f Makefile.in

View File

@@ -0,0 +1,478 @@
/***********************************************************************
*
* Copyright (C) 2006 Novell, Inc. All Rights Reserved.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; version 2.1
* of the License.
*
* This library 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
* Library Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, Novell, Inc.
*
* To contact Novell about this file by physical or electronic mail,
* you may find current contact information at www.novell.com.
*
* Author: Juan Carlos Luciani <jluciani@novell.com>
*
***********************************************************************/
#include <stdbool.h>
#include "apr_strings.h"
#include "ap_config.h"
#include "ap_provider.h"
#include "httpd.h"
#include "http_config.h"
#include "http_core.h"
#include "http_log.h"
#include "http_protocol.h"
#include "http_request.h"
#include "mod_auth.h"
#include "casa_s_authtoken.h"
//
// Module per-dir configuration structure.
//
typedef struct _authn_casa_dir_cfg
{
int performUsernameCheck;
} authn_casa_dir_cfg;
//
// Forward declaration of our module structure.
//
module AP_MODULE_DECLARE_DATA authn_casa_module;
//
// Environment variables set by module
//
static char CasaIdentityIdEnvVar[] = "IdentityId";
static char CasaIdentitySourceNameEnvVar[] = "IdentityDataSourceName";
static char CasaIdentitySourceUrlEnvVar[] = "IdentityDataSourceUrl";
//
// Function: create_per_dir_config()
//
// Create per-dir configuration structure.
//
static void*
create_per_dir_config(
apr_pool_t *p,
char *x)
{
authn_casa_dir_cfg *pDirConfig;
// Allocate space for our configuration structure
pDirConfig = (authn_casa_dir_cfg*) apr_palloc(p, sizeof(*pDirConfig));
// Return our new configuration structure
return (void*) pDirConfig;
}
/* ************************************************************************
* set_authn_casa_uname_check()
*
* Process UsernameCheck configuration directive..
*
* L2
* ************************************************************************/
static const char*
set_authn_casa_uname_check(
cmd_parms *cmd,
void *cfg,
int arg)
{
authn_casa_dir_cfg *pDirConfig = (authn_casa_dir_cfg*) cfg;
// Record the value in our structure
pDirConfig->performUsernameCheck = arg;
return NULL;
}
//
// Configuration directives array structure.
//
static const command_rec authn_casa_cmds[] =
{
AP_INIT_FLAG("UsernameCheck", // tbd - May be this directive should be on a per-directory or per-location basis
set_authn_casa_uname_check,
NULL,
OR_AUTHCFG,
"Check for username == CasaPrincipal (Value limited to 'on' or 'off')"),
{NULL}
};
/* ************************************************************************
* check_password()
*
* Given a user and password, expected to return AUTH_GRANTED if we
* can validate the user/password combination.
*
* L2
* ************************************************************************/
static authn_status
check_password(
request_rec *r,
const char *user,
const char *password)
{
authn_status retStatus;
authn_casa_dir_cfg *pDirConfig;
bool userNameChecked = false;
int i;
char *pLocationName;
// First determine the length of the name of the location being protected
i = 0;
while (r->uri[i] != '\0')
{
if (r->uri[i] == '/')
{
// Ignore the slash if it is at the beginning of the uri
if (i != 0)
{
// The slash is not at the beggining of the uri, stop.
break;
}
}
i++;
}
// Now get a copy of the location being protected
if (i > 1)
{
pLocationName = apr_palloc(r->pool, i);
if (pLocationName)
{
memset(pLocationName, 0, i);
memcpy(pLocationName, &(r->uri[1]), i - 1); // Do not include the slashes
}
else
{
ap_log_rerror(APLOG_MARK, APLOG_ALERT, 0, r, "Memory allocation failure");
return AUTH_GENERAL_ERROR;
}
}
else
{
// We are protecting the server root
pLocationName = "apache_root";
}
// Get access to our per-dir configuration structure
pDirConfig = ap_get_module_config(r->per_dir_config,
&authn_casa_module);
if (pDirConfig)
{
// Assume success
retStatus = AUTH_GRANTED;
// Check if we must perform the username check
if (pDirConfig->performUsernameCheck != 0)
{
// Remember that we performed this check
userNameChecked = true;
// Check if the username matches the name what we are expecting
if (strcmp(user, "CasaPrincipal") != 0)
{
// The username does not match, allow other providers to get
// a crack to it.
retStatus = AUTH_USER_NOT_FOUND;
}
}
// Check the token if a problem has not been found
if (retStatus == AUTH_GRANTED)
{
CasaStatus casaStatus;
PrincipalIf *pPrincipalIf;
// Validate the token
casaStatus = ValidateAuthToken(pLocationName,
password,
strlen(password),
&pPrincipalIf);
if (CASA_SUCCESS(casaStatus))
{
int buffLen = 0;
apr_table_t *e = r->subprocess_env;
// Associate necessary environment variables with the request block
casaStatus = pPrincipalIf->getIdentityId(pPrincipalIf,
NULL,
&buffLen);
if (CasaStatusCode(casaStatus) == CASA_STATUS_BUFFER_OVERFLOW)
{
char *pBuff;
// Allocate buffer to obtain the Identity Id
pBuff = apr_pcalloc(r->pool, buffLen);
if (pBuff)
{
// Read the value into our buffer
if (CASA_SUCCESS(pPrincipalIf->getIdentityId(pPrincipalIf,
pBuff,
&buffLen)))
{
// Now set the environment variable
apr_table_setn(e, CasaIdentityIdEnvVar, pBuff);
// Also, update the username within the request block with the identity id
r->user = pBuff;
}
else
{
ap_log_rerror(APLOG_MARK, APLOG_ALERT, 0, r, "Unable to obtain identity id");
retStatus = AUTH_GENERAL_ERROR;
}
}
else
{
ap_log_rerror(APLOG_MARK, APLOG_ALERT, 0, r, "Memory allocation failure");
retStatus = AUTH_GENERAL_ERROR;
}
}
else
{
ap_log_rerror(APLOG_MARK, APLOG_ALERT, 0, r, "Un-expected error obtaining identity id, %08X", casaStatus);
retStatus = AUTH_GENERAL_ERROR;
}
if (retStatus == AUTH_GRANTED)
{
buffLen = 0;
casaStatus = pPrincipalIf->getSourceName(pPrincipalIf,
NULL,
&buffLen);
if (CasaStatusCode(casaStatus) == CASA_STATUS_BUFFER_OVERFLOW)
{
char *pBuff;
// Allocate buffer to obtain the Identity Source Name
pBuff = apr_pcalloc(r->pool, buffLen);
if (pBuff)
{
// Read the value into our buffer
if (CASA_SUCCESS(pPrincipalIf->getSourceName(pPrincipalIf,
pBuff,
&buffLen)))
{
// Now set the environment variable
apr_table_setn(e, CasaIdentitySourceNameEnvVar, pBuff);
}
else
{
ap_log_rerror(APLOG_MARK, APLOG_ALERT, 0, r, "Unable to obtain identity source name");
retStatus = AUTH_GENERAL_ERROR;
}
}
else
{
ap_log_rerror(APLOG_MARK, APLOG_ALERT, 0, r, "Memory allocation failure");
retStatus = AUTH_GENERAL_ERROR;
}
}
else
{
ap_log_rerror(APLOG_MARK, APLOG_ALERT, 0, r, "Un-expected error obtaining identity source name, %08X", casaStatus);
retStatus = AUTH_GENERAL_ERROR;
}
}
if (retStatus == AUTH_GRANTED)
{
buffLen = 0;
casaStatus = pPrincipalIf->getSourceUrl(pPrincipalIf,
NULL,
&buffLen);
if (CasaStatusCode(casaStatus) == CASA_STATUS_BUFFER_OVERFLOW)
{
char *pBuff;
// Allocate buffer to obtain the Identity Source Url
pBuff = apr_pcalloc(r->pool, buffLen);
if (pBuff)
{
// Read the value into our buffer
if (CASA_SUCCESS(pPrincipalIf->getSourceUrl(pPrincipalIf,
pBuff,
&buffLen)))
{
// Now set the environment variable
apr_table_setn(e, CasaIdentitySourceUrlEnvVar, pBuff);
}
else
{
ap_log_rerror(APLOG_MARK, APLOG_ALERT, 0, r, "Unable to obtain identity source url");
retStatus = AUTH_GENERAL_ERROR;
}
}
else
{
ap_log_rerror(APLOG_MARK, APLOG_ALERT, 0, r, "Memory allocation failure");
retStatus = AUTH_GENERAL_ERROR;
}
}
else
{
ap_log_rerror(APLOG_MARK, APLOG_ALERT, 0, r, "Un-expected error obtaining identity source url, %08X", casaStatus);
retStatus = AUTH_GENERAL_ERROR;
}
}
if (retStatus == AUTH_GRANTED)
{
char *pAttribNameBuff, *pAttribValueBuff;
int enumHandle = 0;
int attribNameBuffLen, attribValueBuffLen;
while (retStatus == AUTH_GRANTED)
{
// Get attribute lengths
attribNameBuffLen = attribValueBuffLen = 0;
casaStatus = pPrincipalIf->attributeEnumerate(pPrincipalIf,
&enumHandle,
NULL,
&attribNameBuffLen,
NULL,
&attribValueBuffLen);
if (CasaStatusCode(casaStatus) == CASA_STATUS_BUFFER_OVERFLOW)
{
// Allocate buffers to obtain the attribute data
pAttribNameBuff = apr_pcalloc(r->pool, attribNameBuffLen);
pAttribValueBuff = apr_pcalloc(r->pool, attribValueBuffLen);
if (pAttribNameBuff && pAttribValueBuff)
{
// Read the attribute into our buffer
if (CASA_SUCCESS(pPrincipalIf->attributeEnumerate(pPrincipalIf,
&enumHandle,
pAttribNameBuff,
&attribNameBuffLen,
pAttribValueBuff,
&attribValueBuffLen)))
{
// Now set the environment variable
apr_table_setn(e, pAttribNameBuff, pAttribValueBuff);
}
else
{
ap_log_rerror(APLOG_MARK, APLOG_ALERT, 0, r, "Unable to obtain identity attribute");
retStatus = AUTH_GENERAL_ERROR;
}
}
else
{
ap_log_rerror(APLOG_MARK, APLOG_ALERT, 0, r, "Memory allocation failure");
retStatus = AUTH_GENERAL_ERROR;
}
}
else
{
// Check if we are done going through the attributes
if (CasaStatusCode(casaStatus) == CASA_STATUS_NO_MORE_ENTRIES)
{
// Done
break;
}
else
{
ap_log_rerror(APLOG_MARK, APLOG_ALERT, 0, r, "Un-expected error during attribute enumeration, %08X", casaStatus);
retStatus = AUTH_GENERAL_ERROR;
}
}
}
}
// Release the principal interface instance
pPrincipalIf->releaseReference(pPrincipalIf);
}
else
{
// Check if the token validation failed for a CasaPrincipal
if (userNameChecked)
{
// Token validation failed for a CasaPrincipal, always return AUTH_DENIED.
retStatus = AUTH_DENIED;
}
else
{
// We did not check the username, set the return status based on the status
// returned by ValidateAuthToken().
if (CasaStatusCode(casaStatus) == CASA_STATUS_AUTHENTICATION_FAILURE)
{
// Authentication failed
retStatus = AUTH_DENIED;
}
else
{
// Allow other providers to get a crack to it
retStatus = AUTH_USER_NOT_FOUND;
}
}
}
}
}
else
{
ap_log_rerror(APLOG_MARK, APLOG_ALERT, 0, r, "Did not get module per-server config structure");
retStatus = AUTH_GENERAL_ERROR;
}
return retStatus;
}
//
// Authentication Provider Function Table
//
static const authn_provider authn_casa_provider =
{
&check_password,
NULL, // We do not support Digest Authentication
};
/* ************************************************************************
* register_hooks()
*
* Register all of the module hooks.
*
* L2
* ************************************************************************/
static void
register_hooks(
apr_pool_t *p)
{
// Register as an authentication provider
ap_register_provider(p,
AUTHN_PROVIDER_GROUP, // Provider group
"casa", // Provider name
"0", // Provider version
&authn_casa_provider); // Authentication Provider function table
}
//
// Declare ourselves to the HTTPD core.
//
module AP_MODULE_DECLARE_DATA authn_casa_module =
{
STANDARD20_MODULE_STUFF,
create_per_dir_config, // Create per-dir config structures
NULL, // merge per-dir config structures
NULL, // Create per-server config structures
NULL, // merge per-server config structures
authn_casa_cmds, // command handlers
register_hooks // register hooks
};

View File

@@ -0,0 +1,37 @@
#######################################################################
#
# Copyright (C) 2006 Novell, 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 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.
#
# Author: Juan Carlos Luciani <jluciani@novell.com>
#
#######################################################################
SUBDIRS = 2.2
DIST_SUBDIRS = 2.2
CFILES =
EXTRA_DIST = $(CFILES)
.PHONY: package package-clean package-install package-uninstall
package package-clean package-install package-uninstall:
$(MAKE) -C $(TARGET_OS) $@
maintainer-clean-local:
rm -f Makefile.in