11305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood/* $OpenBSD: match.c,v 1.27 2008/06/10 23:06:19 djm Exp $ */
21305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood/*
31305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * Author: Tatu Ylonen <ylo@cs.hut.fi>
41305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
51305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood *                    All rights reserved
61305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * Simple pattern matching, with '*' and '?' as wildcards.
71305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood *
81305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * As far as I am concerned, the code I have written for this software
91305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * can be used freely for any purpose.  Any derived versions of this
101305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * software must be clearly marked as such, and if the derived work is
111305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * incompatible with the protocol description in the RFC file, it must be
121305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * called by a name other than "ssh" or "Secure Shell".
131305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood */
141305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood/*
151305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * Copyright (c) 2000 Markus Friedl.  All rights reserved.
161305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood *
171305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * Redistribution and use in source and binary forms, with or without
181305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * modification, are permitted provided that the following conditions
191305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * are met:
201305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * 1. Redistributions of source code must retain the above copyright
211305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood *    notice, this list of conditions and the following disclaimer.
221305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * 2. Redistributions in binary form must reproduce the above copyright
231305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood *    notice, this list of conditions and the following disclaimer in the
241305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood *    documentation and/or other materials provided with the distribution.
251305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood *
261305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
271305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
281305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
291305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
301305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
311305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
321305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
331305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
341305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
351305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
361305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood */
371305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
381305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include "includes.h"
391305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
401305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include <sys/types.h>
411305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
421305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include <ctype.h>
431305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include <string.h>
441305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
451305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include "xmalloc.h"
461305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include "match.h"
471305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
481305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood/*
491305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * Returns true if the given string matches the pattern (which may contain ?
501305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * and * as wildcards), and zero if it does not match.
511305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood */
521305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
531305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodint
541305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodmatch_pattern(const char *s, const char *pattern)
551305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{
561305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	for (;;) {
571305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		/* If at end of pattern, accept if also at end of string. */
581305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		if (!*pattern)
591305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			return !*s;
601305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
611305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		if (*pattern == '*') {
621305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			/* Skip the asterisk. */
631305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			pattern++;
641305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
651305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			/* If at end of pattern, accept immediately. */
661305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			if (!*pattern)
671305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood				return 1;
681305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
691305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			/* If next character in pattern is known, optimize. */
701305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			if (*pattern != '?' && *pattern != '*') {
711305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood				/*
721305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood				 * Look instances of the next character in
731305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood				 * pattern, and try to match starting from
741305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood				 * those.
751305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood				 */
761305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood				for (; *s; s++)
771305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood					if (*s == *pattern &&
781305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood					    match_pattern(s + 1, pattern + 1))
791305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood						return 1;
801305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood				/* Failed. */
811305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood				return 0;
821305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			}
831305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			/*
841305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			 * Move ahead one character at a time and try to
851305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			 * match at each position.
861305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			 */
871305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			for (; *s; s++)
881305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood				if (match_pattern(s, pattern))
891305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood					return 1;
901305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			/* Failed. */
911305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			return 0;
921305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		}
931305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		/*
941305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		 * There must be at least one more character in the string.
951305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		 * If we are at the end, fail.
961305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		 */
971305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		if (!*s)
981305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			return 0;
991305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
1001305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		/* Check if the next character of the string is acceptable. */
1011305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		if (*pattern != '?' && *pattern != *s)
1021305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			return 0;
1031305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
1041305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		/* Move to the next character, both in string and in pattern. */
1051305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		s++;
1061305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		pattern++;
1071305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	}
1081305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	/* NOTREACHED */
1091305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood}
1101305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
1111305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood/*
1121305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * Tries to match the string against the
1131305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * comma-separated sequence of subpatterns (each possibly preceded by ! to
1141305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * indicate negation).  Returns -1 if negation matches, 1 if there is
1151305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * a positive match, 0 if there is no match at all.
1161305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood */
1171305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
1181305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodint
1191305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodmatch_pattern_list(const char *string, const char *pattern, u_int len,
1201305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood    int dolower)
1211305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{
1221305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	char sub[1024];
1231305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	int negated;
1241305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	int got_positive;
1251305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	u_int i, subi;
1261305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
1271305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	got_positive = 0;
1281305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	for (i = 0; i < len;) {
1291305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		/* Check if the subpattern is negated. */
1301305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		if (pattern[i] == '!') {
1311305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			negated = 1;
1321305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			i++;
1331305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		} else
1341305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			negated = 0;
1351305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
1361305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		/*
1371305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		 * Extract the subpattern up to a comma or end.  Convert the
1381305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		 * subpattern to lowercase.
1391305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		 */
1401305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		for (subi = 0;
1411305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		    i < len && subi < sizeof(sub) - 1 && pattern[i] != ',';
1421305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		    subi++, i++)
1431305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			sub[subi] = dolower && isupper(pattern[i]) ?
1441305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			    (char)tolower(pattern[i]) : pattern[i];
1451305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		/* If subpattern too long, return failure (no match). */
1461305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		if (subi >= sizeof(sub) - 1)
1471305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			return 0;
1481305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
1491305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		/* If the subpattern was terminated by a comma, skip the comma. */
1501305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		if (i < len && pattern[i] == ',')
1511305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			i++;
1521305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
1531305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		/* Null-terminate the subpattern. */
1541305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		sub[subi] = '\0';
1551305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
1561305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		/* Try to match the subpattern against the string. */
1571305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		if (match_pattern(string, sub)) {
1581305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			if (negated)
1591305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood				return -1;		/* Negative */
1601305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			else
1611305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood				got_positive = 1;	/* Positive */
1621305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		}
1631305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	}
1641305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
1651305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	/*
1661305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	 * Return success if got a positive match.  If there was a negative
1671305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	 * match, we have already returned -1 and never get here.
1681305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	 */
1691305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	return got_positive;
1701305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood}
1711305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
1721305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood/*
1731305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * Tries to match the host name (which must be in all lowercase) against the
1741305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * comma-separated sequence of subpatterns (each possibly preceded by ! to
1751305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * indicate negation).  Returns -1 if negation matches, 1 if there is
1761305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * a positive match, 0 if there is no match at all.
1771305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood */
1781305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodint
1791305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodmatch_hostname(const char *host, const char *pattern, u_int len)
1801305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{
1811305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	return match_pattern_list(host, pattern, len, 1);
1821305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood}
1831305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
1841305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood/*
1851305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * returns 0 if we get a negative match for the hostname or the ip
1861305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * or if we get no match at all.  returns -1 on error, or 1 on
1871305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * successful match.
1881305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood */
1891305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodint
1901305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodmatch_host_and_ip(const char *host, const char *ipaddr,
1911305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood    const char *patterns)
1921305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{
1931305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	int mhost, mip;
1941305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
1951305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	/* error in ipaddr match */
1961305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	if ((mip = addr_match_list(ipaddr, patterns)) == -2)
1971305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		return -1;
1981305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	else if (mip == -1) /* negative ip address match */
1991305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		return 0;
2001305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
2011305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	/* negative hostname match */
2021305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	if ((mhost = match_hostname(host, patterns, strlen(patterns))) == -1)
2031305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		return 0;
2041305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	/* no match at all */
2051305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	if (mhost == 0 && mip == 0)
2061305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		return 0;
2071305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	return 1;
2081305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood}
2091305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
2101305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood/*
2111305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * match user, user@host_or_ip, user@host_or_ip_list against pattern
2121305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood */
2131305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodint
2141305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodmatch_user(const char *user, const char *host, const char *ipaddr,
2151305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood    const char *pattern)
2161305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{
2171305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	char *p, *pat;
2181305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	int ret;
2191305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
2201305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	if ((p = strchr(pattern,'@')) == NULL)
2211305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		return match_pattern(user, pattern);
2221305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
2231305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	pat = xstrdup(pattern);
2241305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	p = strchr(pat, '@');
2251305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	*p++ = '\0';
2261305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
2271305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	if ((ret = match_pattern(user, pat)) == 1)
2281305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		ret = match_host_and_ip(host, ipaddr, p);
2291305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	xfree(pat);
2301305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
2311305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	return ret;
2321305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood}
2331305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
2341305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood/*
2351305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * Returns first item from client-list that is also supported by server-list,
2361305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * caller must xfree() returned string.
2371305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood */
2381305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#define	MAX_PROP	40
2391305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#define	SEP	","
2401305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodchar *
2411305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodmatch_list(const char *client, const char *server, u_int *next)
2421305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{
2431305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	char *sproposals[MAX_PROP];
2441305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	char *c, *s, *p, *ret, *cp, *sp;
2451305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	int i, j, nproposals;
2461305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
2471305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	c = cp = xstrdup(client);
2481305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	s = sp = xstrdup(server);
2491305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
2501305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	for ((p = strsep(&sp, SEP)), i=0; p && *p != '\0';
2511305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	    (p = strsep(&sp, SEP)), i++) {
2521305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		if (i < MAX_PROP)
2531305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			sproposals[i] = p;
2541305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		else
2551305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			break;
2561305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	}
2571305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	nproposals = i;
2581305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
2591305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	for ((p = strsep(&cp, SEP)), i=0; p && *p != '\0';
2601305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	    (p = strsep(&cp, SEP)), i++) {
2611305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		for (j = 0; j < nproposals; j++) {
2621305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			if (strcmp(p, sproposals[j]) == 0) {
2631305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood				ret = xstrdup(p);
2641305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood				if (next != NULL)
2651305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood					*next = (cp == NULL) ?
2661305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood					    strlen(c) : (u_int)(cp - c);
2671305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood				xfree(c);
2681305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood				xfree(s);
2691305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood				return ret;
2701305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			}
2711305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		}
2721305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	}
2731305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	if (next != NULL)
2741305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		*next = strlen(c);
2751305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	xfree(c);
2761305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	xfree(s);
2771305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	return NULL;
2781305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood}
279