This is match.c in view mode; [Download] [Up]
/*
match.c
Author: Tatu Ylonen <ylo@cs.hut.fi>
Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
All rights reserved
Created: Thu Jun 22 01:17:50 1995 ylo
Simple pattern matching, with '*' and '?' as wildcards.
*/
/*
* $Id: match.c,v 1.7 1998/07/08 01:08:02 kivinen Exp $
* $Log: match.c,v $
* Revision 1.7 1998/07/08 01:08:02 kivinen
* Added more conts, fixed typo.
*
* Revision 1.6 1998/07/08 01:05:11 kivinen
* Added consts.
*
* Revision 1.5 1998/07/08 00:44:44 kivinen
* Added match_host. Changed match_user to use it.
*
* Revision 1.4 1998/06/11 00:07:36 kivinen
* Added match_user function.
*
* Revision 1.3 1997/04/27 22:19:35 kivinen
* Fixed typo.
*
* Revision 1.2 1997/04/27 21:52:05 kivinen
* Added F-SECURE stuff. Added match_port function.
*
* Revision 1.1.1.1 1996/02/18 21:38:12 ylo
* Imported ssh-1.2.13.
*
* Revision 1.2 1995/07/13 01:27:07 ylo
* Removed "Last modified" header.
* Added cvs log.
*
* $Endlog$
*/
#include "includes.h"
#include "ssh.h"
#include "xmalloc.h"
/* Returns true if the given string matches the pattern (which may contain
? and * as wildcards), and zero if it does not match. */
int match_pattern(const char *s, const char *pattern)
{
while (1)
{
/* If at end of pattern, accept if also at end of string. */
if (!*pattern)
return !*s;
/* Process '*'. */
if (*pattern == '*')
{
/* Skip the asterisk. */
pattern++;
/* If at end of pattern, accept immediately. */
if (!*pattern)
return 1;
/* If next character in pattern is known, optimize. */
if (*pattern != '?' && *pattern != '*')
{
/* Look instances of the next character in pattern, and try
to match starting from those. */
for (; *s; s++)
if (*s == *pattern &&
match_pattern(s + 1, pattern + 1))
return 1;
/* Failed. */
return 0;
}
/* Move ahead one character at a time and try to match at each
position. */
for (; *s; s++)
if (match_pattern(s, pattern))
return 1;
/* Failed. */
return 0;
}
/* There must be at least one more character in the string. If we are
at the end, fail. */
if (!*s)
return 0;
/* Check if the next character of the string is acceptable. */
if (*pattern != '?' && *pattern != *s)
return 0;
/* Move to the next character, both in string and in pattern. */
s++;
pattern++;
}
/*NOTREACHED*/
}
/* Check that host name matches the pattern. If the pattern only contains
numbers and periods, and wildcards compare it against the ip address
otherwise assume it is host name */
int match_host(const char *host, const char *ip, const char *pattern)
{
int is_ip_pattern;
const char *p;
/* if the pattern does not contain any alpha characters then
assume that it is a IP address (with possible wildcards),
otherwise assume it is a hostname */
if (ip)
is_ip_pattern = 1;
else
is_ip_pattern = 0;
for(p = pattern; *p; p++)
if (!(isdigit(*p) || *p == '.' || *p == '?' || *p == '*'))
{
is_ip_pattern = 0;
break;
}
if (is_ip_pattern)
{
return match_pattern(ip, pattern);
}
return match_pattern(host, pattern);
}
/* this combines the effect of match_pattern on a username, hostname
and IP address. If the pattern contains a @ then the part preceding
the @ is checked against the username. The part after the @ is
checked against the hostname and IP address. If no @ is found then
a normal match_pattern is done against the username
This is more useful than just a match_pattern as it allows you to
specify exactly what users are alowed to login from what hosts
(tridge, May 1998)
*/
int match_user(const char *user, const char *host, const char *ip,
const char *pattern)
{
int ret;
char *p2;
char *p;
p = strchr(pattern,'@');
if (!p)
return match_pattern(user, pattern);
p2 = xstrdup(pattern);
p = strchr(p2, '@');
*p = 0;
ret = match_pattern(user,p2) && match_host(host, ip, p + 1);
xfree(p2);
return ret;
}
#ifdef F_SECURE_COMMERCIAL
#endif /* F_SECURE_COMMERCIAL */
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.