--- /dev/null
+--- pam_pkcs11-0.5.3/src/tools/Makefile.am.setup 2006-07-07 13:46:34.000000000 +0200
++++ pam_pkcs11-0.5.3/src/tools/Makefile.am 2006-07-07 13:46:34.000000000 +0200
+@@ -8,11 +8,11 @@
+ AM_LDFLAGS = $(PCSC_LIBS)
+
+ if HAVE_PCSC
+-bin_PROGRAMS = card_eventmgr pkcs11_eventmgr pklogin_finder pkcs11_inspect
++bin_PROGRAMS = card_eventmgr pkcs11_eventmgr pklogin_finder pkcs11_inspect pkcs11_setup
+ card_eventmgr_SOURCES = card_eventmgr.c
+ card_eventmgr_LDADD = @LIBSCCONF@ @LIBCOMMON@
+ else
+-bin_PROGRAMS = pkcs11_eventmgr pklogin_finder pkcs11_inspect
++bin_PROGRAMS = pkcs11_eventmgr pklogin_finder pkcs11_inspect pkcs11_setup
+ endif
+
+ pklogin_finder_SOURCES = pklogin_finder.c
+@@ -23,3 +23,6 @@
+
+ pkcs11_inspect_SOURCES = pkcs11_inspect.c
+ pkcs11_inspect_LDADD = $(FINDER_OBJS) @LIBMAPPERS@
++
++pkcs11_setup_SOURCES = pkcs11_setup.c
++pkcs11_setup_LDADD = @LIBSCCONF@ @LIBCOMMON@
+--- pam_pkcs11-0.5.3/src/tools/Makefile.in.setup 2006-07-07 13:46:34.000000000 +0200
++++ pam_pkcs11-0.5.3/src/tools/Makefile.in 2006-07-07 13:46:34.000000000 +0200
+@@ -16,7 +16,7 @@
+
+ # Process this file with automake to create Makefile.in
+
+-SOURCES = $(card_eventmgr_SOURCES) $(pkcs11_eventmgr_SOURCES) $(pkcs11_inspect_SOURCES) $(pklogin_finder_SOURCES)
++SOURCES = $(card_eventmgr_SOURCES) $(pkcs11_eventmgr_SOURCES) $(pkcs11_inspect_SOURCES) $(pkcs11_setup_SOURCES) $(pklogin_finder_SOURCES)
+
+ srcdir = @srcdir@
+ top_srcdir = @top_srcdir@
+@@ -43,11 +43,11 @@
+ target_triplet = @target@
+ @HAVE_PCSC_FALSE@bin_PROGRAMS = pkcs11_eventmgr$(EXEEXT) \
+ @HAVE_PCSC_FALSE@ pklogin_finder$(EXEEXT) \
+-@HAVE_PCSC_FALSE@ pkcs11_inspect$(EXEEXT)
++@HAVE_PCSC_FALSE@ pkcs11_inspect$(EXEEXT) pkcs11_setup$(EXEEXT)
+ @HAVE_PCSC_TRUE@bin_PROGRAMS = card_eventmgr$(EXEEXT) \
+ @HAVE_PCSC_TRUE@ pkcs11_eventmgr$(EXEEXT) \
+ @HAVE_PCSC_TRUE@ pklogin_finder$(EXEEXT) \
+-@HAVE_PCSC_TRUE@ pkcs11_inspect$(EXEEXT)
++@HAVE_PCSC_TRUE@ pkcs11_inspect$(EXEEXT) pkcs11_setup$(EXEEXT)
+ subdir = src/tools
+ DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in
+ ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+@@ -73,6 +73,9 @@
+ am__DEPENDENCIES_2 = ../pam_pkcs11/mapper_mgr.o \
+ ../pam_pkcs11/pam_config.o
+ pkcs11_inspect_DEPENDENCIES = $(am__DEPENDENCIES_2)
++am_pkcs11_setup_OBJECTS = pkcs11_setup.$(OBJEXT)
++pkcs11_setup_OBJECTS = $(am_pkcs11_setup_OBJECTS)
++pkcs11_setup_DEPENDENCIES =
+ am_pklogin_finder_OBJECTS = pklogin_finder.$(OBJEXT)
+ pklogin_finder_OBJECTS = $(am_pklogin_finder_OBJECTS)
+ pklogin_finder_DEPENDENCIES = $(am__DEPENDENCIES_2)
+@@ -88,10 +91,11 @@
+ LINK = $(LIBTOOL) --tag=CC --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
+ $(AM_LDFLAGS) $(LDFLAGS) -o $@
+ SOURCES = $(card_eventmgr_SOURCES) $(pkcs11_eventmgr_SOURCES) \
+- $(pkcs11_inspect_SOURCES) $(pklogin_finder_SOURCES)
++ $(pkcs11_inspect_SOURCES) $(pkcs11_setup_SOURCES) \
++ $(pklogin_finder_SOURCES)
+ DIST_SOURCES = $(am__card_eventmgr_SOURCES_DIST) \
+ $(pkcs11_eventmgr_SOURCES) $(pkcs11_inspect_SOURCES) \
+- $(pklogin_finder_SOURCES)
++ $(pkcs11_setup_SOURCES) $(pklogin_finder_SOURCES)
+ ETAGS = etags
+ CTAGS = ctags
+ DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+@@ -188,6 +192,7 @@
+ ac_ct_F77 = @ac_ct_F77@
+ ac_ct_RANLIB = @ac_ct_RANLIB@
+ ac_ct_STRIP = @ac_ct_STRIP@
++ac_pt_PKG_CONFIG = @ac_pt_PKG_CONFIG@
+ am__fastdepCC_FALSE = @am__fastdepCC_FALSE@
+ am__fastdepCC_TRUE = @am__fastdepCC_TRUE@
+ am__fastdepCXX_FALSE = @am__fastdepCXX_FALSE@
+@@ -241,6 +246,8 @@
+ pkcs11_eventmgr_LDADD = @LIBSCCONF@ @LIBCOMMON@ $(CRYPTO_LIBS)
+ pkcs11_inspect_SOURCES = pkcs11_inspect.c
+ pkcs11_inspect_LDADD = $(FINDER_OBJS) @LIBMAPPERS@
++pkcs11_setup_SOURCES = pkcs11_setup.c
++pkcs11_setup_LDADD = @LIBSCCONF@ @LIBCOMMON@
+ all: all-am
+
+ .SUFFIXES:
+@@ -311,6 +318,9 @@
+ pkcs11_inspect$(EXEEXT): $(pkcs11_inspect_OBJECTS) $(pkcs11_inspect_DEPENDENCIES)
+ @rm -f pkcs11_inspect$(EXEEXT)
+ $(LINK) $(pkcs11_inspect_LDFLAGS) $(pkcs11_inspect_OBJECTS) $(pkcs11_inspect_LDADD) $(LIBS)
++pkcs11_setup$(EXEEXT): $(pkcs11_setup_OBJECTS) $(pkcs11_setup_DEPENDENCIES)
++ @rm -f pkcs11_setup$(EXEEXT)
++ $(LINK) $(pkcs11_setup_LDFLAGS) $(pkcs11_setup_OBJECTS) $(pkcs11_setup_LDADD) $(LIBS)
+ pklogin_finder$(EXEEXT): $(pklogin_finder_OBJECTS) $(pklogin_finder_DEPENDENCIES)
+ @rm -f pklogin_finder$(EXEEXT)
+ $(LINK) $(pklogin_finder_LDFLAGS) $(pklogin_finder_OBJECTS) $(pklogin_finder_LDADD) $(LIBS)
+@@ -324,6 +334,7 @@
+ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/card_eventmgr.Po@am__quote@
+ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pkcs11_eventmgr.Po@am__quote@
+ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pkcs11_inspect.Po@am__quote@
++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pkcs11_setup.Po@am__quote@
+ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pklogin_finder.Po@am__quote@
+
+ .c.o:
+--- /dev/null 2006-07-07 08:05:54.592713000 +0200
++++ pam_pkcs11-0.5.3/src/tools/pkcs11_setup.c 2006-07-07 13:54:45.000000000 +0200
+@@ -0,0 +1,519 @@
++/*
++ * PKCS#11 Card viewer tool
++ * Copyright (C) 2006 Red Hat, Inc.
++ *
++ * 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; either
++ * version 2.1 of the License, or (at your option) any later version.
++ *
++ * 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
++ * Lesser General Public License for more details.
++ *
++ */
++
++#define _GNU_SOURCE
++
++#ifdef HAVE_CONFIG_H
++#include <config.h>
++#endif
++
++#include <ctype.h>
++#include <string.h>
++#include <errno.h>
++#include <unistd.h>
++#include <stdio.h>
++#include <stdlib.h>
++#include <dlfcn.h>
++#include "../scconf/scconf.h"
++#include "../common/debug.h"
++#include "../common/error.h"
++
++#define PAM_PKCS11_CONF "/etc/pam_pkcs11/pam_pkcs11.conf"
++#define EVENTMGR_CONF "/etc/pam_pkcs11/pkcs11_eventmgr.conf"
++
++static const char Ins_action[] = "ins_action=";
++static const char Rm_action[] = "rm_action=";
++static const char Use_module[] = "use_module=";
++static const char List_modules[] = "list_modules";
++
++enum params { INS_ACTION, RM_ACTION, USE_MODULE, LIST_MODULES };
++
++static const char const *param_names[] = { Ins_action, Rm_action, Use_module, List_modules };
++static int pn_sizes[] = { sizeof(Ins_action), sizeof(Rm_action), sizeof(Use_module), sizeof(List_modules) };
++
++#define NUM_PARAMS (sizeof(param_names)/sizeof(param_names[0]))
++
++const char *scconf_replace_str(scconf_block * block, const char *option, const char *value)
++{
++ scconf_list *list = NULL;
++ scconf_item *item;
++
++ scconf_list_add(&list, value);
++ item = scconf_item_add(NULL, block, NULL, SCCONF_ITEM_TYPE_VALUE, option, list);
++
++ /* now clear out the item list */
++ scconf_list_destroy(item->value.list);
++ item->value.list = list; /* adopt */
++ return value;
++}
++
++int scconf_replace_str_list(scconf_block * block, const char *option, const char *value)
++{
++ scconf_list *list = NULL;
++ scconf_item *item;
++ char *lstitem = NULL;
++ char *next;
++
++ while (value != NULL) {
++ if ((next=strchr(value, ',')) != NULL) {
++ lstitem = strndup(value, next-value);
++ next++;
++ }
++ else {
++ lstitem = strdup(value);
++ }
++ if (lstitem == NULL)
++ return 1;
++ scconf_list_add(&list, lstitem);
++ value = next;
++ free(lstitem);
++ }
++
++ item = scconf_item_add(NULL, block, NULL, SCCONF_ITEM_TYPE_VALUE, option, list);
++
++ /* now clear out the item list */
++ scconf_list_destroy(item->value.list);
++ item->value.list = list; /* adopt */
++ return 0;
++}
++
++int list_modules(void)
++{
++ const scconf_block *pam_pkcs11;
++ scconf_block **pkcs11_blocks;
++ scconf_context *ctx = NULL;
++ int i;
++ int result = 1;
++
++ /*
++ * loop through looking for smart card entries
++ */
++ ctx = scconf_new(PAM_PKCS11_CONF);
++ if (ctx == NULL) {
++ goto bail;
++ }
++ if (scconf_parse(ctx) <= 0 ) {
++ goto bail;
++ }
++ pam_pkcs11 = scconf_find_block(ctx, NULL, "pam_pkcs11");
++ if (!pam_pkcs11) {
++ goto bail;
++ }
++ pkcs11_blocks = scconf_find_blocks(ctx, pam_pkcs11, "pkcs11_module", NULL);
++ if (!pkcs11_blocks) {
++ goto bail;
++ }
++
++ /* list only those smart cards which are actually installed */
++ for (i=0; pkcs11_blocks[i]; i++) {
++ void *libhandle;
++ const char *path =
++ scconf_get_str(pkcs11_blocks[i], "module", NULL);
++ /* check to see if the module exists on the system */
++ if (!path || *path == 0) {
++ continue;
++ }
++ /* verify the module exists */
++ if ((libhandle=dlopen(path, RTLD_LAZY)) != NULL) {
++ dlclose(libhandle);
++ if (pkcs11_blocks[i] && pkcs11_blocks[i]->name
++ && pkcs11_blocks[i]->name->data) {
++ printf("%s\n", pkcs11_blocks[i]->name->data);
++ }
++ }
++ }
++
++ result = 0;
++
++bail:
++ if (ctx) {
++ scconf_free(ctx);
++ }
++ return result;
++}
++
++int print_default_module(void)
++{
++ const scconf_block *pam_pkcs11;
++ scconf_context *ctx = NULL;
++ int result = 1;
++
++ /*
++ * read the base pam_pkcs11.conf
++ */
++ ctx = scconf_new(PAM_PKCS11_CONF);
++ if (ctx == NULL) {
++ goto bail;
++ }
++ if (scconf_parse(ctx) <= 0) {
++ goto bail;
++ }
++ pam_pkcs11 = scconf_find_block(ctx, NULL, "pam_pkcs11");
++ if (!pam_pkcs11) {
++ goto bail;
++ }
++ printf("%s\n", scconf_get_str(pam_pkcs11, "use_pkcs11_module", ""));
++ result = 0;
++
++ bail:
++ if (ctx) {
++ scconf_free(ctx);
++ }
++ ctx = NULL;
++
++ return result;
++}
++
++int set_default_module(const char *mod)
++{
++ scconf_block *pam_pkcs11, *pkcs11_eventmgr;
++ scconf_block **modules = NULL;
++ scconf_context *ctx = NULL;
++ scconf_context *ectx = NULL;
++ const char *lib = NULL;
++ int result = 1;
++
++ /*
++ * write out pam_pkcs11.conf
++ */
++ ctx = scconf_new(PAM_PKCS11_CONF);
++ if (ctx == NULL) {
++ goto bail;
++ }
++ if (scconf_parse(ctx) <= 0) {
++ goto bail;
++ }
++ pam_pkcs11 = (scconf_block *)scconf_find_block(ctx, NULL, "pam_pkcs11");
++ if (!pam_pkcs11) {
++ goto bail;
++ }
++ scconf_replace_str(pam_pkcs11, "use_pkcs11_module", mod);
++
++ modules = scconf_find_blocks(ctx, pam_pkcs11, "pkcs11_module", mod);
++ if (!modules || !modules[0]) {
++ goto bail;
++ }
++ lib = scconf_get_str(modules[0], "module", NULL);
++ if (!lib) {
++ goto bail;
++ }
++ result = scconf_write(ctx, NULL);
++ if (result != 0) {
++ goto bail;
++ }
++
++ ectx = scconf_new(EVENTMGR_CONF);
++ if (ectx == NULL) {
++ goto bail;
++ }
++ if (scconf_parse(ectx) <= 0) {
++ goto bail;
++ }
++ pkcs11_eventmgr = (scconf_block *)
++ scconf_find_block(ectx, NULL, "pkcs11_eventmgr");
++ if (!pkcs11_eventmgr) {
++ goto bail;
++ }
++ scconf_replace_str(pkcs11_eventmgr, "pkcs11_module", lib);
++ result = scconf_write(ectx, NULL);
++
++bail:
++ if (modules) {
++ free(modules);
++ }
++ if (ctx) {
++ scconf_free(ctx);
++ }
++ if (ectx) {
++ scconf_free(ectx);
++ }
++
++ return result;
++}
++
++int print_card_insert_action(void)
++{
++ const scconf_block *pkcs11_eventmgr;
++ scconf_block **event_blocks = NULL;
++ scconf_context *ctx = NULL;
++ const scconf_list *actionList = NULL;
++ int result = 1;
++
++ /*
++ * read the pkcs11_eventmgr.conf to get our action
++ */
++ ctx = scconf_new(EVENTMGR_CONF);
++ if (ctx == NULL) {
++ goto bail;
++ }
++ if (scconf_parse(ctx) <= 0) {
++ goto bail;
++ }
++ pkcs11_eventmgr = scconf_find_block(ctx, NULL, "pkcs11_eventmgr");
++ if (!pkcs11_eventmgr) {
++ goto bail;
++ }
++ event_blocks = scconf_find_blocks(ctx, pkcs11_eventmgr, "event",
++ "card_insert");
++ if (!event_blocks || !event_blocks[0]) {
++ goto bail;
++ }
++ actionList = scconf_find_list(event_blocks[0],"action");
++ if (actionList) {
++ char *lst = scconf_list_strdup(actionList, "\n");
++ if (lst != NULL) {
++ printf("%s\n", lst);
++ free(lst);
++ }
++ }
++ result = 0;
++
++bail:
++ if (event_blocks) {
++ free(event_blocks);
++ }
++ if (ctx) {
++ scconf_free(ctx);
++ }
++
++ return result;
++}
++
++int set_card_insert_action(const char *act)
++{
++ scconf_block *pkcs11_eventmgr;
++ scconf_block **insert_blocks = NULL;
++ scconf_context *ctx = NULL;
++ int result = 1;
++
++ /*
++ * write out pkcs11_eventmgr.conf
++ */
++ ctx = scconf_new(EVENTMGR_CONF);
++ if (ctx == NULL) {
++ goto bail;
++ }
++ if (scconf_parse(ctx) <= 0) {
++ goto bail;
++ }
++ pkcs11_eventmgr = (scconf_block *)
++ scconf_find_block(ctx, NULL, "pkcs11_eventmgr");
++ if (!pkcs11_eventmgr) {
++ goto bail;
++ }
++ insert_blocks = scconf_find_blocks(ctx, pkcs11_eventmgr,
++ "event", "card_insert");
++ if (!insert_blocks || !insert_blocks[0]) {
++ goto bail;
++ }
++
++ scconf_replace_str_list(insert_blocks[0], "action", act);
++
++ result = scconf_write(ctx, NULL);
++
++bail:
++ if (insert_blocks) {
++ free(insert_blocks);
++ }
++ if (ctx) {
++ scconf_free(ctx);
++ }
++ return result;
++}
++
++int print_card_remove_action(void)
++{
++ const scconf_block *pkcs11_eventmgr;
++ scconf_block **event_blocks = NULL;
++ scconf_context *ctx = NULL;
++ const scconf_list *actionList = NULL;
++ int result = 1;
++
++ /*
++ * read the pkcs11_eventmgr.conf to get our action
++ */
++ ctx = scconf_new(EVENTMGR_CONF);
++ if (ctx == NULL) {
++ goto bail;
++ }
++ if (scconf_parse(ctx) <= 0) {
++ goto bail;
++ }
++ pkcs11_eventmgr = scconf_find_block(ctx, NULL, "pkcs11_eventmgr");
++ if (!pkcs11_eventmgr) {
++ goto bail;
++ }
++ event_blocks = scconf_find_blocks(ctx, pkcs11_eventmgr, "event",
++ "card_remove");
++ if (!event_blocks || !event_blocks[0]) {
++ goto bail;
++ }
++ actionList = scconf_find_list(event_blocks[0],"action");
++ if (actionList) {
++ char *lst = scconf_list_strdup(actionList, "\n");
++ if (lst != NULL) {
++ printf("%s\n", lst);
++ free(lst);
++ }
++ }
++ result = 0;
++
++bail:
++ if (event_blocks) {
++ free(event_blocks);
++ }
++ if (ctx) {
++ scconf_free(ctx);
++ }
++
++ return result;
++}
++
++int set_card_remove_action(const char *act)
++{
++ scconf_block *pkcs11_eventmgr;
++ scconf_block **insert_blocks = NULL;
++ scconf_context *ctx = NULL;
++ int result = 1;
++
++ /*
++ * write out pkcs11_eventmgr.conf
++ */
++ ctx = scconf_new(EVENTMGR_CONF);
++ if (ctx == NULL) {
++ goto bail;
++ }
++ if (scconf_parse(ctx) <= 0) {
++ goto bail;
++ }
++ pkcs11_eventmgr = (scconf_block *)
++ scconf_find_block(ctx, NULL, "pkcs11_eventmgr");
++ if (!pkcs11_eventmgr) {
++ goto bail;
++ }
++ insert_blocks = scconf_find_blocks(ctx, pkcs11_eventmgr,
++ "event", "card_remove");
++ if (!insert_blocks || !insert_blocks[0]) {
++ goto bail;
++ }
++
++ scconf_replace_str_list(insert_blocks[0], "action", act);
++
++ result = scconf_write(ctx, NULL);
++
++bail:
++ if (insert_blocks) {
++ free(insert_blocks);
++ }
++ if (ctx) {
++ scconf_free(ctx);
++ }
++ return result;
++}
++
++int main(int argc, const char **argv)
++{
++ int i;
++ int pname;
++ const char *params[NUM_PARAMS];
++
++ memset(params, '\0', sizeof(params));
++
++ for (i = 1; i < argc; i++) {
++ for (pname = 0; pname < NUM_PARAMS; pname++) {
++ if (param_names[pname][pn_sizes[pname]-2] == '=') {
++ if (strncmp(argv[i], param_names[pname], pn_sizes[pname]-1) == 0) {
++ params[pname] = argv[i] + pn_sizes[pname] - 1;
++ }
++ else if (strncmp(argv[i], param_names[pname], pn_sizes[pname]-2) == 0
++ && argv[i][pn_sizes[pname]-2] == '\0') {
++ params[pname] = (void *)1;
++ }
++ }
++ else {
++ if (strcmp(argv[i], param_names[pname]) == 0) {
++ params[pname] = (void *)1;
++ }
++ }
++ }
++ }
++
++ for (pname = 0; pname < NUM_PARAMS; pname++) {
++ if (params[pname] != NULL)
++ break;
++ }
++
++ if (pname == NUM_PARAMS) {
++ DBG("No correct parameter specified");
++ printf("usage: pkcs11_setup [list_modules] [use_module[=<module_name>]]\n"
++ " [ins_action[=<executable,executable,...>]]\n"
++ " [rm_action[=<executable,executable,...>]]\n");
++ }
++
++ if (params[LIST_MODULES] != NULL) {
++ DBG("List modules:");
++ return list_modules();
++ }
++ else {
++ if (params[USE_MODULE] == (void *)1) {
++ DBG("Print default module:");
++ if ((i=print_default_module()) != 0) {
++ DBG1("Print default module failed with: %d", i);
++ return i;
++ }
++ return 0;
++ }
++ else if (params[USE_MODULE] != NULL) {
++ DBG1("Set default module: %s", params[USE_MODULE]);
++ if ((i=set_default_module(params[USE_MODULE])) != 0) {
++ DBG1("Set default module failed with: %d", i);
++ return i;
++ }
++ }
++ if (params[INS_ACTION] == (void *)1) {
++ DBG("Print card insert action:");
++ if ((i=print_card_insert_action()) != 0) {
++ DBG1("Print card insert action failed with: %d", i);
++ return i;
++ }
++ return 0;
++ }
++ else if (params[INS_ACTION] != NULL) {
++ DBG1("Set card insert action: %s", params[INS_ACTION]);
++ if ((i=set_card_insert_action(params[INS_ACTION])) != 0) {
++ DBG1("Set card insert action failed with: %d", i);
++ return i;
++ }
++ }
++ if (params[RM_ACTION] == (void *)1) {
++ DBG("Print card remove action:");
++ if ((i=print_card_remove_action()) != 0) {
++ DBG1("Set card remove action failed with: %d", i);
++ return i;
++ }
++ return 0;
++ }
++ else if (params[RM_ACTION] != NULL) {
++ DBG1("Set card remove action: %s", params[RM_ACTION]);
++ if ((i=set_card_remove_action(params[RM_ACTION])) != 0) {
++ DBG1("Set card remove action failed with: %d", i);
++ return i;
++ }
++ }
++ }
++ DBG("Process completed");
++ return 0;
++}