pluginviewer.c   pluginviewer.c 
/* pluginviewer.c -- Plugin Viewer for CMU SASL /* pluginviewer.c -- Plugin Viewer for CMU SASL
* Alexey Melnikov, Isode Ltd. * Alexey Melnikov, Isode Ltd.
* *
* $Id: pluginviewer.c,v 1.4 2006/04/26 15:34:34 mel Exp $ * $Id: pluginviewer.c,v 1.11 2011/09/01 14:12:18 mel Exp $
*/ */
/* /*
* Copyright (c) 2004 Carnegie Mellon University. All rights reserved. * Copyright (c) 2004 Carnegie Mellon University. All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions * modification, are permitted provided that the following conditions
* are met: * are met:
* *
* 1. Redistributions of source code must retain the above copyright * 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer. * notice, this list of conditions and the following disclaimer.
skipping to change at line 96 skipping to change at line 96
#ifndef HAVE_GETSUBOPT #ifndef HAVE_GETSUBOPT
int getsubopt(char **optionp, const char * const *tokens, char **valuep); int getsubopt(char **optionp, const char * const *tokens, char **valuep);
#endif #endif
static const char static const char
build_ident[] = "$Build: pluginviewer " PACKAGE "-" VERSION " $"; build_ident[] = "$Build: pluginviewer " PACKAGE "-" VERSION " $";
static const char *progname = NULL; static const char *progname = NULL;
/* SASL authentication methods (client or server side). NULL means all. */ /* SASL authentication methods (client or server side). NULL means all. */
static char *mech = NULL; static char *sasl_mech = NULL;
/* auxprop methods. NULL means all. */ /* auxprop methods. NULL means all. */
static char *auxprop_mech = NULL; static char *auxprop_mech = NULL;
#define N_CALLBACKS (16) #define N_CALLBACKS (16)
#define NOT_NULL (void *) -1 #define NOT_NULL (void *) -1
#define SAMPLE_SEC_BUF_SIZE (2048) #define SAMPLE_SEC_BUF_SIZE (2048)
static const char *bit_subopts[] = { static const char *bit_subopts[] = {
skipping to change at line 138 skipping to change at line 138
"nodict", "nodict",
#define OPT_FORWARDSEC (3) #define OPT_FORWARDSEC (3)
"forwardsec", "forwardsec",
#define OPT_NOANONYMOUS (4) #define OPT_NOANONYMOUS (4)
"noanonymous", "noanonymous",
#define OPT_PASSCRED (5) #define OPT_PASSCRED (5)
"passcred", "passcred",
NULL NULL
}; };
static const char *ip_subopts[] = {
#define OPT_IP_LOCAL (0)
"local",
#define OPT_IP_REMOTE (1)
"remote",
NULL
};
/* Whitespace separated list of mechanisms to allow (e.g. 'plain otp'). /* Whitespace separated list of mechanisms to allow (e.g. 'plain otp').
Used to restrict the mechanisms to a subset of the installed plugins. Used to restrict the mechanisms to a subset of the installed plugins.
Default: NULL (i.e. all available) */ Default: NULL (i.e. all available) */
#define SASL_OPT_MECH_LIST "mech_list" #define SASL_OPT_MECH_LIST "mech_list"
/* Name of canon_user plugin to use, default is "INTERNAL" */ /* Name of canon_user plugin to use, default is "INTERNAL" */
#define SASL_OPT_CANON_USER_PLUGIN "canon_user_plugin" #define SASL_OPT_CANON_USER_PLUGIN "canon_user_plugin"
/* Name of auxiliary plugin to use, you may specify a space-separated list /* Name of auxiliary plugin to use, you may specify a space-separated list
of plugin names, and the plugins will be queried in order. Default is NU LL (i.e. query all) */ of plugin names, and the plugins will be queried in order. Default is NU LL (i.e. query all) */
#define SASL_OPT_AUXPROP_PLUGIN "auxprop_plugin" #define SASL_OPT_AUXPROP_PLUGIN "auxprop_plugin"
skipping to change at line 219 skipping to change at line 211
if (searchpath) { if (searchpath) {
*path = searchpath; *path = searchpath;
} else { } else {
*path = PLUGINDIR; *path = PLUGINDIR;
} }
return SASL_OK; return SASL_OK;
} }
static int static int
sasl_getopt ( plugview_sasl_getopt (
void *context, void *context,
const char *plugin_name, const char *plugin_name,
const char *option, const char *option,
const char **result, const char **result,
unsigned *len unsigned *len
) )
{ {
if (strcasecmp (option, SASL_OPT_MECH_LIST) == 0) { if (strcasecmp (option, SASL_OPT_MECH_LIST) == 0) {
/* Whitespace separated list of mechanisms to allow (e.g. 'plain ot p'). /* Whitespace separated list of mechanisms to allow (e.g. 'plain ot p').
Used to restrict the mechanisms to a subset of the installed plu gins. Used to restrict the mechanisms to a subset of the installed plu gins.
Default: NULL (i.e. all available) */ Default: NULL (i.e. all available) */
if (result != NULL) { if (result != NULL) {
*result = mech; *result = sasl_mech;
} }
if (len != NULL) { if (len != NULL) {
/* This might be NULL, which means "all mechanisms" */ /* This might be NULL, which means "all mechanisms" */
*len = mech ? strlen(mech) : 0; *len = sasl_mech ? strlen(sasl_mech) : 0;
} }
return (SASL_OK); return (SASL_OK);
} }
else { else {
/* Unrecognized */ /* Unrecognized */
return (SASL_FAIL); return (SASL_FAIL);
} }
} }
static void static void
skipping to change at line 281 skipping to change at line 273
} }
static void static void
fail(const char *what) fail(const char *what)
{ {
fprintf(stderr, "%s: %s\n", fprintf(stderr, "%s: %s\n",
progname, what); progname, what);
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
} }
static void
osfail()
{
perror(progname);
exit(EXIT_FAILURE);
}
/* Produce a space separated list of installed mechanisms */ /* Produce a space separated list of installed mechanisms */
static void static void
list_installed_server_mechanisms ( list_installed_server_mechanisms (
server_sasl_mechanism_t *m, server_sasl_mechanism_t *m,
sasl_info_callback_stage_t stage, sasl_info_callback_stage_t stage,
void *rock void *rock
) )
{ {
char ** list_of_mechs = (char **) rock; char ** list_of_mechs = (char **) rock;
char * new_list; char * new_list;
skipping to change at line 382 skipping to change at line 367
{ {
int c = 0; int c = 0;
int errflag = 0; int errflag = 0;
int result; int result;
sasl_security_properties_t secprops; sasl_security_properties_t secprops;
sasl_ssf_t extssf = 0; sasl_ssf_t extssf = 0;
const char *ext_authid = NULL; const char *ext_authid = NULL;
char *options, *value; char *options, *value;
const char *available_mechs = NULL; const char *available_mechs = NULL;
unsigned len; unsigned len;
unsigned count; int count;
sasl_callback_t callbacks[N_CALLBACKS], *callback; sasl_callback_t callbacks[N_CALLBACKS], *callback;
char *searchpath = NULL; char *searchpath = NULL;
char *service = "test"; char *service = "test";
char * list_of_server_mechs = NULL; char * list_of_server_mechs = NULL;
char * list_of_client_mechs = NULL; char * list_of_client_mechs = NULL;
char * list_of_auxprop_mechs = NULL; char * list_of_auxprop_mechs = NULL;
int list_all_plugins = 1; /* By default we list all plugins * / int list_all_plugins = 1; /* By default we list all plugins * /
int list_client_auth_plugins = 0; int list_client_auth_plugins = 0;
int list_server_auth_plugins = 0; int list_server_auth_plugins = 0;
int list_auxprop_plugins = 0; int list_auxprop_plugins = 0;
skipping to change at line 488 skipping to change at line 473
} }
break; break;
default: default:
errflag = 1; errflag = 1;
break; break;
} }
} }
break; break;
case 'm': case 'm':
mech = optarg; sasl_mech = optarg;
break; break;
case 'f': case 'f':
options = optarg; options = optarg;
while (*options != '\0') { while (*options != '\0') {
switch(getsubopt(&options, (const char * const *)flag_subopt s, &value)) { switch(getsubopt(&options, (const char * const *)flag_subopt s, &value)) {
case OPT_NOPLAIN: case OPT_NOPLAIN:
secprops.security_flags |= SASL_SEC_NOPLAINTEXT; secprops.security_flags |= SASL_SEC_NOPLAINTEXT;
break; break;
case OPT_NOACTIVE: case OPT_NOACTIVE:
skipping to change at line 539 skipping to change at line 524
if (optind != argc) { if (optind != argc) {
/* We don't *have* extra arguments */ /* We don't *have* extra arguments */
errflag = 1; errflag = 1;
} }
if (errflag) { if (errflag) {
fprintf(stderr, "%s: Usage: %s [-a] [-s] [-c] [-b min=N,max=N] [-e ssf=N,id=ID] [-m MECHS] [-x AUXPROP_MECH] [-f FLAGS] [-i local=IP,remote=IP ] [-p PATH]\n" fprintf(stderr, "%s: Usage: %s [-a] [-s] [-c] [-b min=N,max=N] [-e ssf=N,id=ID] [-m MECHS] [-x AUXPROP_MECH] [-f FLAGS] [-i local=IP,remote=IP ] [-p PATH]\n"
"\t-a\tlist auxprop plugins\n" "\t-a\tlist auxprop plugins\n"
"\t-s\tlist server authentication (SASL) plugins\n" "\t-s\tlist server authentication (SASL) plugins\n"
"\t-s\tlist client authentication (SASL) plugins\n" "\t-c\tlist client authentication (SASL) plugins\n"
"\t-b ...\t#bits to use for encryption\n" "\t-b ...\t#bits to use for encryption\n"
"\t\tmin=N\tminumum #bits to use (1 => integrity)\n" "\t\tmin=N\tminumum #bits to use (1 => integrity)\n"
"\t\tmax=N\tmaximum #bits to use\n" "\t\tmax=N\tmaximum #bits to use\n"
"\t-e ...\tassume external encryption\n" "\t-e ...\tassume external encryption\n"
"\t\tssf=N\texternal mech provides N bits of encryption\n" "\t\tssf=N\texternal mech provides N bits of encryption\n"
"\t\tid=ID\texternal mech provides authentication id ID\n" "\t\tid=ID\texternal mech provides authentication id ID\n"
"\t-m MECHS\tforce to use one of MECHS SASL mechanism\n" "\t-m MECHS\tforce to use one of MECHS SASL mechanism\n"
"\t-x AUXPROP_MECHS\tforce to use one of AUXPROP_MECHS auxpr op plugins\n" "\t-x AUXPROP_MECHS\tforce to use one of AUXPROP_MECHS auxpr op plugins\n"
"\t-f ...\tset security flags\n" "\t-f ...\tset security flags\n"
"\t\tnoplain\t\tno plaintext password send during authentica tion\n" "\t\tnoplain\t\tno plaintext password send during authentica tion\n"
"\t\tnoactive\trequire security vs. active attacks\n" "\t\tnoactive\trequire security vs. active attacks\n"
"\t\tnodict\t\trequire security vs. passive dictionary attac ks\n" "\t\tnodict\t\trequire security vs. passive dictionary attac ks\n"
"\t\tforwardsec\trequire forward secrecy\n" "\t\tforwardsec\trequire forward secrecy\n"
"\t\tmaximum\t\trequire all security flags\n" "\t\tmaximum\t\trequire all security flags\n"
"\t\tpasscred\tattempt to pass client credentials\n" "\t\tpasscred\tattempt to pass client credentials\n"
#ifdef WIN32 #ifdef WIN32
"\t-p PATH\tsemicolon-separated search path for mechanisms\n ", "\t-p PATH\tsemicolon-separated search path for mechanisms\n ",
#else #else
"\t-p PATH\tcolon-seperated search path for mechanisms\n", "\t-p PATH\tcolon-separated search path for mechanisms\n",
#endif #endif
progname, progname); progname, progname);
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
} }
/* Fill in the callbacks that we're providing... */ /* Fill in the callbacks that we're providing... */
callback = callbacks; callback = callbacks;
/* log */ /* log */
callback->id = SASL_CB_LOG; callback->id = SASL_CB_LOG;
callback->proc = &sasl_my_log; callback->proc = (sasl_callback_ft)&sasl_my_log;
callback->context = NULL; callback->context = NULL;
++callback; ++callback;
/* getpath */ /* getpath */
if (searchpath) { if (searchpath) {
callback->id = SASL_CB_GETPATH; callback->id = SASL_CB_GETPATH;
callback->proc = &getpath; callback->proc = (sasl_callback_ft)&getpath;
callback->context = searchpath; callback->context = searchpath;
++callback; ++callback;
} }
/* getopt */ /* getopt */
/* NOTE: this will return "sasl_mech" option, however this HAS NO EFFEC
T
on client side SASL plugins, which just never query this option */
callback->id = SASL_CB_GETOPT; callback->id = SASL_CB_GETOPT;
callback->proc = &sasl_getopt; callback->proc = (sasl_callback_ft)&plugview_sasl_getopt;
callback->context = NULL; callback->context = NULL;
++callback; ++callback;
/* The following callbacks are for a client connection only. /* The following callbacks are for a client connection only.
We reuse the same callbacks variable and the server side doesn't like We reuse the same callbacks variable and the server side doesn't like
proc == NULL. So we just put something there, != NULL! */ proc == NULL. So we just put something there, != NULL! */
callback->id = SASL_CB_AUTHNAME; callback->id = SASL_CB_AUTHNAME;
callback->proc = NOT_NULL; callback->proc = NOT_NULL;
callback->context = NULL; callback->context = NULL;
++callback; ++callback;
skipping to change at line 622 skipping to change at line 609
result = sasl_client_init(callbacks); result = sasl_client_init(callbacks);
if (result != SASL_OK) { if (result != SASL_OK) {
saslfail(result, "Initializing client side of libsasl", NULL); saslfail(result, "Initializing client side of libsasl", NULL);
} }
result = sasl_server_init(callbacks, "pluginviewer"); result = sasl_server_init(callbacks, "pluginviewer");
if (result != SASL_OK) { if (result != SASL_OK) {
saslfail(result, "Initializing server side of libsasl", NULL); saslfail(result, "Initializing server side of libsasl", NULL);
} }
if (list_all_plugins || list_server_auth_plugins) { if (list_all_plugins || list_auxprop_plugins) {
list_of_auxprop_mechs = NULL;
auxprop_plugin_info (NULL, /* list all auxprop mechanisms */
&list_installed_auxprop_mechanisms,
(void *) &list_of_auxprop_mechs);
printf ("Installed and properly configured auxprop mechanisms are:\n
%s\n",
(list_of_auxprop_mechs == NULL) ? "<none>" : list_of_auxprop
_mechs);
free (list_of_auxprop_mechs);
auxprop_plugin_info (auxprop_mech, NULL, NULL);
}
/* TODO: add listing of canonicalization plugins, if needed. */
if (list_all_plugins || list_server_auth_plugins) {
/* SASL server plugins */ /* SASL server plugins */
/* List all loaded plugins first */
list_of_server_mechs = NULL;
sasl_server_plugin_info (NULL, /* list all SASL mechanisms */
&list_installed_server_mechanisms,
(void *) &list_of_server_mechs);
printf ("Installed and properly configured SASL (server side) mecha
nisms are:\n %s\n", list_of_server_mechs);
free (list_of_server_mechs);
/* Now list plugins matching the criteria */
result = sasl_server_new(service, result = sasl_server_new(service,
/* Has to be any non NULL value */ /* Has to be any non NULL value */
"test.example.com", /* localdomain */ "test.example.com", /* localdomain */
NULL, /* userdomain */ NULL, /* userdomain */
NULL, /* iplocal */ NULL, /* iplocal */
NULL, /* ipremote */ NULL, /* ipremote */
NULL, NULL,
0, 0,
&server_conn); &server_conn);
if (result != SASL_OK) { if (result != SASL_OK) {
saslfail(result, "Allocating sasl connection state (server side )", NULL); saslfail(result, "Allocating sasl connection state (server side )", NULL);
} }
/* The following two options are required for SSF */ /* The following two options are required for SASL EXTERNAL */
if (extssf) { if (extssf) {
result = sasl_setprop(server_conn, result = sasl_setprop(server_conn,
SASL_SSF_EXTERNAL, SASL_SSF_EXTERNAL,
&extssf); &extssf);
if (result != SASL_OK) { if (result != SASL_OK) {
saslfail(result, "Setting external SSF", NULL); saslfail(result, "Setting external SSF", NULL);
} }
} }
skipping to change at line 667 skipping to change at line 682
} }
result = sasl_setprop(server_conn, result = sasl_setprop(server_conn,
SASL_SEC_PROPS, SASL_SEC_PROPS,
&secprops); &secprops);
if (result != SASL_OK) { if (result != SASL_OK) {
saslfail(result, "Setting security properties", NULL); saslfail(result, "Setting security properties", NULL);
} }
/* This will use getopt callback, which is using the "mech" global variable */ /* NOTE - available_mechs must not be freed */
result = sasl_listmech(server_conn, result = sasl_listmech(server_conn,
ext_authid, ext_authid,
NULL, NULL,
" ", " ",
NULL, NULL,
&available_mechs, &available_mechs,
&len, &len,
&count); &count);
if (result != SASL_OK) { if (result != SASL_OK) {
saslfail(result, "Setting security properties", NULL); saslfail(result, "Listing SASL mechanisms", NULL);
} }
if (count > 0) { /* NOTE: available_mechs contains subset of sasl_mech */
list_of_server_mechs = NULL;
sasl_server_plugin_info (NULL, /* list all SASL mechanisms */
&list_installed_server_mechanisms,
(void *) &list_of_server_mechs);
printf ("Installed SASL (server side) mechanisms are:\n%s\n", l if (count > 0) {
ist_of_server_mechs); printf ("Available SASL (server side) mechanisms matching your
criteria are:\n %s\n", available_mechs);
free (list_of_server_mechs);
/* Dump information about the requested SASL mechanism */ /* Dump information about the requested SASL mechanism */
/* NOTE - available_mechs must not be freed */
sasl_server_plugin_info (available_mechs, NULL, NULL); sasl_server_plugin_info (available_mechs, NULL, NULL);
} else { } else {
printf ("No server side SASL mechanisms installed\n"); printf ("No server side SASL mechanisms matching your criteria f ound\n");
} }
} }
if (list_all_plugins || list_auxprop_plugins) { if (list_all_plugins || list_client_auth_plugins) {
list_of_auxprop_mechs = NULL; /* SASL client plugins */
/* List all loaded plugins first */
auxprop_plugin_info (NULL, /* list all auxprop mechanisms */ list_of_client_mechs = NULL;
&list_installed_auxprop_mechanisms,
(void *) &list_of_auxprop_mechs);
printf ("Installed auxprop mechanisms are:\n%s\n", list_of_auxprop_m
echs);
free (list_of_auxprop_mechs); sasl_client_plugin_info (NULL, /* list all SASL mechanisms */
&list_installed_client_mechanisms,
(void *) &list_of_client_mechs);
auxprop_plugin_info (auxprop_mech, NULL, NULL); printf ("Installed and properly configured SASL (client side) mechan
} isms are:\n %s\n",
(list_of_client_mechs != NULL) ? list_of_client_mechs : "<no
ne>");
/* TODO: add listing of canonicalization plugins, if needed. */ free (list_of_client_mechs);
if (list_all_plugins || list_client_auth_plugins) { /* Now list plugins matching the criteria */
/* SASL client plugins */
result = sasl_client_new(service, result = sasl_client_new(service,
/* Has to be any non NULL value */ /* Has to be any non NULL value */
"test.example.com", /* fqdn */ "test.example.com", /* fqdn */
NULL, /* iplocal */ NULL, /* iplocal */
NULL, /* ipremote */ NULL, /* ipremote */
NULL, NULL,
0, 0,
&client_conn); &client_conn);
if (result != SASL_OK) { if (result != SASL_OK) {
skipping to change at line 759 skipping to change at line 764
} }
result = sasl_setprop(client_conn, result = sasl_setprop(client_conn,
SASL_SEC_PROPS, SASL_SEC_PROPS,
&secprops); &secprops);
if (result != SASL_OK) { if (result != SASL_OK) {
saslfail(result, "Setting security properties", NULL); saslfail(result, "Setting security properties", NULL);
} }
/* This will use getopt callback, which is using the "mech" global variable */ /* NOTE - available_mechs must not be freed */
result = sasl_listmech(client_conn, result = sasl_listmech(client_conn,
ext_authid, ext_authid,
NULL, NULL,
" ", " ",
NULL, NULL,
&available_mechs, &available_mechs,
&len, &len,
&count); &count);
if (result != SASL_OK) { if (result != SASL_OK) {
saslfail(result, "Setting security properties", NULL); saslfail(result, "Listing SASL mechanisms", NULL);
} }
if (count > 0) { if (count > 0) {
list_of_client_mechs = NULL; printf ("Available SASL (client side) mechanisms matching your
criteria are:\n %s\n", available_mechs);
sasl_client_plugin_info (NULL, /* list all SASL mechanisms */
&list_installed_client_mechanisms,
(void *) &list_of_client_mechs);
printf ("Installed SASL (client side) mechanisms are:\n%s\n", li
st_of_client_mechs);
free (list_of_client_mechs);
/* Dump information about the requested SASL mechanism */ /* Dump information about the requested SASL mechanism */
/* NOTE - available_mechs must not be freed */ sasl_client_plugin_info (sasl_mech, NULL, NULL);
sasl_client_plugin_info (available_mechs, NULL, NULL);
} else { } else {
printf ("No client side SASL mechanisms installed\n"); printf ("No client side SASL mechanisms matching your criteria f ound\n");
} }
} }
free_conn(); free_conn();
/* Call sasl_done twice - one for the client side SASL and /* Call sasl_done twice - one for the client side SASL and
one for the server side. */ one for the server side. */
sasl_done(); sasl_done();
sasl_done(); sasl_done();
#ifdef WIN32 #ifdef WIN32
 End of changes. 36 change blocks. 
80 lines changed or deleted 81 lines changed or added

This html diff was produced by rfcdiff 1.41. The latest version is available from http://tools.ietf.org/tools/rfcdiff/