diff options
author | joerg <joerg@pkgsrc.org> | 2009-04-25 21:31:13 +0000 |
---|---|---|
committer | joerg <joerg@pkgsrc.org> | 2009-04-25 21:31:13 +0000 |
commit | 655468e84f946b1fb4426e8ce19efd5bbae4e554 (patch) | |
tree | d7222d89001b7f012a805a62f4521d28e85fd7e3 | |
parent | a0343c9b12ac7cafe85ee5a6bffae7bfede4b9cc (diff) | |
download | pkgsrc-655468e84f946b1fb4426e8ce19efd5bbae4e554.tar.gz |
pkg_install-20090425:
Add logic to evaluate license conditions. As frontend for pkgsrc,
pkg_admin gets two new commands (check-license and
check-single-license), which can be used to evaluate a given condition.
pkg_add will be changed to honour licenses at a later point.
-rw-r--r-- | pkgtools/pkg_install/files/admin/main.c | 37 | ||||
-rw-r--r-- | pkgtools/pkg_install/files/admin/pkg_admin.1 | 18 | ||||
-rw-r--r-- | pkgtools/pkg_install/files/lib/Makefile.in | 4 | ||||
-rw-r--r-- | pkgtools/pkg_install/files/lib/lib.h | 12 | ||||
-rw-r--r-- | pkgtools/pkg_install/files/lib/license.c | 275 | ||||
-rw-r--r-- | pkgtools/pkg_install/files/lib/parse-config.c | 8 | ||||
-rw-r--r-- | pkgtools/pkg_install/files/lib/pkg_install.conf.5.in | 8 | ||||
-rw-r--r-- | pkgtools/pkg_install/files/lib/version.h | 4 |
8 files changed, 351 insertions, 15 deletions
diff --git a/pkgtools/pkg_install/files/admin/main.c b/pkgtools/pkg_install/files/admin/main.c index 81e967cd8b0..cf10405a652 100644 --- a/pkgtools/pkg_install/files/admin/main.c +++ b/pkgtools/pkg_install/files/admin/main.c @@ -1,4 +1,4 @@ -/* $NetBSD: main.c,v 1.51 2009/04/24 14:00:25 joerg Exp $ */ +/* $NetBSD: main.c,v 1.52 2009/04/25 21:31:13 joerg Exp $ */ #if HAVE_CONFIG_H #include "config.h" @@ -7,7 +7,7 @@ #if HAVE_SYS_CDEFS_H #include <sys/cdefs.h> #endif -__RCSID("$NetBSD: main.c,v 1.51 2009/04/24 14:00:25 joerg Exp $"); +__RCSID("$NetBSD: main.c,v 1.52 2009/04/25 21:31:13 joerg Exp $"); /*- * Copyright (c) 1999-2008 The NetBSD Foundation, Inc. @@ -110,6 +110,8 @@ usage(void) " audit-pkg [-es] [-t type] ... - check listed packages for vulnerabilities\n" " audit-batch [-es] [-t type] ... - check packages in listed files for vulnerabilities\n" " audit-history [-t type] ... - print all advisories for package names\n" + " check-license <condition> - check if condition is acceptable\n" + " check-single-license <license> - check if license is acceptable\n" " config-var name - print current value of the configuration variable\n" " check-signature ... - verify the signature of packages\n" " x509-sign-package pkg spkg key cert - create X509 signature\n" @@ -524,6 +526,37 @@ main(int argc, char *argv[]) if (argv == NULL || argv[1] != NULL) errx(EXIT_FAILURE, "config-var takes exactly one argument"); pkg_install_show_variable(argv[0]); + } else if (strcasecmp(argv[0], "check-license") == 0) { + if (argv[1] == NULL) + errx(EXIT_FAILURE, "check-license takes exactly one argument"); + + load_license_lists(); + + switch (acceptable_pkg_license(argv[1])) { + case 0: + puts("no"); + return 0; + case 1: + puts("yes"); + return 0; + case -1: + errx(EXIT_FAILURE, "invalid license condition"); + } + } else if (strcasecmp(argv[0], "check-single-license") == 0) { + if (argv[1] == NULL) + errx(EXIT_FAILURE, "check-license takes exactly one argument"); + load_license_lists(); + + switch (acceptable_license(argv[1])) { + case 0: + puts("no"); + return 0; + case 1: + puts("yes"); + return 0; + case -1: + errx(EXIT_FAILURE, "invalid license"); + } } #ifndef BOOTSTRAP else if (strcasecmp(argv[0], "fetch-pkg-vulnerabilities") == 0) { diff --git a/pkgtools/pkg_install/files/admin/pkg_admin.1 b/pkgtools/pkg_install/files/admin/pkg_admin.1 index 5d7997e7228..839a243a78a 100644 --- a/pkgtools/pkg_install/files/admin/pkg_admin.1 +++ b/pkgtools/pkg_install/files/admin/pkg_admin.1 @@ -1,6 +1,6 @@ -.\" $NetBSD: pkg_admin.1,v 1.22 2009/04/22 19:13:54 joerg Exp $ +.\" $NetBSD: pkg_admin.1,v 1.23 2009/04/25 21:31:13 joerg Exp $ .\" -.\" Copyright (c) 1999-2008 The NetBSD Foundation, Inc. +.\" Copyright (c) 1999-2009 The NetBSD Foundation, Inc. .\" All rights reserved. .\" .\" This code is derived from software contributed to The NetBSD Foundation @@ -34,7 +34,7 @@ .\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE .\" POSSIBILITY OF SUCH DAMAGE. .\" -.Dd May 30, 2008 +.Dd April 25, 2009 .Dt PKG_ADMIN 1 .Os .Sh NAME @@ -160,6 +160,12 @@ A warning message is printed if the expected checksum differs from the checksum of the file on disk. Symbolic links are also checked, ensuring that the targets on disk are the same as the contents recorded at package installation time. +.It Cm check-license Ar condition +Check if +.Ar condition +can be fulfilled with the currently set of accepted licenses. +Prints either yes or no to stdout if the condition can be parsed, +otherwise it exits with error. .It Cm check-pkg-vulnerabilities Oo Fl s Oc Ar file Check format and hashes in the pkg-vulnerabilities file .Ar file . @@ -170,6 +176,12 @@ is given, also check the embedded signature. Reports if .Ar file is a correctly signed package. +.It Cm check-single-license Ar liccense +Check if +.Ar license +is a valid license name and if it is in the set of acceptable licenses. +Prints either yes or no to stdout if the condition can be parsed, +otherwise it exits with error. .It Cm config-var Ar variable Print the current value of .Ar variable diff --git a/pkgtools/pkg_install/files/lib/Makefile.in b/pkgtools/pkg_install/files/lib/Makefile.in index 69b8ac6abde..3dc8ca65301 100644 --- a/pkgtools/pkg_install/files/lib/Makefile.in +++ b/pkgtools/pkg_install/files/lib/Makefile.in @@ -1,4 +1,4 @@ -# $NetBSD: Makefile.in,v 1.26 2009/02/28 16:03:56 joerg Exp $ +# $NetBSD: Makefile.in,v 1.27 2009/04/25 21:31:13 joerg Exp $ srcdir= @srcdir@ @@ -27,7 +27,7 @@ INSTALL= @INSTALL@ LIB= libinstall.a OBJS= automatic.o conflicts.o decompress.o dewey.o fexec.o file.o \ - gpgsig.o global.o iterate.o lpkg.o opattern.o \ + gpgsig.o global.o iterate.o license.o lpkg.o opattern.o \ parse-config.o pkgdb.o plist.o remove.o \ str.o var.o version.o vulnerabilities-file.o xwrapper.o diff --git a/pkgtools/pkg_install/files/lib/lib.h b/pkgtools/pkg_install/files/lib/lib.h index 95e449823a0..b7e073702fc 100644 --- a/pkgtools/pkg_install/files/lib/lib.h +++ b/pkgtools/pkg_install/files/lib/lib.h @@ -1,4 +1,4 @@ -/* $NetBSD: lib.h,v 1.54 2009/04/24 14:00:26 joerg Exp $ */ +/* $NetBSD: lib.h,v 1.55 2009/04/25 21:31:13 joerg Exp $ */ /* from FreeBSD Id: lib.h,v 1.25 1997/10/08 07:48:03 charnier Exp */ @@ -399,6 +399,13 @@ int detached_gpg_verify(const char *, size_t, const char *, size_t, int detached_gpg_sign(const char *, size_t, char **, size_t *, const char *, const char *); +/* License handling */ +int add_licenses(const char *); +int acceptable_license(const char *); +int acceptable_pkg_license(const char *); +void load_license_lists(void); + +/* Helper functions for memory allocation */ char *xstrdup(const char *); void *xrealloc(void *, size_t); void *xcalloc(size_t, size_t); @@ -429,4 +436,7 @@ extern const char *pkg_vulnerabilities_url; extern const char *ignore_advisories; extern const char tnf_vulnerability_base[]; +extern const char *acceptable_licenses; +extern const char *default_acceptable_licenses; + #endif /* _INST_LIB_LIB_H_ */ diff --git a/pkgtools/pkg_install/files/lib/license.c b/pkgtools/pkg_install/files/lib/license.c new file mode 100644 index 00000000000..1516a85a1da --- /dev/null +++ b/pkgtools/pkg_install/files/lib/license.c @@ -0,0 +1,275 @@ +/* $NetBSD: license.c,v 1.1 2009/04/25 21:31:14 joerg Exp $ */ + +/*- + * Copyright (c) 2009 Joerg Sonnenberger <joerg@NetBSD.org>. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <nbcompat.h> + +#if HAVE_ERR_H +#include <err.h> +#endif +#include <stdlib.h> +#include <string.h> + +#include "lib.h" + +#define HASH_SIZE 521 + +const char *default_acceptable_licenses = + "public-domain " + "gnu-gpl-v2 " + "gnu-lgpl-v2 gnu-lgpl-v2.1 " + "gnu-gpl-v3 gnu-lgpl-v3 " + "original-bsd modified-bsd x11 " + "apache-2.0 " + "artistic artistic-2.0 " + "cddl-1.0 " + "open-font-license "; + +#ifdef DEBUG +static size_t hash_collisions; +#endif + +static char **license_hash[HASH_SIZE]; +static const char license_spaces[] = " \t\n"; +static const char license_chars[] = "abcdefghijklmnopqrstuvwxyz0123456789_-."; + +static size_t +hash_license(const char *license, size_t len) +{ + size_t hash; + + for (hash = 0; *license && len; ++license, --len) + hash = *license + hash * 32; + return hash % HASH_SIZE; +} + +static void +add_license_internal(const char *license, size_t len) +{ + char *new_license; + size_t slot, i; + + slot = hash_license(license, len); + + new_license = malloc(len + 1); + memcpy(new_license, license, len); + new_license[len] = '\0'; + + if (license_hash[slot] == NULL) { + license_hash[slot] = calloc(sizeof(char *), 2); + license_hash[slot][0] = new_license; + } else { + for (i = 0; license_hash[slot][i]; ++i) { + if (!memcmp(license_hash[slot][i], license, len) && + license_hash[slot][i][len] == '\0') { + free(new_license); + return; + } + } + +#ifdef DEBUG + ++hash_collisions; +#endif + + license_hash[slot] = realloc(license_hash[slot], + sizeof(char *) * (i + 2)); + license_hash[slot][i] = new_license; + license_hash[slot][i + 1] = NULL; + } +} + +int +add_licenses(const char *line) +{ + const char *next; + + if (line == NULL) + return 0; + + for (line += strspn(line, license_spaces); line; ) { + next = line + strspn(line, license_chars); + if (next == line) + return *line ? -1 : 0; + add_license_internal(line, next - line); + line = next + strspn(next, license_spaces); + if (next == line) + return *line ? -1 : 0; + } + return 0; +} + +static int +acceptable_license_internal(const char *license, size_t len) +{ + size_t slot, i; + + slot = hash_license(license, len); + + if (license_hash[slot] == NULL) + return 0; + + for (i = 0; license_hash[slot][i]; ++i) { + if (strncmp(license_hash[slot][i], license, len) == 0 && + license_hash[slot][i][len] == '\0') + return 1; + } + + return 0; +} + +int +acceptable_license(const char *license) +{ + size_t len; + + len = strlen(license); + if (strspn(license, license_chars) != len) + return -1; + + return acceptable_license_internal(license, len); +} + +static int +acceptable_pkg_license_internal(const char **licensep, int toplevel) +{ + const char *license = *licensep; + int need_parenthesis, is_true = 0; + int expr_type = 0; /* 0: unset, 1: or, 2: and */ + size_t len; + + license += strspn(license, license_spaces); + + if (*license == '(' && !toplevel) { + need_parenthesis = 1; + ++license; + license += strspn(license, license_spaces); + } else { + need_parenthesis = 0; + } + + for (;;) { + if (*license == '(') { + switch (acceptable_pkg_license_internal(&license, 0)) { + case -1: + return -1; + case 0: + if (expr_type == 2) + is_true = 0; + break; + case 1: + is_true = 1; + break; + } + license += strspn(license, license_spaces); + } else { + len = strspn(license, license_chars); + if (len == 0) + return -1; + + if (acceptable_license_internal(license, len)) { + if (expr_type != 2) + is_true = 1; + } else if (expr_type == 2) { + is_true = 0; + } + + license += len; + + len = strspn(license, license_spaces); + if (len == 0 && *license && *license != ')') + return -1; + license += len; + } + + if (*license == ')') { + if (!need_parenthesis) + return -1; + *licensep = license + 1; + return is_true; + } + if (*license == '\0') { + if (need_parenthesis) + return -1; + *licensep = license; + return is_true; + } + + if (strncmp(license, "AND", 3) == 0) { + if (expr_type == 1) + return -1; + expr_type = 2; + license += 3; + } else if (strncmp(license, "OR", 2) == 0) { + if (expr_type == 2) + return -1; + expr_type = 1; + license += 2; + } else { + return -1; + } + len = strspn(license, license_spaces); + if (len == 0 && *license != '(') + return -1; + license += len; + } + + return is_true; +} + +int +acceptable_pkg_license(const char *license) +{ + int ret; + + ret = acceptable_pkg_license_internal(&license, 1); + if (ret == -1) + return -1; + license += strspn(license, license_spaces); + if (*license) + return -1; + return ret; +} + +void +load_license_lists(void) +{ + if (add_licenses(getenv("PKGSRC_ACCEPTABLE_LICENSES"))) + errx(EXIT_FAILURE, "syntax error in PKGSRC_ACCEPTABLE_LICENSES"); + if (add_licenses(acceptable_licenses)) + errx(EXIT_FAILURE, "syntax error in ACCEPTABLE_LICENSES"); + if (add_licenses(getenv("PKGSRC_DEFAULT_ACCEPTABLE_LICENSES"))) + errx(EXIT_FAILURE, "syntax error in PKGSRC_DEFAULT_ACCEPTABLE_LICENSES"); + if (add_licenses(default_acceptable_licenses)) + errx(EXIT_FAILURE, "syntax error in DEFAULT_ACCEPTABLE_LICENSES"); +} diff --git a/pkgtools/pkg_install/files/lib/parse-config.c b/pkgtools/pkg_install/files/lib/parse-config.c index 0fbe45961de..60aabf0d0ac 100644 --- a/pkgtools/pkg_install/files/lib/parse-config.c +++ b/pkgtools/pkg_install/files/lib/parse-config.c @@ -1,4 +1,4 @@ -/* $NetBSD: parse-config.c,v 1.4 2009/02/28 16:03:56 joerg Exp $ */ +/* $NetBSD: parse-config.c,v 1.5 2009/04/25 21:31:14 joerg Exp $ */ #if HAVE_CONFIG_H #include "config.h" @@ -7,7 +7,7 @@ #if HAVE_SYS_CDEFS_H #include <sys/cdefs.h> #endif -__RCSID("$NetBSD: parse-config.c,v 1.4 2009/02/28 16:03:56 joerg Exp $"); +__RCSID("$NetBSD: parse-config.c,v 1.5 2009/04/25 21:31:14 joerg Exp $"); /*- * Copyright (c) 2008 Joerg Sonnenberger <joerg@NetBSD.org>. @@ -68,18 +68,20 @@ const char *pkg_vulnerabilities_dir; const char *pkg_vulnerabilities_file; const char *pkg_vulnerabilities_url; const char *ignore_advisories = NULL; - const char tnf_vulnerability_base[] = "ftp://ftp.NetBSD.org/pub/NetBSD/packages/vulns"; +const char *acceptable_licenses = NULL; static struct config_variable { const char *name; const char **var; } config_variables[] = { + { "ACCEPTABLE_LICENSES", &acceptable_licenses }, { "ACTIVE_FTP", &active_ftp }, { "CERTIFICATE_ANCHOR_PKGS", &certs_packages }, { "CERTIFICATE_ANCHOR_PKGVULN", &certs_pkg_vulnerabilities }, { "CERTIFICATE_CHAIN", &cert_chain_file }, { "CHECK_VULNERABILITIES", &check_vulnerabilities }, + { "DEFAULT_ACCEPTABLE_LICENSES", &default_acceptable_licenses }, { "GPG", &gpg_cmd }, { "GPG_KEYRING_PKGVULN", &gpg_keyring_pkgvuln }, { "GPG_KEYRING_SIGN", &gpg_keyring_sign }, diff --git a/pkgtools/pkg_install/files/lib/pkg_install.conf.5.in b/pkgtools/pkg_install/files/lib/pkg_install.conf.5.in index 502a041446a..00f38fe5ccd 100644 --- a/pkgtools/pkg_install/files/lib/pkg_install.conf.5.in +++ b/pkgtools/pkg_install/files/lib/pkg_install.conf.5.in @@ -1,4 +1,4 @@ -.\" $NetBSD: pkg_install.conf.5.in,v 1.5 2009/03/10 20:33:43 joerg Exp $ +.\" $NetBSD: pkg_install.conf.5.in,v 1.6 2009/04/25 21:31:14 joerg Exp $ .\" .\" Copyright (c) 2008, 2009 The NetBSD Foundation, Inc. .\" All rights reserved. @@ -27,7 +27,7 @@ .\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE .\" POSSIBILITY OF SUCH DAMAGE. .\" -.Dd February 27, 2009 +.Dd April 25, 2009 .Dt PKG_INSTALL.CONF 5 .Os .Sh NAME @@ -48,6 +48,8 @@ The current value of a variable can be checked by running .Pp The following variables are supported: .Bl -tag -width indent +.It Dv ACCEPTABLE_LICENSES +List of licenses packages are allowed to carry. .It Dv ACTIVE_FTP Force the use of active FTP. .It Dv CERTIFICATE_ANCHOR_PKGS @@ -79,6 +81,8 @@ A missing pkg-vulnerabilities file is considered an error. .It Dv interactive The user is always asked to confirm installation of vulnerable packages. .El +.It Dv DEFAULT_ACCEPTABLE_LICENSES +List of common Free and Open Source licenses packages are allowed to carry. .It Dv GPG Path to .Xr gpg 1 , diff --git a/pkgtools/pkg_install/files/lib/version.h b/pkgtools/pkg_install/files/lib/version.h index 09fa580285e..38511738ee5 100644 --- a/pkgtools/pkg_install/files/lib/version.h +++ b/pkgtools/pkg_install/files/lib/version.h @@ -1,4 +1,4 @@ -/* $NetBSD: version.h,v 1.124 2009/04/24 14:00:26 joerg Exp $ */ +/* $NetBSD: version.h,v 1.125 2009/04/25 21:31:14 joerg Exp $ */ /* * Copyright (c) 2001 Thomas Klausner. All rights reserved. @@ -27,6 +27,6 @@ #ifndef _INST_LIB_VERSION_H_ #define _INST_LIB_VERSION_H_ -#define PKGTOOLS_VERSION "20090424" +#define PKGTOOLS_VERSION "20090425" #endif /* _INST_LIB_VERSION_H_ */ |