/*1* SPDX-License-Identifier: ISC2*3* Copyright (c) 2017 Todd C. Miller <[email protected]>4*5* Permission to use, copy, modify, and distribute this software for any6* purpose with or without fee is hereby granted, provided that the above7* copyright notice and this permission notice appear in all copies.8*9* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES10* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF11* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR12* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES13* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN14* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF15* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.16*/1718#include <config.h>1920#include <stdio.h>21#include <stdlib.h>22#include <string.h>2324#include <sudoers.h>2526/* extern for regress tests */27bool28matches_env_pattern(const char *pattern, const char *var, bool *full_match)29{30size_t len, sep_pos;31bool iswild = false, match = false;32bool saw_sep = false;33const char *cp;34debug_decl(matches_env_pattern, SUDOERS_DEBUG_ENV);3536/* Locate position of the '=' separator in var=value. */37sep_pos = strcspn(var, "=");3839/* Locate '*' wildcard and compute len. */40for (cp = pattern; *cp != '\0'; cp++) {41if (*cp == '*') {42iswild = true;43break;44}45}46len = (size_t)(cp - pattern);4748if (iswild) {49/* Match up to the '*' wildcard. */50if (strncmp(pattern, var, len) == 0) {51while (*cp != '\0') {52if (*cp == '*') {53/* Collapse sequential '*'s */54do {55cp++;56} while (*cp == '*');57/* A '*' at the end of a pattern matches anything. */58if (*cp == '\0') {59match = true;60break;61}62/* Keep track of whether we matched an equal sign. */63if (*cp == '=')64saw_sep = true;65/* Look for first match of text after the '*' */66while ((saw_sep || len != sep_pos) &&67var[len] != '\0' && var[len] != *cp)68len++;69}70if (var[len] != *cp)71break;72cp++;73len++;74}75if (*cp == '\0' && (len == sep_pos || var[len] == '\0'))76match = true;77}78} else {79if (strncmp(pattern, var, len) == 0 &&80(len == sep_pos || var[len] == '\0')) {81match = true;82}83}84if (match)85*full_match = len > sep_pos + 1;86debug_return_bool(match);87}888990