1/*	$NetBSD: sasl_mech_filter.c,v 1.2 2022/10/08 16:12:45 christos Exp $	*/
2
3/*++
4/* NAME
5/*	sasl_mech_filter 3
6/* SUMMARY
7/*	Filter SASL mechanism names
8/* SYNOPSIS
9/*	#include sasl_mech_filter.h
10/*
11/*	const char *sasl_mech_filter(
12/*	STRING_LIST *filter,
13/*	const char *words)
14/* DESCRIPTION
15/*	sasl_mech_filter() applies the specified filter to a list
16/*	of SASL mechanism names. The filter is case-insensitive,
17/*	but preserves the case of input words.
18/*
19/*	Arguments:
20/* .IP filter
21/*	Null pointer or filter specification. If this is a nulll
22/*	pointer, no filter will be applied.
23/* .IP words
24/*	List of SASL authentication mechanisms (separated by blanks).
25/*	If the string is empty, the filter will not be applied.
26/* DIAGNOSTICS
27/*	Fatal errors: memory allocation, table lookup error.
28/* LICENSE
29/* .ad
30/* .fi
31/*	The Secure Mailer license must be distributed with this software.
32/* AUTHOR(S)
33/*	Original author:
34/*	Till Franke
35/*	SuSE Rhein/Main AG
36/*	65760 Eschborn, Germany
37/*
38/*	Adopted by:
39/*	Wietse Venema
40/*	IBM T.J. Watson Research
41/*	P.O. Box 704
42/*	Yorktown Heights, NY 10598, USA
43/*
44/*	Wietse Venema
45/*	Google, Inc.
46/*	111 8th Avenue
47/*	New York, NY 10011, USA
48/*--*/
49
50/* System library. */
51
52#include <sys_defs.h>
53#include <string.h>
54#ifdef STRCASECMP_IN_STRINGS_H
55#include <strings.h>
56#endif
57
58/* Utility library. */
59
60#include <msg.h>
61#include <mymalloc.h>
62#include <stringops.h>
63
64/* Global library. */
65
66#include <sasl_mech_filter.h>
67
68#ifdef USE_SASL_AUTH
69
70/* sasl_mech_filter - filter a SASL mechanism list */
71
72const char *sasl_mech_filter(STRING_LIST *filter,
73			             const char *words)
74{
75    const char myname[] = "sasl_mech_filter";
76    static VSTRING *buf;
77    char   *mech_list;
78    char   *save_mech;
79    char   *mech;
80
81    /*
82     * NOOP if there is no filter, or if the mechanism list is empty.
83     */
84    if (filter == 0 || *words == 0)
85	return (words);
86
87    if (buf == 0)
88	buf = vstring_alloc(10);
89
90    VSTRING_RESET(buf);
91    VSTRING_TERMINATE(buf);
92
93    save_mech = mech_list = mystrdup(words);
94
95    while ((mech = mystrtok(&mech_list, " \t")) != 0) {
96	if (string_list_match(filter, mech)) {
97	    if (VSTRING_LEN(buf) > 0)
98		VSTRING_ADDCH(buf, ' ');
99	    vstring_strcat(buf, mech);
100	    if (msg_verbose)
101		msg_info("%s: keep SASL mechanism: '%s'", myname, mech);
102	} else if (filter->error) {
103	    msg_fatal("%s: SASL mechanism filter failed for: '%s'",
104		      myname, mech);
105	} else {
106	    if (msg_verbose)
107		msg_info("%s: drop SASL mechanism: '%s'", myname, mech);
108	}
109    }
110    myfree(save_mech);
111
112    return (vstring_str(buf));
113}
114
115#endif
116