Synchronize pkg_install with HEAD:
- Add pkg_updating, - Remove pkg_sign, - Support for 8-CURRENT, - Style cleanup (__P use), - ... and much more.
This commit is contained in:
parent
788ab66c9b
commit
657a605681
@ -1,9 +1,7 @@
|
||||
# $FreeBSD$
|
||||
|
||||
SUBDIR= lib add create delete info ${_sign} version
|
||||
.include <bsd.own.mk>
|
||||
|
||||
.if !defined(NO_CRYPT) && !defined(NO_OPENSSL)
|
||||
_sign= sign
|
||||
.endif
|
||||
SUBDIR= lib add create delete info updating version
|
||||
|
||||
.include <bsd.subdir.mk>
|
||||
|
@ -31,6 +31,7 @@ extern Boolean NoInstall;
|
||||
extern Boolean NoRecord;
|
||||
extern Boolean FailOnAlreadyInstalled;
|
||||
extern Boolean KeepPackage;
|
||||
extern Boolean IgnoreDeps;
|
||||
extern char *Mode;
|
||||
extern char *Owner;
|
||||
extern char *Group;
|
||||
|
@ -27,7 +27,7 @@ __FBSDID("$FreeBSD$");
|
||||
#include "lib.h"
|
||||
#include "add.h"
|
||||
|
||||
static char Options[] = "hvIRfFnrp:P:SMt:C:K";
|
||||
static char Options[] = "hviIRfFnrp:P:SMt:C:K";
|
||||
|
||||
char *Prefix = NULL;
|
||||
Boolean PrefixRecursive = FALSE;
|
||||
@ -37,6 +37,7 @@ Boolean NoRecord = FALSE;
|
||||
Boolean Remote = FALSE;
|
||||
Boolean KeepPackage = FALSE;
|
||||
Boolean FailOnAlreadyInstalled = TRUE;
|
||||
Boolean IgnoreDeps = FALSE;
|
||||
|
||||
char *Mode = NULL;
|
||||
char *Owner = NULL;
|
||||
@ -77,11 +78,14 @@ struct {
|
||||
{ 601000, 601099, "/packages-6.1-release" },
|
||||
{ 602000, 602099, "/packages-6.2-release" },
|
||||
{ 603000, 603099, "/packages-6.3-release" },
|
||||
{ 700000, 700099, "/packages-7.0-release" },
|
||||
{ 300000, 399000, "/packages-3-stable" },
|
||||
{ 400000, 499000, "/packages-4-stable" },
|
||||
{ 502100, 502128, "/packages-5-current" },
|
||||
{ 503100, 599000, "/packages-5-stable" },
|
||||
{ 600100, 699000, "/packages-6-stable" },
|
||||
{ 700100, 799000, "/packages-7-stable" },
|
||||
{ 800000, 899000, "/packages-8-current" },
|
||||
{ 0, 9999999, "/packages-current" },
|
||||
{ 0, 0, NULL }
|
||||
};
|
||||
@ -89,7 +93,7 @@ struct {
|
||||
static char *getpackagesite(void);
|
||||
int getosreldate(void);
|
||||
|
||||
static void usage __P((void));
|
||||
static void usage(void);
|
||||
|
||||
int
|
||||
main(int argc, char **argv)
|
||||
@ -109,7 +113,7 @@ main(int argc, char **argv)
|
||||
while ((ch = getopt(argc, argv, Options)) != -1) {
|
||||
switch(ch) {
|
||||
case 'v':
|
||||
Verbose = TRUE;
|
||||
Verbose++;
|
||||
break;
|
||||
|
||||
case 'p':
|
||||
@ -166,6 +170,9 @@ main(int argc, char **argv)
|
||||
case 'C':
|
||||
Chroot = optarg;
|
||||
break;
|
||||
case 'i':
|
||||
IgnoreDeps = TRUE;
|
||||
break;
|
||||
|
||||
case 'h':
|
||||
case '?':
|
||||
@ -178,7 +185,7 @@ main(int argc, char **argv)
|
||||
argv += optind;
|
||||
|
||||
if (AddMode != SLAVE) {
|
||||
pkgs = (char **)malloc((argc + 1) * sizeof(char *));
|
||||
pkgs = (char **)malloc((argc+1) * sizeof(char *));
|
||||
for (ch = 0; ch <= argc; pkgs[ch++] = NULL) ;
|
||||
|
||||
/* Get all the remaining package names, if any */
|
||||
@ -321,7 +328,7 @@ static void
|
||||
usage()
|
||||
{
|
||||
fprintf(stderr, "%s\n%s\n",
|
||||
"usage: pkg_add [-vInrfRMSK] [-t template] [-p prefix] [-P prefix] [-C chrootdir]",
|
||||
"usage: pkg_add [-viInfFrRMSK] [-t template] [-p prefix] [-P prefix] [-C chrootdir]",
|
||||
" pkg-name [pkg-name ...]");
|
||||
exit(1);
|
||||
}
|
||||
|
@ -252,6 +252,7 @@ pkg_do(char *pkg)
|
||||
}
|
||||
|
||||
/* Now check the packing list for conflicts */
|
||||
if (!IgnoreDeps){
|
||||
for (p = Plist.head; p != NULL; p = p->next) {
|
||||
if (p->type == PLIST_CONFLICTS) {
|
||||
int i;
|
||||
@ -368,6 +369,7 @@ pkg_do(char *pkg)
|
||||
else if (Verbose)
|
||||
printf(" - already installed.\n");
|
||||
}
|
||||
} /* if (!IgnoreDeps) */
|
||||
|
||||
if (code != 0)
|
||||
goto bomb;
|
||||
@ -514,6 +516,7 @@ pkg_do(char *pkg)
|
||||
depnames[0] = p->name;
|
||||
depnames[1] = NULL;
|
||||
}
|
||||
if(!IgnoreDeps){
|
||||
for (i = 0; depnames[i] != NULL; i++) {
|
||||
sprintf(contents, "%s/%s/%s", LOG_DIR, depnames[i],
|
||||
REQUIRED_BY_FNAME);
|
||||
@ -531,6 +534,7 @@ pkg_do(char *pkg)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (Verbose)
|
||||
printf("Package %s registered in %s\n", Plist.name, LogDir);
|
||||
}
|
||||
|
@ -15,7 +15,7 @@
|
||||
.\"
|
||||
.\" $FreeBSD$
|
||||
.\"
|
||||
.Dd January 16, 2006
|
||||
.Dd November 29, 2007
|
||||
.Dt PKG_ADD 1
|
||||
.Os
|
||||
.Sh NAME
|
||||
@ -23,7 +23,7 @@
|
||||
.Nd a utility for installing software package distributions
|
||||
.Sh SYNOPSIS
|
||||
.Nm
|
||||
.Op Fl vInfFrRMSK
|
||||
.Op Fl viInfFrRMSK
|
||||
.Op Fl t Ar template
|
||||
.Op Fl p Ar prefix
|
||||
.Op Fl P Ar prefix
|
||||
@ -87,6 +87,9 @@ Turn on verbose output.
|
||||
Keep any downloaded package in
|
||||
.Ev PKGDIR
|
||||
if it is defined or in current directory by default.
|
||||
.It Fl i
|
||||
Install the package without fetching and installing
|
||||
dependencies.
|
||||
.It Fl I
|
||||
If any installation scripts (pre-install or post-install) exist for a given
|
||||
package, do not execute them.
|
||||
@ -134,11 +137,12 @@ modes (see the
|
||||
.Fl M
|
||||
and
|
||||
.Fl S
|
||||
options). If the
|
||||
options).
|
||||
If the
|
||||
.Fl p
|
||||
flag appears after any
|
||||
.Fl P
|
||||
flag on the command line, it overrides it's effect, causing
|
||||
flag on the command line, it overrides its effect, causing
|
||||
.Nm
|
||||
not to use the given
|
||||
.Ar prefix
|
||||
@ -148,11 +152,12 @@ Does the same as the
|
||||
.Fl p
|
||||
option, except that the given
|
||||
.Ar prefix
|
||||
is also used recursively for the dependency packages, if any. If the
|
||||
is also used recursively for the dependency packages, if any.
|
||||
If the
|
||||
.Fl P
|
||||
flag appears after any
|
||||
.Fl p
|
||||
flag on the command line, it overrides it's effect, causing
|
||||
flag on the command line, it overrides its effect, causing
|
||||
.Nm
|
||||
to use the given
|
||||
.Ar prefix
|
||||
@ -279,8 +284,11 @@ ftp.
|
||||
.Sh TECHNICAL DETAILS
|
||||
The
|
||||
.Nm
|
||||
utility extracts each package's "packing list" into a special staging
|
||||
directory in /tmp (or $PKG_TMPDIR if set), parses it, and then runs
|
||||
utility extracts each package's
|
||||
.Dq "packing list"
|
||||
into a special staging directory (see
|
||||
.Sx ENVIRONMENT ) ,
|
||||
parses it, and then runs
|
||||
through the following sequence to fully extract the contents of the package:
|
||||
.Bl -enum
|
||||
.It
|
||||
@ -288,14 +296,14 @@ A check is made to determine if the package is already recorded as installed.
|
||||
If it is, installation is terminated.
|
||||
.It
|
||||
A check is made to determine if the package conflicts (from
|
||||
.Cm @conflicts
|
||||
.Ic @conflicts
|
||||
directives, see
|
||||
.Xr pkg_create 1 )
|
||||
with an already-installed package.
|
||||
with an already installed package.
|
||||
If it is, installation is terminated.
|
||||
.It
|
||||
Scan all the package dependencies (from
|
||||
.Cm @pkgdep
|
||||
.Ic @pkgdep
|
||||
directives, see
|
||||
.Xr pkg_create 1 )
|
||||
are read from the packing list.
|
||||
@ -305,54 +313,51 @@ if the missing package cannot be found or installed,
|
||||
the installation is terminated.
|
||||
.It
|
||||
Search for any
|
||||
.Cm @option
|
||||
.Ic @option
|
||||
directives which control how the package is added to the system.
|
||||
At the time of this writing, the only currently implemented option is
|
||||
.Cm @option extract-in-place
|
||||
.Ic @option Cm extract-in-place
|
||||
which will cause the package to be extracted directly into its
|
||||
prefix directory without moving through a staging area in
|
||||
.Pa /tmp .
|
||||
prefix directory without moving through a staging area.
|
||||
.It
|
||||
If
|
||||
.Cm @option extract-in-place
|
||||
.Ic @option Cm extract-in-place
|
||||
is enabled, the package is now extracted directly into its
|
||||
final location, otherwise it is extracted into the staging area.
|
||||
.It
|
||||
If the package contains a
|
||||
.Ar require
|
||||
file (see
|
||||
If a requirements script
|
||||
.Pa +REQUIRE
|
||||
exists for the package (see the
|
||||
.Fl r
|
||||
flag of
|
||||
.Xr pkg_create 1 ) ,
|
||||
then execute it with the following arguments:
|
||||
.Bd -ragged -offset indent -compact
|
||||
.Ar pkg-name
|
||||
.Ar INSTALL
|
||||
.Ed
|
||||
.Pp
|
||||
.D1 Ar pkg-name Li INSTALL
|
||||
.Pp
|
||||
where
|
||||
.Ar pkg-name
|
||||
is the name of the package in question and the
|
||||
.Ar INSTALL
|
||||
.Dq Li INSTALL
|
||||
keyword denotes this as an installation requirements check (useful if
|
||||
you want to have one script serving multiple functions).
|
||||
.It
|
||||
If a
|
||||
.Ar pre-install
|
||||
script exists for the package, it is then executed with the following
|
||||
arguments:
|
||||
.Bd -ragged -offset indent -compact
|
||||
.Cm script
|
||||
.Ar pkg-name
|
||||
.Ar PRE-INSTALL
|
||||
.Ed
|
||||
If a pre-install script
|
||||
.Pa +INSTALL
|
||||
exists for the package,
|
||||
it is then executed with the following arguments:
|
||||
.Pp
|
||||
.D1 Ar pkg-name Li PRE-INSTALL
|
||||
.Pp
|
||||
where
|
||||
.Ar pkg-name
|
||||
is the name of the package in question and
|
||||
.Ar PRE-INSTALL
|
||||
.Dq Li PRE-INSTALL
|
||||
is a keyword denoting this as the preinstallation phase.
|
||||
.Pp
|
||||
.Sy Note :
|
||||
The
|
||||
.Ar PRE-INSTALL
|
||||
.Dq Li PRE-INSTALL
|
||||
keyword will not appear if separate scripts for pre-install and post-install
|
||||
are given during package creation time (using the
|
||||
.Fl i
|
||||
@ -362,55 +367,51 @@ flags to
|
||||
.Xr pkg_create 1 ) .
|
||||
.It
|
||||
If
|
||||
.Cm @option extract-in-place
|
||||
.Cm @option Cm extract-in-place
|
||||
is not used, then the packing list (this is the
|
||||
.Pa +CONTENTS
|
||||
file) is now used as a guide for moving (or copying, as necessary) files from
|
||||
the staging area into their final locations.
|
||||
.It
|
||||
If the package contains an
|
||||
.Ar mtreefile
|
||||
file (see
|
||||
If an mtree file
|
||||
.Pa +MTREE_DIRS
|
||||
exists for the package (see the
|
||||
.Fl m
|
||||
flag of
|
||||
.Xr pkg_create 1 ) ,
|
||||
then mtree is invoked as:
|
||||
.Bd -ragged -offset indent -compact
|
||||
.Cm mtree
|
||||
.Fl u
|
||||
.Fl f
|
||||
.Ar mtreefile
|
||||
.Fl d
|
||||
.Fl e
|
||||
.Fl p
|
||||
.Pa prefix
|
||||
.Ed
|
||||
then
|
||||
.Xr mtree 8
|
||||
is invoked as:
|
||||
.Pp
|
||||
.D1 Nm mtree Fl U f Pa +MTREE_DIRS Fl d e p Ar prefix
|
||||
.Pp
|
||||
where
|
||||
.Pa prefix
|
||||
.Ar prefix
|
||||
is either the prefix specified with the
|
||||
.Fl p
|
||||
or
|
||||
.Fl P
|
||||
flag or,
|
||||
if neither flag was specified, the name of the first directory named by a
|
||||
.Cm @cwd
|
||||
.Ic @cwd
|
||||
directive within this package.
|
||||
.It
|
||||
If a
|
||||
.Ar post-install
|
||||
script exists for the package, it is then executed as
|
||||
.Bd -ragged -offset indent -compact
|
||||
.Cm script
|
||||
.Ar pkg-name
|
||||
.Ar POST-INSTALL
|
||||
.Ed
|
||||
If a post-install script
|
||||
.Pa +POST-INSTALL
|
||||
exists for the package,
|
||||
it is then executed with the following arguments:
|
||||
.Pp
|
||||
.D1 Ar pkg-name Li POST-INSTALL
|
||||
.Pp
|
||||
where
|
||||
.Ar pkg-name
|
||||
is the name of the package in question and
|
||||
.Ar POST-INSTALL
|
||||
.Dq Li POST-INSTALL
|
||||
is a keyword denoting this as the post-installation phase.
|
||||
.Pp
|
||||
.Sy Note :
|
||||
The
|
||||
.Ar POST-INSTALL
|
||||
.Dq Li POST-INSTALL
|
||||
keyword will not appear if separate scripts for pre-install and post-install
|
||||
are given during package creation time (using the
|
||||
.Fl i
|
||||
@ -420,27 +421,50 @@ flags to
|
||||
.Xr pkg_create 1 ) .
|
||||
.Pp
|
||||
Reasoning behind passing keywords such as
|
||||
.Ar POST-INSTALL
|
||||
.Dq Li POST-INSTALL
|
||||
and
|
||||
.Ar PRE-INSTALL
|
||||
.Dq Li PRE-INSTALL
|
||||
is that this allows you to write a single
|
||||
.Ar install
|
||||
install
|
||||
script that does both
|
||||
.Dq before and after
|
||||
.Dq before
|
||||
and
|
||||
.Dq after
|
||||
actions.
|
||||
But, separating the
|
||||
functionality is more advantageous and easier from a maintenance viewpoint.
|
||||
.It
|
||||
After installation is complete, a copy of the packing list,
|
||||
.Ar deinstall
|
||||
script, description, and display files are copied into
|
||||
.Pa /var/db/pkg/<pkg-name>
|
||||
After installation is complete, a copy of the
|
||||
description
|
||||
.Pq Pa +DESC ,
|
||||
comment
|
||||
.Pq Pa +COMMENT ,
|
||||
pre-install script
|
||||
.Pq Pa +INSTALL ,
|
||||
post-install script
|
||||
.Pq Pa +POST-INSTALL ,
|
||||
deinstall script
|
||||
.Pq Pa +DEINSTALL ,
|
||||
post-deinstall script
|
||||
.Pq Pa +POST-DEINSTALL ,
|
||||
requirements script
|
||||
.Pq Pa +REQUIRE ,
|
||||
display
|
||||
.Pq Pa +DISPLAY ,
|
||||
mtree
|
||||
.Pq Pa +MTREE_DIRS ,
|
||||
and packing list
|
||||
.Pq Pa +CONTENTS
|
||||
files are copied into
|
||||
.Pa /var/db/pkg/ Ns Aq Ar pkg-name
|
||||
for subsequent possible use by
|
||||
.Xr pkg_delete 1 .
|
||||
Any package dependencies are recorded in the other packages'
|
||||
.Pa /var/db/pkg/<other-pkg>/+REQUIRED_BY
|
||||
.Pa /var/db/pkg/ Ns Ao Ar other-pkg Ac Ns Pa /+REQUIRED_BY
|
||||
file
|
||||
(if the environment variable PKG_DBDIR is set, this overrides the
|
||||
(if the environment variable
|
||||
.Ev PKG_DBDIR
|
||||
is set, this overrides the
|
||||
.Pa /var/db/pkg/
|
||||
path shown above).
|
||||
.It
|
||||
@ -461,7 +485,7 @@ is installed, even if the user might change it with the
|
||||
or
|
||||
.Fl P
|
||||
flags to
|
||||
.Cm pkg_add .
|
||||
.Nm .
|
||||
.Sh ENVIRONMENT
|
||||
The value of the
|
||||
.Ev PKG_PATH
|
||||
|
@ -42,13 +42,13 @@ int Dereference = FALSE;
|
||||
int PlistOnly = FALSE;
|
||||
int Recursive = FALSE;
|
||||
#if defined(__FreeBSD_version) && __FreeBSD_version >= 500039
|
||||
enum zipper Zipper = BZIP2;
|
||||
enum zipper Zipper = BZIP2;
|
||||
#else
|
||||
enum zipper Zipper = GZIP;
|
||||
enum zipper Zipper = GZIP;
|
||||
#endif
|
||||
|
||||
|
||||
static void usage __P((void));
|
||||
static void usage(void);
|
||||
|
||||
int
|
||||
main(int argc, char **argv)
|
||||
@ -60,7 +60,7 @@ main(int argc, char **argv)
|
||||
while ((ch = getopt(argc, argv, Options)) != -1)
|
||||
switch(ch) {
|
||||
case 'v':
|
||||
Verbose = TRUE;
|
||||
Verbose++;
|
||||
break;
|
||||
|
||||
case 'x':
|
||||
@ -228,12 +228,12 @@ static void
|
||||
usage()
|
||||
{
|
||||
fprintf(stderr, "%s\n%s\n%s\n%s\n%s\n%s\n%s\n",
|
||||
"usage: pkg_create [-YNOhvyz] [-P pkgs] [-C conflicts] [-p prefix] ",
|
||||
" [-i iscript] [-I piscript] [-k dscript] [-K pdscript] ",
|
||||
" [-r rscript] [-t template] [-X excludefile] ",
|
||||
" [-D displayfile] [-m mtreefile] [-o origin] ",
|
||||
" [-s srcdir] [-S basedir] ",
|
||||
"usage: pkg_create [-YNOhjvyz] [-C conflicts] [-P pkgs] [-p prefix]",
|
||||
" [-i iscript] [-I piscript] [-k dscript] [-K pdscript]",
|
||||
" [-r rscript] [-s srcdir] [-S basedir]",
|
||||
" [-t template] [-X excludefile]",
|
||||
" [-D displayfile] [-m mtreefile] [-o originpath]",
|
||||
" -c comment -d description -f packlist pkg-filename",
|
||||
" pkg_create [-EGYNhvxyzR] -b pkg-name [pkg-filename]");
|
||||
" pkg_create [-EGYNRhvxy] -b pkg-name [pkg-filename]");
|
||||
exit(1);
|
||||
}
|
||||
|
@ -37,7 +37,7 @@ Boolean NoDeInstall = FALSE;
|
||||
Boolean Recursive = FALSE;
|
||||
match_t MatchType = MATCH_GLOB;
|
||||
|
||||
static void usage __P((void));
|
||||
static void usage(void);
|
||||
|
||||
int
|
||||
main(int argc, char **argv)
|
||||
@ -52,7 +52,7 @@ main(int argc, char **argv)
|
||||
while ((ch = getopt(argc, argv, Options)) != -1)
|
||||
switch(ch) {
|
||||
case 'v':
|
||||
Verbose = TRUE;
|
||||
Verbose++;
|
||||
break;
|
||||
|
||||
case 'f':
|
||||
|
@ -266,7 +266,7 @@ pkg_do(char *pkg)
|
||||
for (p = Plist.head; p ; p = p->next) {
|
||||
if (p->type != PLIST_PKGDEP)
|
||||
continue;
|
||||
deporigin = (p->next->type == PLIST_DEPORIGIN) ? p->next->name :
|
||||
deporigin = (p->next != NULL && p->next->type == PLIST_DEPORIGIN) ? p->next->name :
|
||||
NULL;
|
||||
if (Verbose) {
|
||||
printf("Trying to remove dependency on package '%s'", p->name);
|
||||
|
@ -39,7 +39,7 @@ char *LookUpOrigin = NULL;
|
||||
Boolean KeepPackage = FALSE;
|
||||
struct which_head *whead;
|
||||
|
||||
static void usage __P((void));
|
||||
static void usage(void);
|
||||
|
||||
int
|
||||
main(int argc, char **argv)
|
||||
@ -69,7 +69,7 @@ main(int argc, char **argv)
|
||||
break;
|
||||
|
||||
case 'v':
|
||||
Verbose = TRUE;
|
||||
Verbose++;
|
||||
/* Reasonable definition of 'everything' */
|
||||
Flags = SHOW_COMMENT | SHOW_DESC | SHOW_PLIST | SHOW_INSTALL |
|
||||
SHOW_DEINSTALL | SHOW_REQUIRE | SHOW_DISPLAY | SHOW_MTREE;
|
||||
|
@ -17,7 +17,7 @@
|
||||
.\" @(#)pkg_info.1
|
||||
.\" $FreeBSD$
|
||||
.\"
|
||||
.Dd January 16, 2006
|
||||
.Dd January 9, 2006
|
||||
.Dt PKG_INFO 1
|
||||
.Os
|
||||
.Sh NAME
|
||||
@ -25,7 +25,7 @@
|
||||
.Nd a utility for displaying information on software packages
|
||||
.Sh SYNOPSIS
|
||||
.Nm
|
||||
.Op Fl bcdDEfgGijIkKLmopPqQrRsvVxX
|
||||
.Op Fl bcdDEfgGiIjkKLmopPqQrRsvVxX
|
||||
.Op Fl e Ar package
|
||||
.Op Fl l Ar prefix
|
||||
.Op Fl t Ar template
|
||||
@ -56,19 +56,23 @@ A package name may either be the name of
|
||||
an installed package, the pathname to a package distribution file or a
|
||||
URL to an FTP available package.
|
||||
Package version numbers can also be matched in a relational manner using the
|
||||
.Pa \*[Ge], \*[Le], \*[Gt]
|
||||
.Pa >= , <= , >
|
||||
and
|
||||
.Pa \*[Lt]
|
||||
.Pa <
|
||||
operators.
|
||||
For example,
|
||||
.Pa pkg_info 'portupgrade\*[Ge]20030723'
|
||||
.Pp
|
||||
.Dl "pkg_info 'portupgrade>=20030723'"
|
||||
.Pp
|
||||
will match versions 20030723 and later of the
|
||||
.Pa portupgrade
|
||||
package.
|
||||
.It Fl a
|
||||
Show all currently installed packages.
|
||||
.It Fl b
|
||||
Use the BLOCKSIZE environment variable for output even when the
|
||||
Use the
|
||||
.Ev BLOCKSIZE
|
||||
environment variable for output even when the
|
||||
.Fl q
|
||||
or
|
||||
.Fl Q
|
||||
@ -111,11 +115,15 @@ Keep any downloaded package in
|
||||
.Ev PKGDIR
|
||||
if it is defined or in current directory by default.
|
||||
.It Fl r
|
||||
Show the list of packages on which each package depends.
|
||||
For each of the specified packages,
|
||||
show the list of packages on which it depends.
|
||||
.It Fl R
|
||||
Show the list of installed packages which require each package.
|
||||
For each of the specified packages,
|
||||
show the list of installed packages which require it.
|
||||
.It Fl m
|
||||
Show the mtree file (if any) for each package.
|
||||
Show the
|
||||
.Xr mtree 8
|
||||
file (if any) for each package.
|
||||
.It Fl L
|
||||
Show the files within each package.
|
||||
This is different from just
|
||||
@ -127,11 +135,10 @@ Show the total size occupied by files installed within each package.
|
||||
Show the
|
||||
.Dq origin
|
||||
path recorded on package generation.
|
||||
This path
|
||||
intended to give an idea as to where the underlying port, from which
|
||||
package was generated, is located in the
|
||||
This path is the directory name in the
|
||||
.Fx
|
||||
.Em "Ports Collection" .
|
||||
.Em "Ports Collection"
|
||||
of the underlying port from which the package was generated.
|
||||
.It Fl G
|
||||
Do not try to expand shell glob patterns in the
|
||||
.Ar pkg-name
|
||||
@ -139,19 +146,19 @@ when selecting packages to be displayed (by default
|
||||
.Nm
|
||||
automatically expands shell glob patterns in the
|
||||
.Ar pkg-name ) .
|
||||
.It Fl W
|
||||
.It Fl W Ar filename
|
||||
For the specified
|
||||
.Ar filename
|
||||
argument show which package it belongs to.
|
||||
If the file is not in the
|
||||
current directory, and does not have an absolute path, then the
|
||||
directories specified in the environment variable
|
||||
.Ev PATH
|
||||
is searched using
|
||||
are searched using
|
||||
.Xr which 1 .
|
||||
.It Fl O
|
||||
For the specified
|
||||
.Ar origin
|
||||
argument list all packages having this origin.
|
||||
.It Fl O Ar origin
|
||||
List all packages having the specified
|
||||
.Ar origin .
|
||||
.It Fl x
|
||||
Treat the
|
||||
.Ar pkg-name
|
||||
@ -168,9 +175,9 @@ Like
|
||||
but treats the
|
||||
.Ar pkg-name
|
||||
as an extended regular expression.
|
||||
.It Fl e Ar pkg-name
|
||||
.It Fl e Ar package
|
||||
If the package identified by
|
||||
.Ar pkg-name
|
||||
.Ar package
|
||||
is currently installed, return 0, otherwise return 1.
|
||||
This option
|
||||
allows you to easily test for the presence of another (perhaps
|
||||
@ -180,21 +187,21 @@ Show only matching package names.
|
||||
This option takes
|
||||
precedence over all other package formatting options.
|
||||
If any packages match, return 0, otherwise return 1.
|
||||
.It Fl l Ar str
|
||||
.It Fl l Ar prefix
|
||||
Prefix each information category header (see
|
||||
.Fl q )
|
||||
shown with
|
||||
.Ar str .
|
||||
This is primarily of use to front-end programs who want to request a
|
||||
.Ar prefix .
|
||||
This is primarily of use to front-end programs that want to request a
|
||||
lot of different information fields at once for a package, but do not
|
||||
necessary want the output intermingled in such a way that they cannot
|
||||
necessarily want the output intermingled in such a way that they cannot
|
||||
organize it.
|
||||
This lets you add a special token to the start of
|
||||
each field.
|
||||
.It Fl t Ar template
|
||||
Use
|
||||
.Ar template
|
||||
as the input to
|
||||
as the argument to
|
||||
.Xr mktemp 3
|
||||
when creating a
|
||||
.Dq staging area .
|
||||
@ -204,8 +211,9 @@ but it may be necessary to override it in the situation where
|
||||
space in your
|
||||
.Pa /tmp
|
||||
directory is limited.
|
||||
Be sure to leave some number of `X' characters
|
||||
for
|
||||
Be sure to leave some number of
|
||||
.Ql X
|
||||
characters for
|
||||
.Xr mktemp 3
|
||||
to fill in with a unique ID.
|
||||
.Bd -ragged -offset indent -compact
|
||||
@ -227,7 +235,7 @@ command line, or from already installed package information
|
||||
in
|
||||
.Pa /var/db/pkg/ Ns Aq Ar pkg-name .
|
||||
.Sh ENVIRONMENT
|
||||
.Bl -tag -width PKG_TMPDIR
|
||||
.Bl -tag -width ".Ev PKG_TMPDIR"
|
||||
.It Ev BLOCKSIZE
|
||||
If the environment variable
|
||||
.Ev BLOCKSIZE
|
||||
@ -250,7 +258,7 @@ found.
|
||||
Specifies an alternative location to save downloaded packages to.
|
||||
.El
|
||||
.Sh FILES
|
||||
.Bl -tag -width /var/db/pkg -compact
|
||||
.Bl -tag -width ".Pa /var/db/pkg" -compact
|
||||
.It Pa /var/tmp
|
||||
Used if the environment variables
|
||||
.Ev PKG_TMPDIR
|
||||
|
@ -68,8 +68,8 @@ vpipe(const char *fmt, ...)
|
||||
|
||||
rp = malloc(MAXPATHLEN);
|
||||
if (!rp) {
|
||||
warnx("vpipe can't alloc buffer space");
|
||||
return NULL;
|
||||
warnx("vpipe can't alloc buffer space");
|
||||
return NULL;
|
||||
}
|
||||
maxargs = sysconf(_SC_ARG_MAX);
|
||||
maxargs -= 32; /* some slop for the sh -c */
|
||||
|
@ -26,7 +26,7 @@ __FBSDID("$FreeBSD$");
|
||||
|
||||
/* These are global for all utils */
|
||||
Boolean Quiet = FALSE;
|
||||
Boolean Verbose = FALSE;
|
||||
Boolean Fake = FALSE;
|
||||
Boolean Force = FALSE;
|
||||
int AutoAnswer = FALSE;
|
||||
int Verbose = 0; /* Allow multiple levels of verbose. */
|
||||
|
@ -57,6 +57,13 @@
|
||||
/* Usually "rm", but often "echo" during debugging! */
|
||||
#define RMDIR_CMD "/bin/rmdir"
|
||||
|
||||
/* Where the ports lives by default */
|
||||
#define DEF_PORTS_DIR "/usr/ports"
|
||||
/* just in case we change the environment variable name */
|
||||
#define PORTSDIR "PORTSDIR"
|
||||
/* macro to get name of directory where the ports lives */
|
||||
#define PORTS_DIR (getenv(PORTSDIR) ? getenv(PORTSDIR) : DEF_PORTS_DIR)
|
||||
|
||||
/* Where we put logging information by default, else ${PKG_DBDIR} if set */
|
||||
#define DEF_LOG_DIR "/var/db/pkg"
|
||||
/* just in case we change the environment variable name */
|
||||
@ -77,7 +84,9 @@
|
||||
#define DISPLAY_FNAME "+DISPLAY"
|
||||
#define MTREE_FNAME "+MTREE_DIRS"
|
||||
|
||||
#if defined(__FreeBSD_version) && __FreeBSD_version >= 700000
|
||||
#if defined(__FreeBSD_version) && __FreeBSD_version >= 800000
|
||||
#define INDEX_FNAME "INDEX-8"
|
||||
#elif defined(__FreeBSD_version) && __FreeBSD_version >= 700000
|
||||
#define INDEX_FNAME "INDEX-7"
|
||||
#elif defined(__FreeBSD_version) && __FreeBSD_version >= 600000
|
||||
#define INDEX_FNAME "INDEX-6"
|
||||
@ -170,7 +179,7 @@ Boolean fexists(const char *);
|
||||
Boolean isdir(const char *);
|
||||
Boolean isemptydir(const char *fname);
|
||||
Boolean isemptyfile(const char *fname);
|
||||
Boolean isfile(const char *);
|
||||
Boolean isfile(const char *);
|
||||
Boolean isempty(const char *);
|
||||
Boolean issymlink(const char *);
|
||||
Boolean isURL(const char *);
|
||||
@ -230,9 +239,9 @@ int version_cmp(const char *, const char *);
|
||||
|
||||
/* Externs */
|
||||
extern Boolean Quiet;
|
||||
extern Boolean Verbose;
|
||||
extern Boolean Fake;
|
||||
extern Boolean Force;
|
||||
extern int AutoAnswer;
|
||||
extern int Verbose;
|
||||
|
||||
#endif /* _INST_LIB_LIB_H_ */
|
||||
|
@ -480,7 +480,7 @@ delete_package(Boolean ign_err, Boolean nukedirs, Package *pkg)
|
||||
/* Mismatch? */
|
||||
if (strcmp(cp, p->next->name + 4)) {
|
||||
warnx("'%s' fails original MD5 checksum - %s",
|
||||
tmp, Force ? "deleted anyway." : "not deleted.");
|
||||
tmp, Force ? "deleted anyway." : "not deleted.");
|
||||
if (!Force) {
|
||||
fail = FAIL;
|
||||
continue;
|
||||
|
@ -38,8 +38,8 @@ fileGetURL(const char *base, const char *spec, int keep_package)
|
||||
char *cp, *rp, *tmp;
|
||||
char fname[FILENAME_MAX];
|
||||
char pen[FILENAME_MAX];
|
||||
char buf[8192];
|
||||
char pkg[FILENAME_MAX];
|
||||
char buf[8192];
|
||||
FILE *ftp;
|
||||
pid_t tpid;
|
||||
int pfd[2], pstat, r, w = 0;
|
||||
@ -98,18 +98,18 @@ fileGetURL(const char *base, const char *spec, int keep_package)
|
||||
else
|
||||
strcpy(fname, spec);
|
||||
|
||||
if (keep_package) {
|
||||
tmp = getenv("PKGDIR");
|
||||
if (keep_package) {
|
||||
tmp = getenv("PKGDIR");
|
||||
strlcpy(pkg, tmp ? tmp : ".", sizeof(pkg));
|
||||
tmp = basename(fname);
|
||||
strlcat(pkg, "/", sizeof(pkg));
|
||||
strlcat(pkg, tmp, sizeof(pkg));
|
||||
if ((pkgfd = open(pkg, O_WRONLY|O_CREAT|O_TRUNC, 0644)) == -1) {
|
||||
printf("Error: Unable to open %s\n", pkg);
|
||||
if ((pkgfd = open(pkg, O_WRONLY|O_CREAT|O_TRUNC, 0644)) == -1) {
|
||||
printf("Error: Unable to open %s\n", pkg);
|
||||
perror("open");
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fetchDebug = (Verbose > 0);
|
||||
if ((ftp = fetchGetURL(fname, Verbose ? "v" : NULL)) == NULL) {
|
||||
@ -142,9 +142,9 @@ fileGetURL(const char *base, const char *spec, int keep_package)
|
||||
close(fd);
|
||||
execl("/usr/bin/tar", "tar",
|
||||
#if defined(__FreeBSD_version) && __FreeBSD_version >= 500039
|
||||
Verbose ? "-xjvf" : "-xjf",
|
||||
Verbose ? "-xpjvf" : "-xpjf",
|
||||
#else
|
||||
Verbose ? "-xzvf" : "-xzf",
|
||||
Verbose ? "-xpzvf" : "-xpzf",
|
||||
#endif
|
||||
"-", (char *)0);
|
||||
_exit(2);
|
||||
|
@ -1,16 +0,0 @@
|
||||
# $FreeBSD$
|
||||
# $OpenBSD: Makefile.bsd-wrapper,v 1.2 1999/10/07 16:30:32 espie Exp $
|
||||
|
||||
PROG= pkg_sign
|
||||
LINKS= ${BINDIR}/pkg_sign ${BINDIR}/pkg_check
|
||||
MLINKS= pkg_sign.1 pkg_check.1
|
||||
SRCS= main.c check.c common.c gzip.c pgp_check.c pgp_sign.c \
|
||||
sha1.c sign.c stand.c x509.c
|
||||
|
||||
CFLAGS+= -I${.CURDIR}/../lib
|
||||
|
||||
DPADD= ${LIBINSTALL} ${LIBMD} ${LIBCRYPTO}
|
||||
LDADD= ${LIBINSTALL} -lmd -lcrypto
|
||||
|
||||
.include <bsd.prog.mk>
|
||||
|
@ -1,55 +0,0 @@
|
||||
To sign packages in a transparent way:
|
||||
gzip files can handle an extra field at the beginning that
|
||||
stores anything we wish.
|
||||
|
||||
So it's just a question to choose a format for the signature, and to
|
||||
embed it there.
|
||||
|
||||
We use the extra field to store signatures. Each signature consists
|
||||
of a 6 bytes type marker, a 2 bytes length, followed by the signature
|
||||
itself. We can potentially stack signatures: resign a signed archive
|
||||
by just prepending the new signature to the extra field.
|
||||
|
||||
To check the first signature, the checker just needs to extract it, pass it
|
||||
off to the checking protocol (e.g. PGP), followed by the unsigned archive
|
||||
(e.g., regenerate the gzip header without the first signature, then put
|
||||
the gzip data).
|
||||
|
||||
* Signed archives just look like normal .tar.gz files, except for programs
|
||||
that use the extra field for their own purpose,
|
||||
* Possibility to grab the files off the net and extract stuff/verify
|
||||
signatures on the fly (just need to wedge the checker as an intermediate
|
||||
pipe)
|
||||
* Pretty simple, small portable code to be able to check signatures
|
||||
everywhere (the signer itself needs getpass and corresponding functionality)
|
||||
|
||||
The scheme should be extensible to any compressed format which allows for
|
||||
extended headers.
|
||||
|
||||
|
||||
Thanks to Angelos D. Keromytis for pointing out I did not need to
|
||||
uncompress the archive to sign it, and to other members of the OpenBSD
|
||||
project for various reasons.
|
||||
|
||||
--
|
||||
Marc Espie, 1999
|
||||
$OpenBSD: README,v 1.2 1999/10/04 21:46:27 espie Exp $
|
||||
|
||||
--
|
||||
|
||||
X.509 notes:
|
||||
|
||||
I added the ability to sign a package with an X.509 key, and to check
|
||||
against a stack of X.509 certificates. This allows a "vendor" to
|
||||
distribute a system with one or more certificates pre-installed, and
|
||||
to add certificates in a signed package by appending them to the
|
||||
default certficiate stack.
|
||||
|
||||
The X.509 signatures are stored in the gzip header in the same manner
|
||||
as other signatures. This is known to compile against OpenSSL
|
||||
libraries on OpenBSD 2.7 and FreeBSD 5.0, your mileage may vary.
|
||||
|
||||
--
|
||||
|
||||
Wes Peters, Dec 2000
|
||||
$FreeBSD$
|
@ -1,119 +0,0 @@
|
||||
/* $OpenBSD: check.c,v 1.2 1999/10/04 21:46:27 espie Exp $ */
|
||||
/*-
|
||||
* Copyright (c) 1999 Marc Espie.
|
||||
*
|
||||
* 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.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by Marc Espie for the OpenBSD
|
||||
* Project.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE OPENBSD PROJECT 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 OPENBSD
|
||||
* PROJECT 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.
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
/* Simple code for a stand-alone package checker */
|
||||
#include <sys/types.h>
|
||||
#include <sys/wait.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include "stand.h"
|
||||
#include "pgp.h"
|
||||
#include "gzip.h"
|
||||
#include "extern.h"
|
||||
|
||||
struct checker {
|
||||
void *context;
|
||||
void (*add)(void *, const char *, size_t);
|
||||
int (*get)(void *);
|
||||
int status;
|
||||
};
|
||||
|
||||
#define MAX_CHECKERS 20
|
||||
|
||||
int
|
||||
check_signature(file, userid, envp, filename)
|
||||
/*@dependent@*/FILE *file;
|
||||
const char *userid;
|
||||
char *envp[];
|
||||
/*@observer@*/const char *filename;
|
||||
{
|
||||
struct signature *sign;
|
||||
struct mygzip_header h;
|
||||
int status;
|
||||
char buffer[1024];
|
||||
size_t length;
|
||||
struct checker checker[MAX_CHECKERS];
|
||||
struct signature *sweep;
|
||||
int i, j;
|
||||
|
||||
status = read_header_and_diagnose(file, &h, &sign, filename);
|
||||
if (status != 1)
|
||||
return PKG_UNSIGNED;
|
||||
|
||||
for (sweep = sign, i = 0;
|
||||
sweep != NULL && i < MAX_CHECKERS;
|
||||
sweep=sweep->next, i++) {
|
||||
switch(sweep->type) {
|
||||
case TAG_OLD:
|
||||
fprintf(stderr, "File %s uses old signatures, no longer supported\n",
|
||||
filename);
|
||||
checker[i].context = NULL;
|
||||
break;
|
||||
case TAG_X509:
|
||||
checker[i].context = new_x509_checker(&h, sweep, userid, envp, filename);
|
||||
checker[i].add = x509_add;
|
||||
checker[i].get = x509_sign_ok;
|
||||
break;
|
||||
case TAG_SHA1:
|
||||
checker[i].context = new_sha1_checker(&h, sweep, userid, envp, filename);
|
||||
checker[i].add = sha1_add;
|
||||
checker[i].get = sha1_sign_ok;
|
||||
break;
|
||||
case TAG_PGP:
|
||||
checker[i].context = new_pgp_checker(&h, sweep, userid, envp, filename);
|
||||
checker[i].add = pgp_add;
|
||||
checker[i].get = pgp_sign_ok;
|
||||
break;
|
||||
default:
|
||||
abort();
|
||||
}
|
||||
}
|
||||
while ((length = fread(buffer, 1, sizeof buffer, file)) > 0) {
|
||||
for (j = 0; j < i; j++) {
|
||||
if (checker[j].context) {
|
||||
(*checker[j].add)(checker[j].context, buffer, length);
|
||||
}
|
||||
}
|
||||
}
|
||||
// for (j = i-1; j >= 0; j--)
|
||||
for (j = 0; j < i; j++) {
|
||||
if (checker[j].context) {
|
||||
checker[j].status = (*checker[j].get)(checker[j].context);
|
||||
} else {
|
||||
checker[j].status = PKG_SIGERROR;
|
||||
}
|
||||
}
|
||||
free_signature(sign);
|
||||
return checker[0].status;
|
||||
}
|
||||
|
@ -1,90 +0,0 @@
|
||||
/* $OpenBSD: common.c,v 1.3 1999/10/07 16:30:32 espie Exp $ */
|
||||
/*-
|
||||
* Copyright (c) 1999 Marc Espie.
|
||||
*
|
||||
* 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.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by Marc Espie for the OpenBSD
|
||||
* Project.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE OPENBSD PROJECT 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 OPENBSD
|
||||
* PROJECT 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.
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/wait.h>
|
||||
#include <sys/stat.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <errno.h>
|
||||
#include "stand.h"
|
||||
#include "gzip.h"
|
||||
#include "pgp.h"
|
||||
#include "extern.h"
|
||||
|
||||
/* Ensure consistent diagnostics */
|
||||
int
|
||||
read_header_and_diagnose(file, h, sign, filename)
|
||||
FILE *file;
|
||||
struct mygzip_header *h;
|
||||
struct signature **sign;
|
||||
const char *filename;
|
||||
{
|
||||
switch(gzip_read_header(file, h, sign)) {
|
||||
case GZIP_SIGNED:
|
||||
if (sign == NULL) {
|
||||
fprintf(stderr, "File %s is already signed\n", filename);
|
||||
return 0;
|
||||
} else
|
||||
return 1;
|
||||
case GZIP_UNSIGNED:
|
||||
if (sign != NULL) {
|
||||
fprintf(stderr, "File %s is not a signed gzip file\n", filename);
|
||||
return 0;
|
||||
} else
|
||||
return 1;
|
||||
case GZIP_NOT_GZIP:
|
||||
fprintf(stderr, "File %s is not a gzip file\n", filename);
|
||||
return 0;
|
||||
case GZIP_NOT_PGPSIGNED:
|
||||
fprintf(stderr, "File %s contains an unknown extension\n", filename);
|
||||
return 0;
|
||||
default:
|
||||
/* this should not happen */
|
||||
abort();
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
reap(pid)
|
||||
pid_t pid;
|
||||
{
|
||||
int pstat;
|
||||
pid_t result;
|
||||
|
||||
do {
|
||||
result = waitpid(pid, &pstat, 0);
|
||||
} while (result == -1 && errno == EINTR);
|
||||
return result == -1 ? -1 : pstat;
|
||||
}
|
||||
|
@ -1,100 +0,0 @@
|
||||
/* $FreeBSD$ */
|
||||
/* $OpenBSD: extern.h,v 1.3 1999/10/07 16:30:32 espie Exp $ */
|
||||
/*-
|
||||
* Copyright (c) 1999 Marc Espie.
|
||||
*
|
||||
* 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.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by Marc Espie for the OpenBSD
|
||||
* Project.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE OPENBSD PROJECT 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 OPENBSD
|
||||
* PROJECT 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Convention: all functions that operate on a FILE * also take a filename
|
||||
* for diagnostic purposes. The file can be connected to a pipe, so
|
||||
* - don't rewind
|
||||
* - don't reopen from filename.
|
||||
*/
|
||||
|
||||
struct mygzip_header;
|
||||
struct signature;
|
||||
|
||||
/* main.c */
|
||||
extern int verbose;
|
||||
extern int quiet;
|
||||
extern char *userkey;
|
||||
|
||||
/* common.c */
|
||||
extern int read_header_and_diagnose __P((FILE *file, \
|
||||
/*@out@*/struct mygzip_header *h, /*@null@*/struct signature **sign, \
|
||||
const char *filename));
|
||||
extern int reap __P((pid_t pid));
|
||||
|
||||
/* sign.c */
|
||||
extern int sign __P((/*@observer@*/const char *filename, int type, \
|
||||
/*@null@*/const char *userid, char *envp[]));
|
||||
|
||||
/* check.c */
|
||||
extern int check_signature __P((/*@dependent@*/FILE *file, \
|
||||
/*@null@*/const char *userid, char *envp[], \
|
||||
/*@observer@*/const char *filename));
|
||||
|
||||
#define PKG_BADSIG 0
|
||||
#define PKG_GOODSIG 1
|
||||
#define PKG_UNSIGNED 2
|
||||
#define PKG_SIGNED 4
|
||||
#define PKG_SIGERROR 8
|
||||
#define PKG_SIGUNKNOWN 16
|
||||
|
||||
typedef /*@observer@*/char *pchar;
|
||||
|
||||
#define MAXID 512
|
||||
/* sha1.c */
|
||||
#define SHA1_DB_NAME "/var/db/pkg/SHA1"
|
||||
|
||||
extern void *new_sha1_checker __P((struct mygzip_header *h, \
|
||||
struct signature *sign, const char *userid, char *envp[], \
|
||||
const char *filename));
|
||||
|
||||
extern void sha1_add __P((void *arg, const char *buffer, \
|
||||
size_t length));
|
||||
|
||||
extern int sha1_sign_ok __P((void *arg));
|
||||
|
||||
extern int retrieve_sha1_marker __P((const char *filename, \
|
||||
struct signature **sign, const char *userid));
|
||||
|
||||
/* x509.c */
|
||||
#define X509_DB_NAME "/var/db/pkg/X509"
|
||||
|
||||
extern void *new_x509_checker __P((struct mygzip_header *h, \
|
||||
struct signature *sign, const char *userid, char *envp[], \
|
||||
const char *filename));
|
||||
|
||||
extern void x509_add __P((void *arg, const char *buffer, \
|
||||
size_t length));
|
||||
|
||||
extern int x509_sign_ok __P((void *arg));
|
||||
|
||||
extern int retrieve_x509_marker __P((const char *filename, \
|
||||
struct signature **sign, const char *userid));
|
@ -1,319 +0,0 @@
|
||||
/* $OpenBSD: gzip.c,v 1.3 1999/10/04 21:46:28 espie Exp $ */
|
||||
/*-
|
||||
* Copyright (c) 1999 Marc Espie.
|
||||
*
|
||||
* 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.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by Marc Espie for the OpenBSD
|
||||
* Project.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE OPENBSD PROJECT 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 OPENBSD
|
||||
* PROJECT 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.
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/wait.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <assert.h>
|
||||
#include <string.h>
|
||||
#include "stand.h"
|
||||
#include "gzip.h"
|
||||
#include "pgp.h"
|
||||
|
||||
/*
|
||||
* Signatures follow a simple format
|
||||
* (endianess was chosen to conform to gzip header format)
|
||||
*/
|
||||
|
||||
SIGNTAG known_tags[KNOWN_TAGS] = {
|
||||
{'S', 'I', 'G', 'P', 'G', 'P', 0, 0 },
|
||||
{'C', 'K', 'S', 'H', 'A', '1', 0, 0 },
|
||||
{'C', 'R', 'X', '5', '0', '9', 0, 0 },
|
||||
{'S', 'i', 'g', 'P', 'G', 'P', 0, 0 } /* old format */
|
||||
};
|
||||
|
||||
void
|
||||
sign_fill_tag(sign)
|
||||
struct signature *sign;
|
||||
{
|
||||
sign->tag[6] = sign->length % 256;
|
||||
sign->tag[7] = sign->length / 256;
|
||||
}
|
||||
|
||||
void
|
||||
sign_fill_length(sign)
|
||||
struct signature *sign;
|
||||
{
|
||||
sign->length = sign->tag[6] + 256 * sign->tag[7];
|
||||
}
|
||||
|
||||
static size_t
|
||||
stack_sign(match, t, f, sign)
|
||||
SIGNTAG match;
|
||||
int t;
|
||||
FILE *f;
|
||||
struct signature **sign;
|
||||
{
|
||||
struct signature *new_sign;
|
||||
size_t length;
|
||||
|
||||
new_sign = malloc(sizeof *new_sign);
|
||||
if (new_sign == NULL)
|
||||
return 0;
|
||||
new_sign->type = t;
|
||||
new_sign->next = NULL;
|
||||
memcpy(new_sign->tag, match, sizeof(SIGNTAG));
|
||||
sign_fill_length(new_sign);
|
||||
new_sign->data = malloc(new_sign->length);
|
||||
if (new_sign->data == NULL ||
|
||||
fread(new_sign->data, 1, new_sign->length, f) != new_sign->length) {
|
||||
free_signature(new_sign);
|
||||
return 0;
|
||||
}
|
||||
length = new_sign->length;
|
||||
if (sign != NULL) {
|
||||
if (!*sign)
|
||||
*sign = new_sign;
|
||||
else {
|
||||
while ((*sign)->next != NULL)
|
||||
sign = &((*sign)->next);
|
||||
(*sign)->next = new_sign;
|
||||
}
|
||||
} else
|
||||
free_signature(new_sign);
|
||||
return length;
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
add_sign(f, sign)
|
||||
FILE *f;
|
||||
struct signature **sign;
|
||||
{
|
||||
SIGNTAG match;
|
||||
int i;
|
||||
|
||||
if (fread(match, 1, sizeof(SIGNTAG), f) != sizeof(SIGNTAG))
|
||||
return -1;
|
||||
for (i = 0; i < KNOWN_TAGS; i++) {
|
||||
if (memcmp(match, known_tags[i], TAGCHECK) == 0) {
|
||||
unsigned int sign_length = stack_sign(match, i, f, sign);
|
||||
if (sign_length > 0)
|
||||
return sign_length + sizeof(SIGNTAG);
|
||||
else
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
gzip_magic(f)
|
||||
FILE *f;
|
||||
{
|
||||
int c, d;
|
||||
|
||||
c = fgetc(f);
|
||||
d = fgetc(f);
|
||||
if ((unsigned char)c != (unsigned char)GZIP_MAGIC0
|
||||
|| (unsigned char)d != (unsigned char)GZIP_MAGIC1)
|
||||
return 0;
|
||||
else
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int
|
||||
fill_gzip_fields(f, h)
|
||||
FILE *f;
|
||||
struct mygzip_header *h;
|
||||
{
|
||||
int method, flags;
|
||||
|
||||
method = fgetc(f);
|
||||
flags = fgetc(f);
|
||||
|
||||
if (method == EOF || flags == EOF || fread(h->stamp, 1, 6, f) != 6)
|
||||
return 0;
|
||||
h->method = (char)method;
|
||||
h->flags = (char)flags;
|
||||
if ((h->flags & CONTINUATION) != 0)
|
||||
if (fread(h->part, 1, 2, f) != 2)
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* retrieve a gzip header, including signatures */
|
||||
int
|
||||
gzip_read_header(f, h, sign)
|
||||
FILE *f;
|
||||
struct mygzip_header *h;
|
||||
struct signature **sign;
|
||||
{
|
||||
if (sign != NULL)
|
||||
*sign = NULL;
|
||||
if (!gzip_magic(f) || !fill_gzip_fields(f, h))
|
||||
return GZIP_NOT_GZIP;
|
||||
|
||||
if ((h->flags & EXTRA_FIELD) == 0) {
|
||||
h->remaining = 0;
|
||||
return GZIP_UNSIGNED;
|
||||
}
|
||||
else {
|
||||
int c;
|
||||
|
||||
c = fgetc(f);
|
||||
if (c == EOF)
|
||||
return GZIP_NOT_GZIP;
|
||||
h->remaining = (unsigned)c;
|
||||
c = fgetc(f);
|
||||
if (c == EOF)
|
||||
return GZIP_NOT_PGPSIGNED;
|
||||
h->remaining += ((unsigned) c) << 8;
|
||||
while (h->remaining >= sizeof(SIGNTAG)) {
|
||||
int sign_length = add_sign(f, sign);
|
||||
if (sign_length > 0)
|
||||
h->remaining -= sign_length;
|
||||
if (sign_length < 0)
|
||||
return GZIP_NOT_GZIP;
|
||||
if (sign_length == 0)
|
||||
return GZIP_SIGNED;
|
||||
}
|
||||
return GZIP_SIGNED;
|
||||
}
|
||||
}
|
||||
|
||||
static unsigned
|
||||
sign_length(sign)
|
||||
struct signature *sign;
|
||||
{
|
||||
unsigned total = 0;
|
||||
|
||||
while (sign != NULL) {
|
||||
total += sizeof(SIGNTAG) + sign->length;
|
||||
sign = sign->next;
|
||||
}
|
||||
return total;
|
||||
}
|
||||
|
||||
struct mydata {
|
||||
FILE *file;
|
||||
int ok;
|
||||
};
|
||||
|
||||
static void myadd(arg, buffer, size)
|
||||
void *arg;
|
||||
const char *buffer;
|
||||
size_t size;
|
||||
{
|
||||
struct mydata *d = arg;
|
||||
|
||||
if (fwrite(buffer, 1, size, d->file) == size)
|
||||
d->ok = 1;
|
||||
else
|
||||
d->ok = 0;
|
||||
}
|
||||
|
||||
/* write a gzip header, including signatures */
|
||||
int
|
||||
gzip_write_header(f, h, sign)
|
||||
FILE *f;
|
||||
const struct mygzip_header *h;
|
||||
struct signature *sign;
|
||||
{
|
||||
struct mydata d;
|
||||
d.file = f;
|
||||
if (gzip_copy_header(h, sign, myadd, &d) == 0)
|
||||
return 0;
|
||||
return d.ok;
|
||||
}
|
||||
|
||||
int
|
||||
gzip_copy_header(h, sign, add, data)
|
||||
const struct mygzip_header *h;
|
||||
struct signature *sign;
|
||||
void (*add)(void *, const char *, size_t);
|
||||
void *data;
|
||||
{
|
||||
char flags;
|
||||
size_t length;
|
||||
size_t buflength;
|
||||
size_t i;
|
||||
char *buffer;
|
||||
|
||||
length = h->remaining + sign_length(sign);
|
||||
if (length) {
|
||||
buflength = length + 2;
|
||||
flags = h->flags | EXTRA_FIELD;
|
||||
} else {
|
||||
flags = h->flags & ~EXTRA_FIELD;
|
||||
buflength = 0;
|
||||
}
|
||||
buflength += 10;
|
||||
if ((h->flags & CONTINUATION) != 0)
|
||||
buflength += 2;
|
||||
|
||||
buffer = malloc(buflength);
|
||||
if (buffer == NULL)
|
||||
return 0;
|
||||
|
||||
i = 0;
|
||||
buffer[i++] = GZIP_MAGIC0;
|
||||
buffer[i++] = GZIP_MAGIC1;
|
||||
buffer[i++] = h->method;
|
||||
buffer[i++] = flags;
|
||||
memcpy(buffer+i, h->stamp, 6);
|
||||
i += 6;
|
||||
if ((flags & CONTINUATION) != 0) {
|
||||
memcpy(buffer+i, h->part, 2);
|
||||
i += 2;
|
||||
}
|
||||
if (length) {
|
||||
buffer[i++] = (char)(length % 256);
|
||||
buffer[i++] = (char)(length / 256);
|
||||
while (sign != NULL) {
|
||||
memcpy(buffer+i, sign->tag, sizeof(SIGNTAG));
|
||||
i += sizeof(SIGNTAG);
|
||||
memcpy(buffer+i, sign->data, sign->length);
|
||||
i += sign->length;
|
||||
sign = sign->next;
|
||||
}
|
||||
}
|
||||
(*add)(data, buffer, buflength);
|
||||
free(buffer);
|
||||
return 1;
|
||||
}
|
||||
|
||||
void
|
||||
free_signature(sign)
|
||||
struct signature *sign;
|
||||
{
|
||||
struct signature *next;
|
||||
|
||||
while (sign != NULL) {
|
||||
next = sign->next;
|
||||
free(sign->data);
|
||||
free(sign);
|
||||
sign = next;
|
||||
}
|
||||
}
|
@ -1,95 +0,0 @@
|
||||
/* $FreeBSD$ */
|
||||
/* $OpenBSD: gzip.h,v 1.2 1999/10/04 21:46:28 espie Exp $ */
|
||||
/*-
|
||||
* Copyright (c) 1999 Marc Espie.
|
||||
*
|
||||
* 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.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by Marc Espie for the OpenBSD
|
||||
* Project.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE OPENBSD PROJECT 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 OPENBSD
|
||||
* PROJECT 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.
|
||||
*/
|
||||
|
||||
#define GZIP_MAGIC0 '\037'
|
||||
#define GZIP_MAGIC1 '\213'
|
||||
/* flags values */
|
||||
#define CONTINUATION 0x02
|
||||
#define EXTRA_FIELD 0x04
|
||||
|
||||
/*
|
||||
* Meaningful fields in a gzip header, see gzip proper for details.
|
||||
* This structure should not be fiddled with outside of gzip_read_header
|
||||
* and gzip_write_header
|
||||
*/
|
||||
struct mygzip_header {
|
||||
char method;
|
||||
char flags;
|
||||
char stamp[6];
|
||||
char part[2];
|
||||
/* remaining extra, after know signs have been read */
|
||||
unsigned int remaining;
|
||||
};
|
||||
|
||||
#define TAGSIZE 8
|
||||
#define TAGCHECK 6
|
||||
|
||||
typedef unsigned char SIGNTAG[8];
|
||||
|
||||
/* stack of signatures */
|
||||
struct signature {
|
||||
SIGNTAG tag;
|
||||
int type;
|
||||
int length;
|
||||
char *data;
|
||||
struct signature *next;
|
||||
};
|
||||
|
||||
/* returns from gzip_read_header */
|
||||
#define GZIP_UNSIGNED 0 /* gzip file, no signature */
|
||||
#define GZIP_SIGNED 1 /* gzip file, signature parsed ok */
|
||||
#define GZIP_NOT_GZIP 2 /* not a proper gzip file */
|
||||
#define GZIP_NOT_PGPSIGNED 3 /* gzip file, unknown extension */
|
||||
extern int gzip_read_header __P((FILE *f, /*@out@*/struct mygzip_header *h, \
|
||||
/*@null@*/struct signature **sign));
|
||||
/* gzip_write_header returns 1 for success */
|
||||
extern int gzip_write_header __P((FILE *f, const struct mygzip_header *h, \
|
||||
/*@null@*/struct signature *sign));
|
||||
/*
|
||||
* Writing header to memory. Returns size needed, or 0 if buffer too small
|
||||
* buffer must be at least 14 characters
|
||||
*/
|
||||
extern int gzip_copy_header __P((const struct mygzip_header *h, \
|
||||
/*@null@*/struct signature *sign, \
|
||||
void (*add)(void *, const char *, size_t), void *data));
|
||||
|
||||
extern void free_signature __P((/*@null@*/struct signature *sign));
|
||||
extern void sign_fill_tag __P((struct signature *sign));
|
||||
#define KNOWN_TAGS 4
|
||||
#define TAG_PGP 0
|
||||
#define TAG_SHA1 1
|
||||
#define TAG_X509 2
|
||||
#define TAG_OLD 3
|
||||
#define TAG_ANY -1
|
||||
#define pgptag (known_tags[TAG_PGP])
|
||||
#define sha1tag (known_tags[TAG_SHA1])
|
||||
#define x509tag (known_tags[TAG_X509])
|
||||
extern SIGNTAG known_tags[KNOWN_TAGS];
|
@ -1,185 +0,0 @@
|
||||
/* $OpenBSD: main.c,v 1.2 1999/10/04 21:46:28 espie Exp $ */
|
||||
/*-
|
||||
* Copyright (c) 1999 Marc Espie.
|
||||
*
|
||||
* 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.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by Marc Espie for the OpenBSD
|
||||
* Project.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE OPENBSD PROJECT 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 OPENBSD
|
||||
* PROJECT 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.
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/wait.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
#include "stand.h"
|
||||
#include "gzip.h"
|
||||
#include "pgp.h"
|
||||
#include "extern.h"
|
||||
|
||||
#ifdef __OpenBSD__
|
||||
extern char *__progname;
|
||||
#define argv0 __progname
|
||||
#else
|
||||
static char *argv0;
|
||||
#endif
|
||||
|
||||
#define NM_SIGN "pkg_sign"
|
||||
|
||||
int verbose = 0;
|
||||
int quiet = 0;
|
||||
char *userkey = NULL;
|
||||
|
||||
static void
|
||||
usage()
|
||||
{
|
||||
fprintf(stderr, "usage: %s [-sc] [-t type] [-u userid] [-k keyfile] pkg1 ...\n", argv0);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
#define SIGN 0
|
||||
#define CHECK 1
|
||||
|
||||
/* wrapper for the check_signature function (open file if needed) */
|
||||
static int
|
||||
check(filename, type, userid, envp)
|
||||
/*@observer@*/const char *filename;
|
||||
int type;
|
||||
/*@null@*/const char *userid;
|
||||
char *envp[];
|
||||
{
|
||||
int result;
|
||||
FILE *file;
|
||||
|
||||
if (strcmp(filename, "-") == 0)
|
||||
return check_signature(stdin, userid, envp, "stdin");
|
||||
file = fopen(filename, "r");
|
||||
if (file == NULL) {
|
||||
fprintf(stderr, "Can't open %s\n", filename);
|
||||
return 0;
|
||||
}
|
||||
result = check_signature(file, userid, envp, filename);
|
||||
if (fclose(file) == 0) {
|
||||
if (result == PKG_BADSIG || result == PKG_SIGERROR)
|
||||
return 0;
|
||||
else
|
||||
return 1;
|
||||
} else
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
main(argc, argv, envp)
|
||||
int argc;
|
||||
char *argv[];
|
||||
char *envp[];
|
||||
{
|
||||
int success = 1;
|
||||
int ch;
|
||||
char *userid = NULL;
|
||||
int mode;
|
||||
int i;
|
||||
int type = TAG_ANY;
|
||||
|
||||
#ifndef BSD4_4
|
||||
set_program_name(argv[0]);
|
||||
#endif
|
||||
#ifdef CHECKER_ONLY
|
||||
mode = CHECK;
|
||||
#else
|
||||
#ifndef __OpenBSD__
|
||||
if ((argv0 = strrchr(argv[0], '/')) != NULL)
|
||||
argv0++;
|
||||
else
|
||||
argv0 = argv[0];
|
||||
#endif
|
||||
if (strcmp(argv0, NM_SIGN) == 0)
|
||||
mode = SIGN;
|
||||
else
|
||||
mode = CHECK;
|
||||
#endif
|
||||
|
||||
while ((ch = getopt(argc, argv, "t:u:k:qscv")) != -1) {
|
||||
switch(ch) {
|
||||
case 't':
|
||||
if (strcmp(optarg, "pgp") == 0)
|
||||
type = TAG_PGP;
|
||||
else if (strcmp(optarg, "sha1") == 0)
|
||||
type = TAG_SHA1;
|
||||
else if (strcmp(optarg, "x509") == 0)
|
||||
type = TAG_X509;
|
||||
else
|
||||
usage();
|
||||
break;
|
||||
case 'u':
|
||||
userid = strdup(optarg);
|
||||
break;
|
||||
|
||||
case 'k':
|
||||
userkey = optarg;
|
||||
break;
|
||||
|
||||
case 'q':
|
||||
quiet = 1;
|
||||
break;
|
||||
|
||||
#ifndef CHECKER_ONLY
|
||||
case 's':
|
||||
mode = SIGN;
|
||||
break;
|
||||
#endif
|
||||
case 'c':
|
||||
mode = CHECK;
|
||||
break;
|
||||
|
||||
case 'v':
|
||||
verbose = 1;
|
||||
break;
|
||||
default:
|
||||
usage();
|
||||
}
|
||||
}
|
||||
argc -= optind;
|
||||
argv += optind;
|
||||
if (argc == 0) {
|
||||
if (mode == CHECK)
|
||||
success &= check("-", 0, userid, envp);
|
||||
else
|
||||
usage();
|
||||
}
|
||||
|
||||
#ifndef CHECKER_ONLY
|
||||
if (mode == SIGN && type == TAG_ANY)
|
||||
type = TAG_PGP;
|
||||
if (mode == SIGN && type == TAG_PGP)
|
||||
handle_pgp_passphrase();
|
||||
#endif
|
||||
for (i = 0; i < argc; i++)
|
||||
success &= (mode == SIGN ? sign : check)(argv[i], type, userid, envp);
|
||||
exit(success == 1 ? EXIT_SUCCESS : EXIT_FAILURE);
|
||||
}
|
@ -1,25 +0,0 @@
|
||||
/* $FreeBSD$ */
|
||||
/* $OpenBSD: pgp.h,v 1.2 1999/10/04 21:46:28 espie Exp $ */
|
||||
/* Estimate size of pgp signature */
|
||||
#define MAXPGPSIGNSIZE 1024
|
||||
|
||||
#ifndef PGP
|
||||
#define PGP "/usr/local/bin/pgp"
|
||||
#endif
|
||||
|
||||
struct mygzip_header;
|
||||
struct signature;
|
||||
|
||||
extern void *new_pgp_checker __P((struct mygzip_header *h, \
|
||||
struct signature *sign, const char *userid, char *envp[], \
|
||||
const char *filename));
|
||||
|
||||
extern void pgp_add __P((void *arg, const char *buffer, \
|
||||
size_t length));
|
||||
|
||||
extern int pgp_sign_ok __P((void *arg));
|
||||
|
||||
extern void handle_pgp_passphrase __P((void));
|
||||
|
||||
extern int retrieve_pgp_signature __P((const char *filename, \
|
||||
struct signature **sign, const char *userid, char *envp[]));
|
@ -1,196 +0,0 @@
|
||||
/* $OpenBSD: pgp_check.c,v 1.2 1999/10/07 16:30:32 espie Exp $ */
|
||||
/*-
|
||||
* Copyright (c) 1999 Marc Espie.
|
||||
*
|
||||
* 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.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by Marc Espie for the OpenBSD
|
||||
* Project.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE OPENBSD PROJECT 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 OPENBSD
|
||||
* PROJECT 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.
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#include <stdio.h>
|
||||
#include <errno.h>
|
||||
#include <assert.h>
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
#include <paths.h>
|
||||
#include <stdlib.h>
|
||||
#include <sys/stat.h>
|
||||
#include "stand.h"
|
||||
#include "pgp.h"
|
||||
#include "gzip.h"
|
||||
#include "extern.h"
|
||||
|
||||
#ifndef _PATH_DEVNULL
|
||||
#define _PATH_DEVNULL "/dev/null"
|
||||
#endif
|
||||
|
||||
/* transform current process into pgp signature checker -u userid <fd */
|
||||
static void
|
||||
pgpcheck(fd, userid, envp)
|
||||
int fd;
|
||||
const char *userid;
|
||||
char *envp[];
|
||||
{
|
||||
int fdnull;
|
||||
pchar argv[6];
|
||||
int argc = 0;
|
||||
|
||||
argv[argc++] = PGP;
|
||||
argv[argc++] = "+batchmode";
|
||||
argv[argc++] = "-f";
|
||||
|
||||
if (userid) {
|
||||
argv[argc++] = "-u";
|
||||
argv[argc++] = (char *)userid;
|
||||
}
|
||||
argv[argc++] = NULL;
|
||||
|
||||
assert(argc <= sizeof argv / sizeof(pchar));
|
||||
|
||||
fdnull = open(_PATH_DEVNULL, O_RDWR);
|
||||
if (fdnull == -1 ||
|
||||
dup2(fd, fileno(stdin)) == -1 ||
|
||||
dup2(fdnull, fileno(stdout)) == -1 ||
|
||||
close(fdnull) == -1 || close(fd) == -1 ||
|
||||
execve(PGP, argv, envp) == -1)
|
||||
perror("launching pgp");
|
||||
exit(errno);
|
||||
}
|
||||
|
||||
struct pgp_checker {
|
||||
pid_t id;
|
||||
int fdout;
|
||||
int status;
|
||||
#ifdef DEBUG_DUMP
|
||||
FILE *out;
|
||||
#endif
|
||||
};
|
||||
|
||||
void *
|
||||
new_pgp_checker(h, sign, userid, envp, filename)
|
||||
struct mygzip_header *h;
|
||||
struct signature *sign;
|
||||
const char *userid;
|
||||
char *envp[];
|
||||
/*@observer@*/const char *filename;
|
||||
{
|
||||
struct pgp_checker *n;
|
||||
int topgpcheck[2];
|
||||
|
||||
assert(sign->type == TAG_PGP);
|
||||
n = malloc(sizeof *n);
|
||||
|
||||
{
|
||||
struct stat sbuf;
|
||||
|
||||
if (stat(PGP, &sbuf) == -1) {
|
||||
warnx("%s does not exist", PGP);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
if (n == NULL) {
|
||||
warnx("Can't allocate pgp_checker");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (pipe(topgpcheck) == -1) {
|
||||
warn("Pgp checker pipe");
|
||||
free(n);
|
||||
return NULL;
|
||||
}
|
||||
switch(n->id = fork()) {
|
||||
case -1:
|
||||
warn("Pgp checker process");
|
||||
free(n);
|
||||
return NULL;
|
||||
case 0:
|
||||
if (close(topgpcheck[1]) == -1)
|
||||
exit(errno);
|
||||
pgpcheck(topgpcheck[0], userid, envp);
|
||||
/*@notreached@*/
|
||||
break;
|
||||
default:
|
||||
(void)close(topgpcheck[0]);
|
||||
break;
|
||||
}
|
||||
n->fdout = topgpcheck[1];
|
||||
/* so that subsequent fork() won't duplicate it inadvertently */
|
||||
(void)fcntl(n->fdout, F_SETFD, FD_CLOEXEC);
|
||||
#ifdef DEBUG_DUMP
|
||||
n->out = fopen("compare", "w");
|
||||
#endif
|
||||
n->status = PKG_GOODSIG;
|
||||
|
||||
pgp_add(n, sign->data, sign->length);
|
||||
if (gzip_copy_header(h, sign->next, pgp_add, n) == 0) {
|
||||
warnx("Unexpected header in %s", filename);
|
||||
n->status = PKG_SIGERROR;
|
||||
}
|
||||
return n;
|
||||
}
|
||||
|
||||
void
|
||||
pgp_add(arg, buffer, length)
|
||||
void *arg;
|
||||
const char *buffer;
|
||||
size_t length;
|
||||
{
|
||||
struct pgp_checker *n = arg;
|
||||
|
||||
if (n->status == PKG_GOODSIG) {
|
||||
#ifdef DEBUG_DUMP
|
||||
fwrite(buffer, 1, length, n->out);
|
||||
#endif
|
||||
while (length > 0) {
|
||||
ssize_t l = write(n->fdout, buffer, length);
|
||||
if (l == -1) {
|
||||
n->status = PKG_SIGERROR;
|
||||
break;
|
||||
}
|
||||
length -= l;
|
||||
buffer += l;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
pgp_sign_ok(arg)
|
||||
void *arg;
|
||||
{
|
||||
struct pgp_checker *n = arg;
|
||||
int status = n->status;
|
||||
|
||||
#ifdef DEBUG_DUMP
|
||||
fclose(n->out);
|
||||
#endif
|
||||
if (close(n->fdout) != 0)
|
||||
status = PKG_SIGERROR;
|
||||
if (reap(n->id) != 0)
|
||||
status = PKG_BADSIG;
|
||||
free(n);
|
||||
return status;
|
||||
}
|
@ -1,281 +0,0 @@
|
||||
/* $OpenBSD: pgp_sign.c,v 1.1 1999/10/04 21:46:29 espie Exp $ */
|
||||
/*-
|
||||
* Copyright (c) 1999 Marc Espie.
|
||||
*
|
||||
* 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.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by Marc Espie for the OpenBSD
|
||||
* Project.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE OPENBSD PROJECT 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 OPENBSD
|
||||
* PROJECT 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.
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <stdio.h>
|
||||
#include <errno.h>
|
||||
#include <signal.h>
|
||||
#include <pwd.h>
|
||||
#include <assert.h>
|
||||
#include "stand.h"
|
||||
#include "pgp.h"
|
||||
#include "gzip.h"
|
||||
#include "extern.h"
|
||||
|
||||
static void
|
||||
pgpsign(fdin, fdout, userid, envp)
|
||||
int fdin, fdout;
|
||||
const char *userid;
|
||||
char *envp[];
|
||||
{
|
||||
pchar argv[10];
|
||||
int argc = 0;
|
||||
|
||||
argv[argc++] = PGP;
|
||||
argv[argc++] = "+batchmode";
|
||||
argv[argc++] = "+compress=off";
|
||||
argv[argc++] = "-f";
|
||||
argv[argc++] = "-s";
|
||||
argv[argc++] = "-zAthlon";
|
||||
|
||||
if (userid) {
|
||||
argv[argc++] = "-u";
|
||||
argv[argc++] = (char *)userid;
|
||||
}
|
||||
argv[argc++] = NULL;
|
||||
assert(argc <= sizeof argv / sizeof(pchar));
|
||||
|
||||
if (dup2(fdin, fileno(stdin)) == -1 ||
|
||||
dup2(fdout, fileno(stdout)) == -1 ||
|
||||
execve(PGP, argv, envp) == -1)
|
||||
exit(errno);
|
||||
}
|
||||
|
||||
static struct signature *
|
||||
new_pgpsignature(old)
|
||||
struct signature *old;
|
||||
{
|
||||
struct signature *n;
|
||||
|
||||
n = malloc(sizeof(*n));
|
||||
if (n != NULL) {
|
||||
n->data = malloc(MAXPGPSIGNSIZE);
|
||||
if (n->data == NULL) {
|
||||
free(n);
|
||||
return NULL;
|
||||
}
|
||||
n->length = 0;
|
||||
n->next = old;
|
||||
n->type = TAG_PGP;
|
||||
memcpy(n->tag, pgptag, sizeof pgptag);
|
||||
}
|
||||
return n;
|
||||
}
|
||||
|
||||
int
|
||||
retrieve_pgp_signature(filename, sign, userid, envp)
|
||||
const char *filename;
|
||||
struct signature **sign;
|
||||
const char *userid;
|
||||
char *envp[];
|
||||
{
|
||||
int topgp[2], frompgp[2];
|
||||
pid_t pgpid;
|
||||
struct mygzip_header h;
|
||||
int success;
|
||||
|
||||
FILE *orig, *dest, *signin;
|
||||
struct signature *old;
|
||||
|
||||
orig = fopen(filename, "r");
|
||||
if (orig == NULL)
|
||||
return 0;
|
||||
if (gzip_read_header(orig, &h, &old) == GZIP_NOT_GZIP) {
|
||||
warnx("File %s is not a gzip file\n", filename);
|
||||
fclose(orig);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (pipe(topgp) == -1) {
|
||||
fclose(orig);
|
||||
return 0;
|
||||
}
|
||||
if (pipe(frompgp) == -1) {
|
||||
fclose(orig);
|
||||
(void)close(topgp[0]);
|
||||
(void)close(topgp[1]);
|
||||
return 0;
|
||||
}
|
||||
switch(pgpid = fork()) {
|
||||
case 0:
|
||||
(void)close(topgp[1]);
|
||||
(void)close(frompgp[0]);
|
||||
pgpsign(topgp[0], frompgp[1], userid, envp);
|
||||
/*NOT REACHED */
|
||||
case -1:
|
||||
(void)close(topgp[0]);
|
||||
(void)close(topgp[1]);
|
||||
(void)close(frompgp[0]);
|
||||
(void)close(frompgp[1]);
|
||||
fclose(orig);
|
||||
return 0;
|
||||
default:
|
||||
(void)close(topgp[0]);
|
||||
(void)close(frompgp[1]);
|
||||
}
|
||||
|
||||
dest = fdopen(topgp[1], "w");
|
||||
if (dest == NULL) {
|
||||
(void)close(topgp[1]);
|
||||
(void)close(frompgp[0]);
|
||||
(void)reap(pgpid);
|
||||
return 0;
|
||||
}
|
||||
|
||||
success = 1;
|
||||
if (gzip_write_header(dest, &h, old) == 0)
|
||||
success = 0;
|
||||
else {
|
||||
int c;
|
||||
|
||||
while ((c = fgetc(orig)) != EOF && fputc(c, dest) != EOF)
|
||||
;
|
||||
if (ferror(dest))
|
||||
success = 0;
|
||||
}
|
||||
if (fclose(dest) != 0)
|
||||
success = 0;
|
||||
|
||||
if (fclose(orig) != 0)
|
||||
success = 0;
|
||||
|
||||
signin = fdopen(frompgp[0], "r");
|
||||
if (signin == NULL) {
|
||||
(void)close(frompgp[0]);
|
||||
} else {
|
||||
enum { NONE, FIRST, DONE, COPY} magic = NONE;
|
||||
int c;
|
||||
#ifdef DEBUG_DUMP
|
||||
FILE *out = fopen("dump", "w");
|
||||
#endif
|
||||
|
||||
if ((*sign = new_pgpsignature(old)) == NULL)
|
||||
success = 0;
|
||||
else {
|
||||
while ((c = fgetc(signin)) != EOF && magic != DONE &&
|
||||
(*sign)->length < MAXPGPSIGNSIZE) {
|
||||
switch(magic) {
|
||||
case NONE:
|
||||
(*sign)->data[(*sign)->length++] = c;
|
||||
if ((unsigned char)c == (unsigned char)GZIP_MAGIC0)
|
||||
magic = FIRST;
|
||||
break;
|
||||
case FIRST:
|
||||
(*sign)->data[(*sign)->length++] = c;
|
||||
if ((unsigned char)c == (unsigned char)GZIP_MAGIC1)
|
||||
#ifdef DEBUG_DUMP
|
||||
magic = COPY;
|
||||
#else
|
||||
magic = DONE;
|
||||
#endif
|
||||
else if ((unsigned char)c != (unsigned char)GZIP_MAGIC0)
|
||||
magic = NONE;
|
||||
break;
|
||||
case DONE:
|
||||
case COPY:
|
||||
break;
|
||||
}
|
||||
#ifdef DEBUG_DUMP
|
||||
fputc(c, out);
|
||||
#endif
|
||||
}
|
||||
if ((*sign)->length == MAXPGPSIGNSIZE)
|
||||
success = 0;
|
||||
(*sign)->length -= 2;
|
||||
sign_fill_tag(*sign);
|
||||
}
|
||||
fclose(signin);
|
||||
#ifdef DEBUG_DUMP
|
||||
fclose(out);
|
||||
#endif
|
||||
reap(pgpid);
|
||||
}
|
||||
return success;
|
||||
}
|
||||
|
||||
void
|
||||
handle_pgp_passphrase()
|
||||
{
|
||||
pid_t pid;
|
||||
int fd[2];
|
||||
char *p;
|
||||
|
||||
printf("Short-circuiting %s\n", __func__);
|
||||
return;
|
||||
|
||||
/* Retrieve the pgp passphrase */
|
||||
p = getpass("Enter passphrase:");
|
||||
|
||||
/*
|
||||
* Somewhat kludgy code to get the passphrase to pgp, see
|
||||
* pgp documentation for the gore
|
||||
*/
|
||||
if (pipe(fd) != 0) {
|
||||
perror("pkg_sign");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
switch(pid = fork()) {
|
||||
case -1:
|
||||
perror("pkg_sign");
|
||||
exit(EXIT_FAILURE);
|
||||
case 0:
|
||||
{
|
||||
(void)close(fd[0]);
|
||||
/*
|
||||
* The child fills the pipe with copies of the passphrase.
|
||||
* Expect violent death when father exits.
|
||||
*/
|
||||
printf("Child process %d stuffing passphrase in pipe:\n", getpid());
|
||||
for(;;) {
|
||||
char c = '\n';
|
||||
(void)write(fd[1], p, strlen(p));
|
||||
(void)write(fd[1], &c, 1);
|
||||
putchar('.'); fflush(stdout);
|
||||
}
|
||||
}
|
||||
default:
|
||||
{
|
||||
char buf[10];
|
||||
|
||||
sleep(1);
|
||||
(void)close(fd[1]);
|
||||
(void)sprintf(buf, "%d", fd[0]);
|
||||
(void)setenv("PGPPASSFD", buf, 1);
|
||||
printf("Parent process PGPPASSFD=%d.\n", fd[0]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,211 +0,0 @@
|
||||
.\" $FreeBSD$
|
||||
.\" $OpenBSD: pkg_sign.1,v 1.6 2000/04/15 02:15:20 aaron Exp $
|
||||
.\"
|
||||
.\" Copyright (c) 1999 Marc Espie.
|
||||
.\"
|
||||
.\" 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.
|
||||
.\" 3. All advertising materials mentioning features or use of this software
|
||||
.\" must display the following acknowledgement:
|
||||
.\" This product includes software developed by Marc Espie for the OpenBSD
|
||||
.\" Project.
|
||||
.\"
|
||||
.\" THIS SOFTWARE IS PROVIDED BY THE OPENBSD PROJECT 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 OPENBSD
|
||||
.\" PROJECT 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.
|
||||
.Dd September 24, 1999
|
||||
.Dt PKG_SIGN 1
|
||||
.Os
|
||||
.Sh NAME
|
||||
.Nm pkg_sign ,
|
||||
.Nm pkg_check
|
||||
.Nd handle package signatures
|
||||
.Sh SYNOPSIS
|
||||
.Nm
|
||||
.Op Fl sc
|
||||
.Op Fl t Ar type
|
||||
.Op Fl u Ar id
|
||||
.Op Fl k Ar key
|
||||
.Op Ar
|
||||
.Nm pkg_check
|
||||
.Op Fl sc
|
||||
.Op Fl u Ar id
|
||||
.Op Fl k Ar cert
|
||||
.Op Ar
|
||||
.Sh DESCRIPTION
|
||||
The
|
||||
.Nm
|
||||
utility embeds a cryptographic signature within a gzip file
|
||||
.Ar file .
|
||||
.Ar type
|
||||
can be
|
||||
.Cm pgp
|
||||
(default),
|
||||
.Cm sha1 ,
|
||||
or
|
||||
.Cm x509 .
|
||||
If
|
||||
.Ar type
|
||||
is
|
||||
.Cm pgp ,
|
||||
it will always prompt you for a passphrase to unlock your private
|
||||
pgp key, even if you do not use a passphrase (which is a bad idea, anyway).
|
||||
If
|
||||
.Ar type
|
||||
is
|
||||
.Cm sha1 ,
|
||||
you must supply an
|
||||
.Ar id ,
|
||||
which will be recorded as the name of the package, and printed as the
|
||||
SHA1 checksum.
|
||||
.Pp
|
||||
The
|
||||
.Nm pkg_check
|
||||
utility checks that cryptographic signature.
|
||||
It currently disregards
|
||||
.Ar type
|
||||
and checks only the topmost signature.
|
||||
For
|
||||
.Cm sha1 ,
|
||||
it checksums the file
|
||||
and verifies that the result matches the list of checksums recorded in
|
||||
.Pa /var/db/pkg/SHA1 .
|
||||
.Pp
|
||||
Options
|
||||
.Fl s
|
||||
and
|
||||
.Fl c
|
||||
can be used to force package signing or signature checking mode.
|
||||
.Pp
|
||||
For
|
||||
.Cm pgp ,
|
||||
the
|
||||
.Ar id
|
||||
to use to sign the package or verify the signature can be forced with
|
||||
.Fl u .
|
||||
.Pp
|
||||
For
|
||||
.Cm x509 ,
|
||||
the signing key or verification certificate may be
|
||||
specified with the
|
||||
.Fl k
|
||||
option.
|
||||
If not specified, packages are signed or verified with the
|
||||
default keys and certificates documented below.
|
||||
.Pp
|
||||
If
|
||||
.Ar file
|
||||
is a single dash
|
||||
.Pq Sq Fl
|
||||
or absent,
|
||||
.Nm
|
||||
reads from the standard input.
|
||||
.Pp
|
||||
Package signing uses a feature of the gzip format, namely that one can
|
||||
set a flag
|
||||
.Dv EXTRA_FIELD
|
||||
in the gzip header and store extra data between the gzip header and the
|
||||
compressed file proper.
|
||||
The
|
||||
.Ox
|
||||
signing scheme uses eight bytes markers such
|
||||
.Sq Li SIGPGP
|
||||
+ length or
|
||||
.Sq CKSHA1
|
||||
+ length for its signatures (those markers are conveniently
|
||||
eight bytes long).
|
||||
.Sh FILES
|
||||
.Bl -tag -width "/usr/local/bin/pgp" -compact
|
||||
.It Pa file.sign
|
||||
Temporary file built by
|
||||
.Nm
|
||||
from
|
||||
.Ar file .
|
||||
.It Pa /usr/local/bin/pgp
|
||||
Default path to
|
||||
.Xr pgp 1 .
|
||||
.It Pa /var/db/pkgs/SHA1
|
||||
Recorded checksums.
|
||||
.It Pa /etc/ssl/pkg.key
|
||||
Default package signing key.
|
||||
.It Pa /etc/ssl/pkg.crt
|
||||
Default package verification certificate(s).
|
||||
.El
|
||||
.Sh EXIT STATUS
|
||||
The
|
||||
.Nm
|
||||
and
|
||||
.Nm pkg_check
|
||||
utilities return with an exit code >0 if anything went wrong for any
|
||||
.Ar file .
|
||||
For
|
||||
.Nm pkg_check ,
|
||||
this usually indicates that the package is not signed, or that the
|
||||
signature is forged.
|
||||
.Sh DIAGNOSTICS
|
||||
.Bl -diag
|
||||
.It "File %s is already signed"
|
||||
There is a signature embedded within the gzip file already.
|
||||
The
|
||||
.Nm
|
||||
utility currently does not handle multiple signatures.
|
||||
.It "File %s is not a signed gzip file"
|
||||
This is an unsigned package.
|
||||
.It "File %s is not a gzip file"
|
||||
The program could not find a proper gzip header.
|
||||
.It "File %s contains an unknown extension"
|
||||
The extended area of the gzip file has been used for an unknown purpose.
|
||||
.It "File %s uses old signatures, no longer supported"
|
||||
The gzip file uses a very early version of package signing that was
|
||||
substantially slower.
|
||||
.El
|
||||
.Sh SEE ALSO
|
||||
.Xr gzip 1 ,
|
||||
.Xr pgp 1 ,
|
||||
.Xr pkg_add 1 ,
|
||||
.Xr sha1 1
|
||||
.Sh AUTHORS
|
||||
.An -nosplit
|
||||
A
|
||||
.Nm
|
||||
utility was created by
|
||||
.An Marc Espie
|
||||
for the
|
||||
.Ox
|
||||
Project.
|
||||
X.509 signatures and
|
||||
.Fx
|
||||
support added by
|
||||
.An Wes Peters Aq wes@softweyr.com .
|
||||
.Sh BUGS
|
||||
The
|
||||
.Xr pgp 1
|
||||
utility is an ill-designed program, which is hard to interface with.
|
||||
For instance, the `separate signing scheme' it pretends to offer is
|
||||
useless, as it cannot be used with pipes, so that
|
||||
.Nm pgp_sign
|
||||
needs to kludge it by knowing the length of a pgp signature, and invoking
|
||||
pgp in `seamless' signature mode, without compression of the main file,
|
||||
and just retrieving the signature.
|
||||
.Pp
|
||||
The checking scheme is little less convoluted, namely we rebuild the file
|
||||
that pgp expects on the fly.
|
||||
.Pp
|
||||
Paths to
|
||||
.Nm pgp
|
||||
and
|
||||
the checksum file are hard-coded to avoid tampering and hinder flexibility.
|
@ -1,230 +0,0 @@
|
||||
/* $OpenBSD: sha1.c,v 1.1 1999/10/04 21:46:29 espie Exp $ */
|
||||
/*-
|
||||
* Copyright (c) 1999 Marc Espie.
|
||||
*
|
||||
* 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.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by Marc Espie for the OpenBSD
|
||||
* Project.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE OPENBSD PROJECT 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 OPENBSD
|
||||
* PROJECT 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.
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/wait.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <assert.h>
|
||||
#include <sha.h>
|
||||
#include "stand.h"
|
||||
#include "gzip.h"
|
||||
#include "extern.h"
|
||||
|
||||
/* private context for sha1 signature checker */
|
||||
struct sha1_checker {
|
||||
SHA_CTX context;
|
||||
const char *id;
|
||||
const char *filename;
|
||||
};
|
||||
|
||||
|
||||
#define SHA1_TEMPLATE "SHA1 (%s) = "
|
||||
#define BUFSIZE (MAXID+sizeof(SHA1_TEMPLATE)+2*SHA_DIGEST_LENGTH+1)
|
||||
|
||||
/*
|
||||
* Finalize SHA1 checksum for our sha1_context into result
|
||||
* (size at least BUFSIZE). Returns the length of the checksum
|
||||
* marker, e.g., SHA1 (id) = xxxxxxxxx
|
||||
* ^here
|
||||
* Return 0 for errors.
|
||||
*/
|
||||
size_t
|
||||
sha1_build_checksum(result, n)
|
||||
char *result;
|
||||
struct sha1_checker *n;
|
||||
{
|
||||
size_t length;
|
||||
|
||||
snprintf(result, BUFSIZE-2*SHA_DIGEST_LENGTH-1, SHA1_TEMPLATE, n->id);
|
||||
length = strlen(result);
|
||||
SHA1_End(&n->context, result + length);
|
||||
strcat(result, "\n");
|
||||
free(n);
|
||||
return length;
|
||||
}
|
||||
|
||||
void *
|
||||
new_sha1_checker(h, sign, userid, envp, filename)
|
||||
struct mygzip_header *h;
|
||||
struct signature *sign;
|
||||
const char *userid;
|
||||
char *envp[];
|
||||
/*@observer@*/const char *filename;
|
||||
{
|
||||
struct sha1_checker *n;
|
||||
|
||||
assert(sign->type == TAG_SHA1);
|
||||
/* make sure data conforms to what we can handle */
|
||||
if (sign->length > MAXID || sign->data[sign->length-1] != '\0') {
|
||||
warnx("Corrupted SHA1 header in %s", filename);
|
||||
return 0;
|
||||
}
|
||||
|
||||
n = malloc(sizeof *n);
|
||||
if (n == NULL) {
|
||||
warnx("Can't allocate sha1_checker");
|
||||
return NULL;
|
||||
}
|
||||
SHA1_Init(&n->context);
|
||||
n->id = sign->data;
|
||||
n->filename = filename;
|
||||
|
||||
/* copy header, as this is a checksum, we don't strip our own marker */
|
||||
if (gzip_copy_header(h, sign, sha1_add, n) == 0) {
|
||||
warnx("Unexpected header in %s", filename);
|
||||
free(n);
|
||||
return 0;
|
||||
}
|
||||
return n;
|
||||
}
|
||||
|
||||
void
|
||||
sha1_add(arg, buffer, length)
|
||||
void *arg;
|
||||
const char *buffer;
|
||||
size_t length;
|
||||
{
|
||||
struct sha1_checker *n = arg;
|
||||
SHA1_Update(&n->context, buffer, length);
|
||||
}
|
||||
|
||||
int
|
||||
sha1_sign_ok(arg)
|
||||
void *arg;
|
||||
{
|
||||
struct sha1_checker *n = arg;
|
||||
char buffer[BUFSIZE];
|
||||
char scan[BUFSIZE];
|
||||
size_t length;
|
||||
FILE *f;
|
||||
int tag_found;
|
||||
|
||||
length = sha1_build_checksum(buffer, n);
|
||||
f= fopen(SHA1_DB_NAME, "r");
|
||||
tag_found = 0;
|
||||
|
||||
if (f == NULL) {
|
||||
warn("Can't access checksum file %s", SHA1_DB_NAME);
|
||||
return PKG_BADSIG;
|
||||
}
|
||||
while (fgets(scan, sizeof(scan), f) != NULL) {
|
||||
if (strcmp(scan, buffer) == 0) {
|
||||
fprintf(stderr, "Checksum ok\n");
|
||||
return PKG_GOODSIG;
|
||||
}
|
||||
if (strncmp(scan, buffer, length) == 0)
|
||||
tag_found = 1;
|
||||
}
|
||||
|
||||
if (tag_found) {
|
||||
warnx("Checksum incorrect for %s (%s)", n->filename, n->id);
|
||||
return PKG_BADSIG;
|
||||
} else {
|
||||
warnx("No checksum found for %s (%s)", n->filename, n->id);
|
||||
return PKG_SIGUNKNOWN;
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
retrieve_sha1_marker(filename, sign, userid)
|
||||
const char *filename;
|
||||
struct signature **sign;
|
||||
const char *userid;
|
||||
{
|
||||
struct signature *n;
|
||||
struct mygzip_header h;
|
||||
FILE *f;
|
||||
char buffer[1024];
|
||||
char result[BUFSIZE];
|
||||
ssize_t length = -1;
|
||||
struct sha1_checker *checker;
|
||||
|
||||
*sign = NULL;
|
||||
if (userid == NULL)
|
||||
return 0;
|
||||
|
||||
/*
|
||||
* Create a blank signature and fill it with the userid.
|
||||
*/
|
||||
n = malloc(sizeof *n);
|
||||
if (n == NULL)
|
||||
return 0;
|
||||
n->length = strlen(userid)+1;
|
||||
n->data = malloc(n->length);
|
||||
if (n->data == NULL) {
|
||||
free(n);
|
||||
return 0;
|
||||
}
|
||||
memcpy(n->data, userid, n->length);
|
||||
n->type = TAG_SHA1;
|
||||
memcpy(n->tag, sha1tag, sizeof sha1tag);
|
||||
sign_fill_tag(n);
|
||||
|
||||
/*
|
||||
* Read the gzip header and add our "userid" signature to it.
|
||||
*/
|
||||
f = fopen(filename, "r");
|
||||
if (f == NULL) {
|
||||
free(n);
|
||||
return 0;
|
||||
}
|
||||
if (gzip_read_header(f, &h, sign) == GZIP_NOT_GZIP) {
|
||||
warnx("File %s is not a gzip file\n", filename);
|
||||
fclose(f);
|
||||
free(n);
|
||||
return 0;
|
||||
}
|
||||
n->next = *sign;
|
||||
*sign = n;
|
||||
|
||||
/*
|
||||
* Calculate the SHA1 of the remaining data and write it to stderr.
|
||||
*/
|
||||
checker = new_sha1_checker(&h, *sign, NULL, NULL, filename);
|
||||
if (checker)
|
||||
while ((length = fread(buffer, 1, sizeof buffer, f)) > 0)
|
||||
sha1_add(checker, buffer, length);
|
||||
if (fclose(f) != 0 || length == -1) {
|
||||
warn("Problem checksumming %s", filename);
|
||||
*sign = n->next;
|
||||
free(n);
|
||||
return 0;
|
||||
}
|
||||
|
||||
(void)sha1_build_checksum(result, checker);
|
||||
fputs(result, stderr);
|
||||
return 1;
|
||||
}
|
||||
|
@ -1,150 +0,0 @@
|
||||
/* $OpenBSD: sign.c,v 1.3 1999/10/04 21:46:29 espie Exp $ */
|
||||
/*-
|
||||
* Copyright (c) 1999 Marc Espie.
|
||||
*
|
||||
* 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.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by Marc Espie for the OpenBSD
|
||||
* Project.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE OPENBSD PROJECT 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 OPENBSD
|
||||
* PROJECT 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.
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <stdio.h>
|
||||
#include <errno.h>
|
||||
#include <signal.h>
|
||||
#include <pwd.h>
|
||||
#include <assert.h>
|
||||
#include "stand.h"
|
||||
#include "pgp.h"
|
||||
#include "gzip.h"
|
||||
#include "extern.h"
|
||||
|
||||
#define COPY_TEMPLATE "%s.sign"
|
||||
|
||||
static int
|
||||
embed_signature_FILE(orig, dest, sign, filename)
|
||||
/*@temp@*/FILE *orig;
|
||||
/*@temp@*/FILE *dest;
|
||||
struct signature *sign;
|
||||
const char *filename;
|
||||
{
|
||||
struct mygzip_header h;
|
||||
int c;
|
||||
|
||||
if (gzip_read_header(orig, &h, NULL) == GZIP_NOT_GZIP)
|
||||
return 0;
|
||||
|
||||
if (gzip_write_header(dest, &h, sign) == 0)
|
||||
return 0;
|
||||
while ((c = fgetc(orig)) != EOF && fputc(c, dest) != EOF)
|
||||
;
|
||||
if (ferror(dest) != 0)
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int
|
||||
embed_signature(filename, copy, sign)
|
||||
const char *filename;
|
||||
const char *copy;
|
||||
struct signature *sign;
|
||||
{
|
||||
FILE *orig, *dest;
|
||||
int success;
|
||||
|
||||
success = 0;
|
||||
orig= fopen(filename, "r");
|
||||
if (orig) {
|
||||
dest = fopen(copy, "w");
|
||||
if (dest) {
|
||||
success = embed_signature_FILE(orig, dest, sign, filename);
|
||||
if (fclose(dest) != 0)
|
||||
success = 0;
|
||||
}
|
||||
if (fclose(orig) != 0)
|
||||
success = 0;
|
||||
}
|
||||
return success;
|
||||
}
|
||||
|
||||
int
|
||||
sign(filename, type, userid, envp)
|
||||
const char *filename;
|
||||
const char *userid;
|
||||
int type;
|
||||
char *envp[];
|
||||
{
|
||||
char *copy;
|
||||
int result;
|
||||
struct signature *sign;
|
||||
int success;
|
||||
|
||||
sign = NULL;
|
||||
switch(type) {
|
||||
case TAG_PGP:
|
||||
success = retrieve_pgp_signature(filename, &sign, userid, envp);
|
||||
break;
|
||||
case TAG_SHA1:
|
||||
success = retrieve_sha1_marker(filename, &sign, userid);
|
||||
break;
|
||||
case TAG_X509:
|
||||
success = retrieve_x509_marker(filename, &sign, userid);
|
||||
break;
|
||||
default:
|
||||
success = 0;
|
||||
fprintf(stderr, "Unknown type %d\n", type);
|
||||
}
|
||||
|
||||
if (!success) {
|
||||
fprintf(stderr, "Problem signing %s\n", filename);
|
||||
free_signature(sign);
|
||||
return 0;
|
||||
}
|
||||
copy = malloc(strlen(filename)+sizeof(COPY_TEMPLATE));
|
||||
if (copy == NULL) {
|
||||
fprintf(stderr, "Can't allocate memory\n");
|
||||
free_signature(sign);
|
||||
return 0;
|
||||
}
|
||||
sprintf(copy, COPY_TEMPLATE, filename);
|
||||
result = embed_signature(filename, copy, sign);
|
||||
if (result == 0) {
|
||||
fprintf(stderr, "Can't embed signature in %s\n", filename);
|
||||
} else if (unlink(filename) != 0) {
|
||||
fprintf(stderr, "Can't unlink original %s\n", filename);
|
||||
result = 0;
|
||||
} else if (rename(copy, filename) != 0) {
|
||||
fprintf(stderr, "Can't rename new file %s\n", copy);
|
||||
result = 0;
|
||||
}
|
||||
free(copy);
|
||||
free_signature(sign);
|
||||
return result;
|
||||
}
|
||||
|
@ -1,57 +0,0 @@
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#include "stand.h"
|
||||
|
||||
#ifndef BSD4_4
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <errno.h>
|
||||
#include <stdarg.h>
|
||||
|
||||
/* shortened version of warn */
|
||||
static const char *program_name;
|
||||
|
||||
void
|
||||
set_program_name(n)
|
||||
const char *n;
|
||||
{
|
||||
if ((program_name = strrchr(n, '/')) != NULL)
|
||||
program_name++;
|
||||
else
|
||||
program_name = n;
|
||||
}
|
||||
|
||||
void
|
||||
warn(const char *fmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
int interrno;
|
||||
|
||||
va_start(ap, fmt);
|
||||
|
||||
interrno = errno;
|
||||
(void)fprintf(stderr, "%s: ", program_name);
|
||||
if (fmt != NULL) {
|
||||
(void)vfprintf(stderr, fmt, ap);
|
||||
(void)fprintf(stderr, ": ");
|
||||
}
|
||||
(void)fprintf(stderr, "%s\n", strerror(interrno));
|
||||
|
||||
va_end(ap);
|
||||
}
|
||||
|
||||
void
|
||||
warnx(const char *fmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
|
||||
va_start(ap, fmt);
|
||||
(void)fprintf(stderr, "%s: ", program_name);
|
||||
if (fmt != NULL)
|
||||
(void)vfprintf(stderr, fmt, ap);
|
||||
(void)fprintf(stderr, "\n");
|
||||
va_end(ap);
|
||||
}
|
||||
|
||||
#endif
|
@ -1,28 +0,0 @@
|
||||
/* $FreeBSD$ */
|
||||
/* $OpenBSD: stand.h,v 1.2 1999/10/04 21:46:30 espie Exp $ */
|
||||
|
||||
/* provided to cater for BSD idiosyncrasies */
|
||||
|
||||
#if (defined(__unix__) || defined(unix)) && !defined(USG)
|
||||
#include <sys/param.h>
|
||||
#endif
|
||||
|
||||
#ifndef __P
|
||||
#ifdef __STDC__
|
||||
#define __P(x) x
|
||||
#else
|
||||
#define __P(x) ()
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if defined(BSD4_4)
|
||||
#include <err.h>
|
||||
#else
|
||||
extern void warn __P((const char *fmt, ...));
|
||||
extern void warnx __P((const char *fmt, ...));
|
||||
#endif
|
||||
extern void set_program_name __P((const char * name));
|
||||
|
||||
#ifndef __GNUC__
|
||||
#define __attribute__(x)
|
||||
#endif
|
@ -1,428 +0,0 @@
|
||||
/*-
|
||||
* Copyright (c) 2000 Softweyr LLC, South Jordan, Utah, USA.
|
||||
*
|
||||
* 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 Softweyr LLC ``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 Softweyr LLC 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.
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/wait.h>
|
||||
|
||||
#include <assert.h>
|
||||
#include <fcntl.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <libgen.h>
|
||||
|
||||
#include <openssl/rsa.h>
|
||||
#include <openssl/evp.h>
|
||||
#include <openssl/objects.h>
|
||||
#include <openssl/x509.h>
|
||||
#include <openssl/err.h>
|
||||
#include <openssl/pem.h>
|
||||
#include <openssl/ssl.h>
|
||||
|
||||
#include "stand.h"
|
||||
#include "gzip.h"
|
||||
#include "extern.h"
|
||||
|
||||
|
||||
/*
|
||||
* Default names for the signing key and certificate(s) for verification.
|
||||
*/
|
||||
#define CERTFILE "/etc/ssl/pkg.crt"
|
||||
#define KEYFILE "/etc/ssl/pkg.key"
|
||||
|
||||
|
||||
/*
|
||||
* Private context for X.509 signature checker
|
||||
*/
|
||||
struct x509_checker
|
||||
{
|
||||
const char * id;
|
||||
const char * filename;
|
||||
|
||||
struct signature * signature;
|
||||
|
||||
STACK_OF(X509) * certs;
|
||||
EVP_MD_CTX rsa_ctx, dsa_ctx;
|
||||
int has_rsa, has_dsa;
|
||||
};
|
||||
|
||||
|
||||
static void key_from_name(char *, const char *);
|
||||
|
||||
/*
|
||||
* Initialize an X.509 "checker" context.
|
||||
*/
|
||||
void *
|
||||
new_x509_checker(h, sign, userid, envp, filename)
|
||||
struct mygzip_header *h;
|
||||
struct signature *sign;
|
||||
const char *userid;
|
||||
char *envp[];
|
||||
/*@observer@*/const char *filename;
|
||||
{
|
||||
FILE * fp;
|
||||
struct x509_checker * me;
|
||||
char certfile[PATH_MAX + 1] = CERTFILE;
|
||||
X509 * x509;
|
||||
|
||||
assert(sign->type == TAG_X509);
|
||||
|
||||
/*
|
||||
* Make sure data conforms to what we can handle. We do not write a
|
||||
* trailing null onto the signature like some other types, because
|
||||
* the X.509 signature is binary data.
|
||||
*/
|
||||
if (sign->length > MAXID) {
|
||||
warnx("Corrupted X.509 header in %s", filename);
|
||||
return 0;
|
||||
}
|
||||
|
||||
me = malloc(sizeof *me);
|
||||
if (me == NULL) {
|
||||
warn("Cannot allocate x509_checker");
|
||||
return 0;
|
||||
}
|
||||
me->id = sign->data;
|
||||
me->filename = filename;
|
||||
me->signature = sign;
|
||||
me->has_rsa = 0;
|
||||
me->has_dsa = 0;
|
||||
|
||||
key_from_name(certfile, userkey);
|
||||
|
||||
/*
|
||||
* Load just the crypto library error strings.
|
||||
*/
|
||||
ERR_load_crypto_strings();
|
||||
|
||||
/*
|
||||
* Load the stack of X.509 certs we will compare against.
|
||||
*
|
||||
* KLUDGE: this needs to be fleshed out a bit. We can do better
|
||||
* than hard-coding the location of the cert key file.
|
||||
*/
|
||||
me->certs = sk_X509_new_null();
|
||||
|
||||
fp = fopen(certfile, "r");
|
||||
if (fp == NULL) {
|
||||
warnx("Cannot open public key %s", certfile);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (verbose)
|
||||
printf("Loading certificates from %s:\n", certfile);
|
||||
|
||||
while ((x509 = PEM_read_X509(fp, NULL, NULL, 0))) {
|
||||
sk_X509_push(me->certs, x509);
|
||||
|
||||
switch (EVP_PKEY_type(X509_get_pubkey(x509)->type))
|
||||
{
|
||||
case EVP_PKEY_RSA:
|
||||
me->has_rsa = 1;
|
||||
break;
|
||||
|
||||
case EVP_PKEY_DSA:
|
||||
me->has_dsa = 1;
|
||||
break;
|
||||
|
||||
default:
|
||||
warnx("Unknown certificate type: %d", EVP_PKEY_type(X509_get_pubkey(x509)->type));
|
||||
fclose(fp);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* By default, print the contents of the cert we matched so the
|
||||
* user can decide if she is willing to accept a package from
|
||||
* whoever signed this.
|
||||
*/
|
||||
if (!quiet)
|
||||
X509_print_fp(stdout, x509);
|
||||
}
|
||||
fclose(fp);
|
||||
|
||||
/*
|
||||
* Initialize the verification contexts for both RSA and DSA.
|
||||
*/
|
||||
if (me->has_rsa) EVP_VerifyInit(&me->rsa_ctx, EVP_sha1());
|
||||
if (me->has_dsa) EVP_VerifyInit(&me->dsa_ctx, EVP_dss1());
|
||||
|
||||
return me;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* "Add" another data block to an existing checker.
|
||||
*/
|
||||
void
|
||||
x509_add(arg, buffer, length)
|
||||
void *arg;
|
||||
const char *buffer;
|
||||
size_t length;
|
||||
{
|
||||
struct x509_checker * me = arg;
|
||||
|
||||
if (me->has_rsa) EVP_VerifyUpdate(&me->rsa_ctx, buffer, length);
|
||||
if (me->has_dsa) EVP_VerifyUpdate(&me->dsa_ctx, buffer, length);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Finalize an existing checker and verify the signature matches one of the
|
||||
* certs in our stack.
|
||||
*/
|
||||
int
|
||||
x509_sign_ok(arg)
|
||||
void *arg;
|
||||
{
|
||||
struct x509_checker * n = arg;
|
||||
X509 * x509;
|
||||
EVP_PKEY * pkey;
|
||||
EVP_MD_CTX * md_ctx;
|
||||
int status;
|
||||
|
||||
if (verbose)
|
||||
printf("\n\n-------\n\nChecking package signature:\n");
|
||||
|
||||
while ((x509 = sk_X509_pop(n->certs)) != NULL) {
|
||||
/*
|
||||
* Get public key from cert.
|
||||
*/
|
||||
pkey = X509_get_pubkey(x509);
|
||||
if (pkey == NULL) {
|
||||
warnx("Getting public key:");
|
||||
ERR_print_errors_fp(stderr);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (verbose)
|
||||
X509_print_fp(stdout, x509);
|
||||
|
||||
switch (EVP_PKEY_type(pkey->type))
|
||||
{
|
||||
case EVP_PKEY_RSA:
|
||||
md_ctx = &n->rsa_ctx;
|
||||
break;
|
||||
|
||||
case EVP_PKEY_DSA:
|
||||
md_ctx = &n->dsa_ctx;
|
||||
break;
|
||||
|
||||
default:
|
||||
warnx("Unknown public key type: %d", EVP_PKEY_type(pkey->type));
|
||||
md_ctx = NULL;
|
||||
break;
|
||||
}
|
||||
|
||||
status = (md_ctx == NULL) ? 0 : EVP_VerifyFinal(md_ctx,
|
||||
n->signature->data,
|
||||
n->signature->length,
|
||||
pkey);
|
||||
|
||||
EVP_PKEY_free(pkey);
|
||||
X509_free(x509);
|
||||
|
||||
if (status == 1) {
|
||||
fprintf(stderr, "X.509 signature matched\n");
|
||||
|
||||
/*
|
||||
* KLUDGE: Does this free the rest of the certs, or just the
|
||||
* stack itself? Enquiring minds want to know.
|
||||
*/
|
||||
sk_X509_free(n->certs);
|
||||
return PKG_GOODSIG;
|
||||
}
|
||||
}
|
||||
|
||||
warnx("Verifying signature:");
|
||||
ERR_print_errors_fp(stderr);
|
||||
sk_X509_free(n->certs);
|
||||
return PKG_BADSIG;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Sign the specified filename into sign.
|
||||
*/
|
||||
int
|
||||
retrieve_x509_marker(filename, sign, userid)
|
||||
const char * filename;
|
||||
struct signature ** sign;
|
||||
const char * userid;
|
||||
{
|
||||
struct signature * n;
|
||||
struct mygzip_header h;
|
||||
FILE * f, * keyf;
|
||||
char buffer[1024];
|
||||
ssize_t length;
|
||||
int err;
|
||||
int sig_len = 4096;
|
||||
unsigned char * sig_buf;
|
||||
EVP_MD_CTX md_ctx;
|
||||
const EVP_MD * md_type;
|
||||
EVP_PKEY * pkey;
|
||||
|
||||
char keyfile[PATH_MAX + 1] = KEYFILE;
|
||||
|
||||
key_from_name(keyfile, userkey);
|
||||
|
||||
f = fopen(filename, "r");
|
||||
if (f == NULL) {
|
||||
return 0;
|
||||
}
|
||||
if (gzip_read_header(f, &h, sign) == GZIP_NOT_GZIP) {
|
||||
warnx("File %s is not a gzip file\n", filename);
|
||||
fclose(f);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Sign the remaining data:
|
||||
* Load just the crypto library error strings.
|
||||
*/
|
||||
ERR_load_crypto_strings();
|
||||
|
||||
/*
|
||||
* Read private key.
|
||||
*/
|
||||
keyf = fopen(keyfile, "r");
|
||||
if (keyf == NULL)
|
||||
{
|
||||
warnx("Cannot open private key %s.", keyfile);
|
||||
fclose(f);
|
||||
return 0;
|
||||
}
|
||||
|
||||
pkey = PEM_read_PrivateKey(keyf, NULL, NULL, 0);
|
||||
fclose(keyf);
|
||||
|
||||
if (pkey == NULL)
|
||||
{
|
||||
warnx("Reading private key %s:", keyfile);
|
||||
ERR_print_errors_fp(stderr);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Do the signature. The remaining bytes of the GZIP file are the
|
||||
* compressed tar image, which is what we are signing.
|
||||
*/
|
||||
switch (EVP_PKEY_type(pkey->type))
|
||||
{
|
||||
case EVP_PKEY_RSA:
|
||||
md_type = EVP_sha1();
|
||||
break;
|
||||
|
||||
case EVP_PKEY_DSA:
|
||||
md_type = EVP_dss1();
|
||||
break;
|
||||
|
||||
default:
|
||||
warnx("Unknown key type");
|
||||
fclose(f);
|
||||
return 0;
|
||||
}
|
||||
|
||||
EVP_SignInit(&md_ctx, md_type);
|
||||
|
||||
while ((length = fread(buffer, 1, sizeof buffer, f)) > 0)
|
||||
EVP_SignUpdate(&md_ctx, buffer, length);
|
||||
|
||||
fclose(f);
|
||||
|
||||
sig_buf = malloc(sig_len);
|
||||
if (sig_buf == NULL) {
|
||||
warnx("Cannot allocated %u bytes for signature buffer", sig_len);
|
||||
return 0;
|
||||
}
|
||||
|
||||
err = EVP_SignFinal(&md_ctx, sig_buf, &sig_len, pkey);
|
||||
|
||||
if (err != 1)
|
||||
{
|
||||
warnx("Creating signature:");
|
||||
ERR_print_errors_fp(stderr);
|
||||
return 0;
|
||||
}
|
||||
|
||||
EVP_PKEY_free(pkey);
|
||||
|
||||
/*
|
||||
* Stuff the signature onto the head of the chain of signatures in
|
||||
* the package.
|
||||
*/
|
||||
n = malloc(sizeof *n);
|
||||
if (n == NULL) {
|
||||
warnx("Cannot allocate %u bytes for new signature", sizeof *n);
|
||||
return 0;
|
||||
}
|
||||
n->data = sig_buf;
|
||||
n->length = sig_len;
|
||||
n->type = TAG_X509;
|
||||
memcpy(n->tag, x509tag, sizeof x509tag);
|
||||
sign_fill_tag(n);
|
||||
n->next = *sign;
|
||||
*sign = n;
|
||||
|
||||
/*
|
||||
* Report our success.
|
||||
*/
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
key_from_name(char * filename, const char * ident)
|
||||
{
|
||||
char * cp;
|
||||
|
||||
/*
|
||||
* If an alternate keyfile was specified, treat it as the name of an
|
||||
* alternate private key with which to sign or verify the package.
|
||||
*/
|
||||
if (ident) {
|
||||
printf("Using alternate key/cert \"%s\".\n", ident);
|
||||
if (strchr(ident, '/')) {
|
||||
/*
|
||||
* The user specified a path, take it verbatim.
|
||||
*/
|
||||
strncpy(filename, ident, PATH_MAX);
|
||||
} else {
|
||||
cp = dirname(filename);
|
||||
if (cp == NULL) {
|
||||
warnx("Key directory not correctly specified.");
|
||||
return;
|
||||
}
|
||||
snprintf(filename, PATH_MAX, "%s/%s", cp, ident);
|
||||
}
|
||||
}
|
||||
|
||||
if (verbose)
|
||||
printf("Key is \"%s\".\n", filename);
|
||||
}
|
@ -35,7 +35,7 @@ Boolean RegexExtended = FALSE;
|
||||
Boolean UseINDEXOnly = FALSE;
|
||||
Boolean ShowOrigin = FALSE;
|
||||
|
||||
static void usage __P((void));
|
||||
static void usage(void);
|
||||
|
||||
int
|
||||
main(int argc, char **argv)
|
||||
@ -54,7 +54,7 @@ main(int argc, char **argv)
|
||||
else while ((ch = getopt(argc, argv, Options)) != -1) {
|
||||
switch(ch) {
|
||||
case 'v':
|
||||
Verbose = TRUE;
|
||||
Verbose++;
|
||||
break;
|
||||
|
||||
case 'I':
|
||||
@ -77,9 +77,9 @@ main(int argc, char **argv)
|
||||
MatchName = optarg;
|
||||
break;
|
||||
|
||||
case 'O':
|
||||
LookUpOrigin = optarg;
|
||||
break;
|
||||
case 'O':
|
||||
LookUpOrigin = optarg;
|
||||
break;
|
||||
|
||||
case 'o':
|
||||
ShowOrigin = TRUE;
|
||||
|
@ -235,8 +235,8 @@ pkg_do(char *pkg)
|
||||
show_version(plist, NULL, NULL);
|
||||
else
|
||||
show_version(plist, latest, "index");
|
||||
}
|
||||
}
|
||||
}
|
||||
if (latest != NULL)
|
||||
free(latest);
|
||||
free_plist(&plist);
|
||||
@ -275,7 +275,7 @@ show_version(Package plist, const char *latest, const char *source)
|
||||
if (Verbose)
|
||||
printf(" Comparison failed");
|
||||
printf("\n");
|
||||
} else if (source == NULL && OUTPUT('?')) {
|
||||
} else if (OUTPUT('?')) {
|
||||
printf("%-34s ?", tmp);
|
||||
if (Verbose)
|
||||
printf(" orphaned: %s", plist.origin);
|
||||
|
@ -25,7 +25,7 @@
|
||||
.\"
|
||||
.\" $FreeBSD$
|
||||
.\"
|
||||
.Dd Jul 27, 2005
|
||||
.Dd July 27, 2005
|
||||
.Dt PKG_VERSION 1
|
||||
.Os
|
||||
.Sh NAME
|
||||
@ -72,7 +72,7 @@ cannot be located,
|
||||
.Nm
|
||||
will search for the package in the ports collection index file
|
||||
(typically
|
||||
.Pa /usr/ports/INDEX-6 ) .
|
||||
.Pa /usr/ports/INDEX-8 ) .
|
||||
Any matching version number(s) there will be used to determine whether
|
||||
the installed package is up-to-date or requires updating.
|
||||
.Pp
|
||||
@ -205,12 +205,12 @@ can be used here.
|
||||
If no
|
||||
.Ar index
|
||||
file is specified on the command line,
|
||||
.Pa /usr/ports/INDEX-6
|
||||
.Pa /usr/ports/INDEX-8
|
||||
is used.
|
||||
.El
|
||||
.Sh FILES
|
||||
.Bl -tag -width /usr/ports/INDEX-6 -compact
|
||||
.It Pa /usr/ports/INDEX-6
|
||||
.Bl -tag -width /usr/ports/INDEX-8 -compact
|
||||
.It Pa /usr/ports/INDEX-8
|
||||
Default index file.
|
||||
.El
|
||||
.Sh EXAMPLES
|
||||
@ -224,7 +224,7 @@ index file:
|
||||
The command below generates a report against
|
||||
the version numbers in the on-line ports collection:
|
||||
.Pp
|
||||
.Dl % pkg_version http://www.FreeBSD.org/ports/INDEX-6
|
||||
.Dl % pkg_version http://www.FreeBSD.org/ports/INDEX-8
|
||||
.Pp
|
||||
The following command compares two package version strings:
|
||||
.Pp
|
||||
|
@ -23,13 +23,6 @@
|
||||
#ifndef _INST_VERSION_H_INCLUDE
|
||||
#define _INST_VERSION_H_INCLUDE
|
||||
|
||||
/* Where the ports lives by default */
|
||||
#define DEF_PORTS_DIR "/usr/ports"
|
||||
/* just in case we change the environment variable name */
|
||||
#define PORTSDIR "PORTSDIR"
|
||||
/* macro to get name of directory where we put logging information */
|
||||
#define PORTS_DIR (getenv(PORTSDIR) ? getenv(PORTSDIR) : DEF_PORTS_DIR)
|
||||
|
||||
struct index_entry {
|
||||
SLIST_ENTRY(index_entry) next;
|
||||
char *name;
|
||||
|
Loading…
x
Reference in New Issue
Block a user