3 Commits

Author SHA1 Message Date
oysteikt 3a17ecb3e5 WIP 2026-02-08 16:07:33 +09:00
oysteikt 19156b61f1 Set up nix tooling 2026-02-08 15:58:06 +09:00
oysteikt 63ad2a7931 zed: set tab width 2026-02-08 15:58:01 +09:00
191 changed files with 28956 additions and 4705 deletions
-1
View File
@@ -3,7 +3,6 @@ name: Test Coverage
on:
push:
branches:
- 'master'
- 'coverage-*'
jobs:
+2 -1
View File
@@ -49,7 +49,8 @@ jobs:
cd build
../configure --srcdir=`dirname "$PWD"` --enable-maintainer-mode --enable-developer --with-ldap $CONFIGURE_OPTS --prefix=$HOME/inst CFLAGS="-Wno-error=shadow -Wno-error=bad-function-cast -Wno-error=unused-function -Wno-error=unused-result -Wno-error=deprecated-declarations"
ulimit -c unlimited
# We don't want to scan-build SQLite3 because ETOOSLOW
# We don't want to scan-build libedit nor SQLite3 because ETOOSLOW
(cd lib/libedit && make -j4)
(cd lib/sqlite && make -j4)
cov-build --dir cov-int make -j4
tar czvf ../heimdal.tgz cov-int
+1 -76
View File
@@ -5,7 +5,6 @@ on:
branches:
- 'master'
- 'heimdal-7-1-branch'
- 'test-ILP32'
paths:
- '!docs/**'
- '!**.md'
@@ -64,7 +63,6 @@ jobs:
os: ubuntu-22.04
compiler: gcc
cflags: '-Wnonnull'
configureopts: '--with-readline=yes'
steps:
- name: Clone repository
uses: actions/checkout@v4
@@ -75,7 +73,7 @@ jobs:
sudo apt-get install -y bison comerr-dev flex doxygen
sudo apt-get install -y libcap-ng-dev libdb-dev libedit-dev libjson-perl
sudo apt-get install -y libldap2-dev libncurses5-dev libperl4-corelibs-perl
sudo apt-get install -y libsqlite3-dev libkeyutils-dev libreadline-dev pkg-config python3
sudo apt-get install -y libsqlite3-dev libkeyutils-dev pkg-config python3
sudo apt-get install -y ss-dev texinfo unzip netbase keyutils ldap-utils
sudo apt-get install -y gdb apport curl libmicrohttpd-dev jq valgrind
# Temporary workaround for:
@@ -85,7 +83,6 @@ jobs:
env:
CC: ${{ matrix.compiler }}
MAKEVARS: ${{ matrix.makevars }}
CONFIGURE_OPTS: ${{ matrix.configureopts }}
run: |
/bin/sh ./autogen.sh
mkdir build
@@ -172,75 +169,3 @@ jobs:
with:
name: Test Logs (${{ matrix.name }})
path: '~/logs-linux-${{ matrix.compiler }}.tgz'
linux-i386:
name: linux-i386 (${{ matrix.name }})
# Run if no [only X] tag, or if [only linux] is present (check both push commits and PR titles)
if: >-
(!contains(github.event.head_commit.message, '[only ') &&
!contains(github.event.pull_request.title, '[only ')) ||
contains(github.event.head_commit.message, '[only linux]') ||
contains(github.event.pull_request.title, '[only linux]')
runs-on: ubuntu-22.04
strategy:
fail-fast: false
matrix:
include:
- name: time32
image: i386/debian:bookworm
year2038_configure: ""
time_t_size: 4
- name: year2038
image: i386/debian:trixie
year2038_configure: --enable-year2038
time_t_size: 8
steps:
- name: Clone repository
uses: actions/checkout@v4
- name: Build and test on Debian i386
run: |
docker run --security-opt seccomp=unconfined --platform linux/386 --rm \
-v "$PWD:/src:ro" \
-e YEAR2038_CONFIGURE="${{ matrix.year2038_configure }}" \
-e EXPECT_TIME_T_SIZE="${{ matrix.time_t_size }}" \
${{ matrix.image }} \
/bin/bash -euxc '
export DEBIAN_FRONTEND=noninteractive
apt-get update -qq
apt-get install -y --no-install-recommends \
autoconf automake bison build-essential ca-certificates \
comerr-dev curl doxygen flex gdb git iproute2 jq keyutils \
ldap-utils libcap-ng-dev libdb-dev libedit-dev libjson-perl \
libkeyutils-dev libldap2-dev liblmdb-dev libmicrohttpd-dev libncurses5-dev \
libperl4-corelibs-perl libreadline-dev libsqlite3-dev libssl-dev \
libtool make netbase pkg-config procps python3 ss-dev tar \
texinfo unzip valgrind xz-utils
cp -a /src /tmp/heimdal-src
git config --global --add safe.directory /tmp/heimdal-src
cd /tmp/heimdal-src
/bin/sh ./autogen.sh
mkdir build
cd build
../configure --srcdir=`dirname "$PWD"` \
--enable-maintainer-mode \
--enable-developer \
${YEAR2038_CONFIGURE} \
--with-ldap \
--with-readline=yes \
--with-db-type-preference=lmdb \
--prefix=/tmp/heimdal-i386-inst \
CFLAGS="-Wnonnull -Wno-error=shadow -Wno-error=bad-function-cast -Wno-error=unused-function -Wno-error=unused-result -Wno-error=deprecated-declarations"
printf "%s\n" \
"#include \"include/config.h\"" \
"#include <stdio.h>" \
"#include <time.h>" \
"int main(void) { unsigned long s = sizeof(time_t); printf(\"sizeof(time_t)=%lu\n\", s); return s == EXPECT_TIME_T_SIZE ? 0 : 1; }" \
> check-time-t.c
cc -I. -I.. -DEXPECT_TIME_T_SIZE="$EXPECT_TIME_T_SIZE" -o check-time-t check-time-t.c
./check-time-t
make -j4
make -C lib/asn1 check
make -C lib/hx509 check TESTS=test_cert_binary
make DESTDIR=/tmp/heimdal-i386-root install
'
-1
View File
@@ -62,7 +62,6 @@ jobs:
- name: osx-clang
os: macos-latest
compiler: clang
configureopts: '--with-libedit=yes'
steps:
- name: Install packages
run: |
+2 -1
View File
@@ -44,7 +44,8 @@ jobs:
cd build
../configure --srcdir=`dirname "$PWD"` --enable-maintainer-mode --enable-developer --with-ldap $CONFIGURE_OPTS --prefix=$HOME/inst CFLAGS="-Wno-error=shadow -Wno-error=bad-function-cast -Wno-error=unused-function -Wno-error=unused-result -Wno-error=deprecated-declarations"
ulimit -c unlimited
# We don't want to scan-build SQLite3 because ETOOSLOW
# We don't want to scan-build libedit nor SQLite3 because ETOOSLOW
(cd lib/libedit && make -j4)
(cd lib/sqlite && make -j4)
scan-build --keep-going make -j4
- name: Test
+26 -3
View File
@@ -64,6 +64,32 @@ asn1_*_asn1.c
/tmp.h
/ylwrap
/lib/libedit/aclocal.m4
/lib/libedit/autom4te.cache
/lib/libedit/compile
/lib/libedit/config.guess
/lib/libedit/config.h
/lib/libedit/config.log
/lib/libedit/config.status
/lib/libedit/config.sub
/lib/libedit/configure
/lib/libedit/depcomp
/lib/libedit/install-sh
/lib/libedit/libtool
/lib/libedit/ltmain.sh
/lib/libedit/missing
/lib/libedit/setupbuild.cmd
/lib/libedit/ylwrap
/lib/libedit/src/common.h
/lib/libedit/src/emacs.h
/lib/libedit/src/fcns.c
/lib/libedit/src/fcns.h
/lib/libedit/src/func.h
/lib/libedit/src/help.c
/lib/libedit/src/help.h
/lib/libedit/src/vi.h
/lib/libedit/stamp-h1
# Files in subdirectories.
/admin/ktutil
@@ -694,6 +720,3 @@ asn1_*_asn1.c
/tools/krb5-gssapi.pc
/tools/krb5.pc
/tools/krb5-config
result
result-*
-1
View File
@@ -7,7 +7,6 @@ Release Notes - Heimdal - Version Heimdal 8.0 (future)
- Errors found by the LLVM scan-build static analyzer.
- Errors found by the valgrind memory debugger.
- Fix out-of-tree SQLite3 ccache permissions / umask issues.
- Clamp far-future ASN.1 times on 32-bit time_t platforms instead of wrapping.
- iprop bugs, race conditions, and performance
- Many misc. bugs
-2
View File
@@ -1,7 +1,6 @@
[![GitHub Build Workflow](https://github.com/heimdal/heimdal/actions/workflows/linux.yml/badge.svg)](https://github.com/heimdal/heimdal/actions?query=workflow%3Alinux)
[![GitHub Build Workflow](https://github.com/heimdal/heimdal/actions/workflows/osx.yml/badge.svg)](https://github.com/heimdal/heimdal/actions?query=workflow%3Aosx)
[![GitHub Build Workflow](https://github.com/heimdal/heimdal/actions/workflows/windows.yml/badge.svg)](https://github.com/heimdal/heimdal/actions?query=workflow%3Awindows)
[![Coverage Status](https://coveralls.io/repos/github/heimdal/heimdal/badge.svg?branch=master)](https://coveralls.io/github/heimdal/heimdal?branch=master)
Heimdal
=======
@@ -34,4 +33,3 @@ Build Status
[![GitHub Build Workflow](https://github.com/heimdal/heimdal/actions/workflows/linux.yml/badge.svg)](https://github.com/heimdal/heimdal/actions?query=workflow%3Alinux)
[![GitHub Build Workflow](https://github.com/heimdal/heimdal/actions/workflows/osx.yml/badge.svg)](https://github.com/heimdal/heimdal/actions?query=workflow%3Aosx)
[![GitHub Build Workflow](https://github.com/heimdal/heimdal/actions/workflows/windows.yml/badge.svg)](https://github.com/heimdal/heimdal/actions?query=workflow%3Awindows)
[![Coverage Status](https://coveralls.io/repos/github/heimdal/heimdal/badge.svg?branch=master)](https://coveralls.io/github/heimdal/heimdal?branch=master)
+27 -50
View File
@@ -43,9 +43,6 @@ kt_rename(struct rename_options *opt, int argc, char **argv)
krb5_keytab keytab;
krb5_kt_cursor cursor;
krb5_principal from_princ, to_princ;
krb5_keytab_entry *entries = NULL;
size_t num_entries = 0;
size_t i;
ret = krb5_parse_name(context, argv[0], &from_princ);
if(ret != 0) {
@@ -66,14 +63,6 @@ kt_rename(struct rename_options *opt, int argc, char **argv)
return 1;
}
/*
* Collect matching entries first, then close the cursor before
* adding/removing. We must not call krb5_kt_add_entry() or
* krb5_kt_remove_entry() while holding the seq_get cursor because
* the cursor holds a shared file lock and the add/remove operations
* need an exclusive lock -- with per-fd locking (BSD flock, OFD locks)
* this self-deadlocks.
*/
ret = krb5_kt_start_seq_get(context, keytab, &cursor);
if(ret) {
krb5_kt_close(context, keytab);
@@ -81,52 +70,40 @@ kt_rename(struct rename_options *opt, int argc, char **argv)
krb5_free_principal(context, to_princ);
return 1;
}
while((ret = krb5_kt_next_entry(context, keytab, &entry, &cursor)) == 0) {
if(krb5_principal_compare(context, entry.principal, from_princ)) {
krb5_keytab_entry *tmp;
tmp = realloc(entries, (num_entries + 1) * sizeof(*entries));
if (tmp == NULL) {
krb5_kt_free_entry(context, &entry);
ret = krb5_enomem(context);
break;
}
entries = tmp;
krb5_free_principal(context, entry.principal);
entry.principal = NULL;
entries[num_entries++] = entry;
} else {
krb5_kt_free_entry(context, &entry);
}
}
if(ret == KRB5_CC_END || ret == KRB5_KT_END)
ret = 0;
else if(ret)
krb5_warn(context, ret, "getting entry from keytab");
krb5_kt_end_seq_get(context, keytab, &cursor);
for (i = 0; ret == 0 && i < num_entries; i++) {
entries[i].principal = to_princ;
ret = krb5_kt_add_entry(context, keytab, &entries[i]);
if(ret) {
krb5_warn(context, ret, "adding entry");
while(1) {
ret = krb5_kt_next_entry(context, keytab, &entry, &cursor);
if(ret != 0) {
if(ret != KRB5_CC_END && ret != KRB5_KT_END)
krb5_warn(context, ret, "getting entry from keytab");
else
ret = 0;
break;
}
if (opt->delete_flag) {
entries[i].principal = from_princ;
ret = krb5_kt_remove_entry(context, keytab, &entries[i]);
if(krb5_principal_compare(context, entry.principal, from_princ)) {
krb5_free_principal(context, entry.principal);
entry.principal = to_princ;
ret = krb5_kt_add_entry(context, keytab, &entry);
if(ret) {
krb5_warn(context, ret, "removing entry");
entry.principal = NULL;
krb5_kt_free_entry(context, &entry);
krb5_warn(context, ret, "adding entry");
break;
}
if (opt->delete_flag) {
entry.principal = from_princ;
ret = krb5_kt_remove_entry(context, keytab, &entry);
if(ret) {
entry.principal = NULL;
krb5_kt_free_entry(context, &entry);
krb5_warn(context, ret, "removing entry");
break;
}
}
entry.principal = NULL;
}
krb5_kt_free_entry(context, &entry);
}
for (i = 0; i < num_entries; i++) {
entries[i].principal = NULL;
krb5_kt_free_entry(context, &entries[i]);
}
free(entries);
krb5_kt_end_seq_get(context, keytab, &cursor);
krb5_free_principal(context, from_princ);
krb5_free_principal(context, to_princ);
+1 -1
View File
@@ -10,4 +10,4 @@ man_MANS = bsearch.1
EXTRA_DIST = NTMakefile $(man_MANS)
LDADD = $(LIB_vers) $(LIB_heimbase) $(LIB_roken)
LDADD = $(LIB_roken) $(LIB_vers) $(LIB_heimbase)
-3
View File
@@ -57,9 +57,6 @@ AS_IF([test "x$with_berkeley_db" != xno],
db.h \
])])
dnl detect if compat db_185.h is present
AC_CHECK_HEADERS([db_185.h])
dnl db_create is used by db3 and db4 and db5 and db6
AC_FIND_FUNC_NO_LIBS(db_create, [$dbheader] db-6 db-5 db4 db3 db, [
+11 -71
View File
@@ -9,80 +9,20 @@ AC_DEFUN([KRB_READLINE],[
dnl readline
readline_requested="${with_readline-unset}"
libedit_requested="${with_libedit-unset}"
have_readline=no
rk_TEST_PACKAGE(readline,
[#include <stdio.h>
#if defined(HAVE_READLINE_READLINE_H)
#include <readline/readline.h>
#elif defined(HAVE_READLINE_H)
#include <readline.h>
#endif
],-lreadline,[$LIB_tgetent],,[READLINE],, [readline.h readline/readline.h])
rk_TEST_PACKAGE(libedit,
[#include <stdio.h>
#if defined(HAVE_EDITLINE_READLINE_H)
#include <editline/readline.h>
#elif defined(HAVE_READLINE_READLINE_H)
#include <readline/readline.h>
#elif defined(HAVE_READLINE_H)
#include <readline.h>
#endif
],-ledit,[$LIB_tgetent],,[READLINE],,
[readline.h readline/readline.h editline/readline.h])
ac_foo=no
build_editline=no
if test "$with_readline" = yes; then
have_readline=yes
:
elif test "$with_libedit" = yes; then
INCLUDE_readline="${INCLUDE_libedit}"
LIB_readline="${LIB_libedit}"
have_readline=yes
elif test "$readline_requested" != no; then
rk_readline_header=no
AC_CHECK_HEADERS([readline/readline.h readline.h],
[rk_readline_header=yes])
if test "$rk_readline_header" = yes; then
AC_CHECK_LIB(readline, readline, [
LIB_readline="-lreadline"
if test "x$LIB_tgetent" != x; then
LIB_readline="$LIB_readline $LIB_tgetent"
fi
have_readline=yes
with_readline=yes
], [], [$LIB_tgetent])
fi
fi
if test "$have_readline" != yes && test "$libedit_requested" != no; then
rk_libedit_header=no
AC_CHECK_HEADERS([editline/readline.h readline/readline.h readline.h],
[rk_libedit_header=yes])
if test "$rk_libedit_header" = yes; then
AC_CHECK_LIB(edit, readline, [
LIB_readline="-ledit"
if test "x$LIB_tgetent" != x; then
LIB_readline="$LIB_readline $LIB_tgetent"
fi
have_readline=yes
with_libedit=yes
], [], [$LIB_tgetent])
fi
fi
if test "$have_readline" = yes; then
AC_DEFINE(HAVE_READLINE, 1,
[Define if you have a readline compatible library.])dnl
AC_DEFINE(READLINE, 1, [Define if you have the readline package.])dnl
LIB_readline="${LIB_libedit}"
elif test "$ac_cv_func_readline" = yes; then
:
else
INCLUDE_readline=
LIB_readline=
AC_MSG_NOTICE([readline/libedit not found; command line editing disabled])
build_libedit=yes
LIB_readline="\$(top_builddir)/lib/libedit/src/libheimedit.la \$(LIB_tgetent)"
fi
AC_SUBST(INCLUDE_readline)
AC_SUBST(LIB_readline)
AM_CONDITIONAL(LIBEDIT, test "$build_libedit" = yes)
AC_DEFINE(HAVE_READLINE, 1,
[Define if you have a readline compatible library.])dnl
])
-6
View File
@@ -19,10 +19,4 @@ if test "$enable_largefile" != no; then
[CPPFLAGS="$CPPFLAGS $ac_cv_sys_largefile_opts"])
fi
fi
if test "$enable_year2038" != no; then
if test -n "$ac_cv_sys_year2038_opts"; then
AS_CASE([$ac_cv_sys_year2038_opts],[-D_TIME_BITS=*|-D__MINGW_USE_VC2005_COMPAT],
[CPPFLAGS="$CPPFLAGS $ac_cv_sys_year2038_opts"])
fi
fi
])
+1 -1
View File
@@ -192,6 +192,7 @@ AC_CHECK_FUNCS([ \
mkdtemp \
mkostemp \
on_exit \
poll \
random \
secure_getenv \
setprogname \
@@ -359,7 +360,6 @@ AC_BROKEN([ \
mergesort \
mergesort_r \
mkstemp \
poll \
pread \
putenv \
rcmd \
+4 -4
View File
@@ -24,8 +24,8 @@ AC_ARG_WITH($1-config,
AS_HELP_STRING([--with-$1-config=path],[config program for $1]))
m4_ifval([$6],
[m4_define([rk_pkgname], [$6])],
[m4_define([rk_pkgname], [AS_TR_CPP($1)])])
m4_define([rk_pkgname], $6),
m4_define([rk_pkgname], AS_TR_CPP($1)))
AC_MSG_CHECKING(for $1)
@@ -91,7 +91,7 @@ if test "$with_$1" != no; then
if test "$[]$1_cflags" -a "$[]$1_libs"; then
CFLAGS="$[]$1_cflags $save_CFLAGS"
LIBS="$[]$1_libs $save_LIBS"
m4_ifval([$8],[AC_CHECK_HEADERS([$8])])
m4_ifval([$8],[AC_CHECK_HEADERS([[$8]])])
AC_LINK_IFELSE([AC_LANG_PROGRAM([[$2]],[[]])],[
INCLUDE_$1="$[]$1_cflags"
LIB_$1="$[]$1_libs"
@@ -102,7 +102,7 @@ if test "$with_$1" != no; then
ires= lres=
for i in $header_dirs; do
CFLAGS="-I$i $save_CFLAGS"
m4_ifval([$8],[AC_CHECK_HEADERS([$8])])
m4_ifval([$8],[AC_CHECK_HEADERS([[$8]])])
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[$2]],[[]])],[ires=$i;break])
done
for i in $lib_dirs; do
+37
View File
@@ -230,6 +230,21 @@ AM_CONDITIONAL([HAVE_MICROHTTPD], [test "$with_microhttpd" != "no"])
AC_SUBST([MICROHTTPD_CFLAGS])
AC_SUBST([MICROHTTPD_LIBS])
dnl systemd sd_notify support
AC_ARG_WITH([systemd],
AC_HELP_STRING([--with-systemd], [use systemd sd_notify for readiness @<:@default=check@:>@]),
[],
[with_systemd=check])
if test "$with_systemd" != "no"; then
PKG_CHECK_MODULES([SYSTEMD], [libsystemd], [with_systemd=yes],[with_systemd=no])
fi
if test "$with_systemd" = "yes"; then
AC_DEFINE_UNQUOTED([HAVE_SYSTEMD], 1, [Define if libsystemd sd_notify is available])
fi
AM_CONDITIONAL([HAVE_SYSTEMD], [test "$with_systemd" != "no"])
AC_SUBST([SYSTEMD_CFLAGS])
AC_SUBST([SYSTEMD_LIBS])
dnl mitkrb5
AC_ARG_WITH([mitkrb5],
AC_HELP_STRING([--with-mitkrb5=PATH], [Path to MIT Kerberos for interop testing]),
@@ -382,6 +397,28 @@ AC_SUBST(ENABLE_AFS_STRING_TO_KEY)dnl
rk_CHECK_MAN
rk_TEST_PACKAGE(readline,
[#include <stdio.h>
#if defined(HAVE_READLINE_READLINE_H)
#include <readline/readline.h>
#elif defined(HAVE_READLINE_H)
#include <readline.h>
#endif
],-lreadline,,, READLINE,, [readline.h readline/readline.h])
rk_TEST_PACKAGE(libedit,
[#include <stdio.h>
#if defined(HAVE_READLINE_READLINE_H)
#include <readline/readline.h>
#elif defined(HAVE_READLINE_H)
#include <readline.h>
#elif defined(HAVE_EDITLINE_READLINE_H)
#include <editline/readline.h>
#endif
],-ledit,,, READLINE,, [readline.h readline/readline.h editline/readline.h])
AC_CONFIG_SUBDIRS([lib/libedit])
KRB_C_BIGENDIAN
AC_C_INLINE
+3
View File
@@ -13,6 +13,9 @@ The @code{popper} was also a Berkeley program initially.
Some of the functions in @file{libroken} also come from Berkeley by way
of NetBSD/FreeBSD.
@code{editline} was written by Simmule Turner and Rich Salz. Heimdal
contains a modifed copy.
The @code{getifaddrs} implementation for Linux was written by Hideaki
YOSHIFUJI for the Usagi project.
+42
View File
@@ -123,6 +123,48 @@ SUCH DAMAGE.
@end verbatim
@copynext
@heading The Regents of the University of California.
libedit
@verbatim
SPDX-License-Identifier: BSD-3-Clause
Copyright (c) 1992, 1993
The Regents of the University of California. All rights reserved.
This code is derived from software contributed to Berkeley by
Christos Zoulas of Cornell University.
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. Neither the name of the University nor the names of its contributors
may be used to endorse or promote products derived from this software
without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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.
@end verbatim
@copynext
@copynext
@heading Doug Rabson
GSS-API mechglue layer.
Generated
+3 -3
View File
@@ -2,11 +2,11 @@
"nodes": {
"nixpkgs": {
"locked": {
"lastModified": 1770380644,
"narHash": "sha256-P7dWMHRUWG5m4G+06jDyThXO7kwSk46C1kgjEWcybkE=",
"lastModified": 1769740369,
"narHash": "sha256-xKPyJoMoXfXpDM5DFDZDsi9PHArf2k5BJjvReYXoFpM=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "ae67888ff7ef9dff69b3cf0cc0fbfbcd3a722abe",
"rev": "6308c3b21396534d8aaeac46179c14c439a89b8a",
"type": "github"
},
"original": {
+4 -18
View File
@@ -22,27 +22,13 @@
default = pkgs.callPackage ./nix/shell.nix { };
});
packages = forAllSystems (system: pkgs: let
src = lib.fileset.toSource {
root = ./.;
fileset = lib.fileset.difference ./. (lib.fileset.unions [
./.github
./.gitignore
./.zed
./flake.nix
./flake.lock
./nix
]);
};
in {
packages = forAllSystems (system: pkgs: with pkgs; {
default = self.packages.${system}.heimdal;
src = pkgs.runCommand "heimdal-src" {} "ln -s ${src} \"$out\"";
heimdal = pkgs.callPackage ./nix/heimdal/package.nix {
inherit src;
heimdal = pkgs.callPackage ./nix/heimdal {
src = lib.cleanSource ./.;
inherit (pkgs.darwin.apple_sdk.frameworks) CoreFoundation Security SystemConfiguration;
autoreconfHook = pkgs.buildPackages.autoreconfHook271;
autoreconfHook = pkgs.buildPackages.autoreconfHook269;
};
nixosTest = pkgs.testers.runNixOSTest (import ./nix/nixosTest.nix { inherit nixpkgs; });
+2 -3
View File
@@ -9,11 +9,9 @@ CHECK_LOCAL = no-check-local
AM_CPPFLAGS += -DHOST=\"$(CANONICAL_HOST)\"
include_HEADERS = heim_threads.h
nodist_include_HEADERS = krb5-types.h
noinst_HEADERS = heimqueue.h crypto-headers.h
noinst_HEADERS = heimqueue.h heim_threads.h crypto-headers.h
EXTRA_DIST = NTMakefile krb5-types.cross config.h.w32
@@ -50,6 +48,7 @@ CLEANFILES = \
der.h \
digest_asn1.h \
digest_template_asn1.h \
editline.h \
err.h \
getarg.h \
glob.h \
+1 -1
View File
@@ -54,7 +54,7 @@ kadmind_SOURCES = \
add_random_users_SOURCES = add-random-users.c
test_util_SOURCES = test_util.c util.c random_password.c
test_util_SOURCES = test_util.c util.c
TESTS = test_util
+7
View File
@@ -35,6 +35,9 @@
#ifdef HAVE_SYS_WAIT_H
#include <sys/wait.h>
#endif
#ifdef HAVE_SYSTEMD
#include <systemd/sd-daemon.h>
#endif
extern int daemon_child;
@@ -304,6 +307,10 @@ start_server(krb5_context contextp, const char *port_str)
krb5_errx(contextp, 1, "no sockets to listen to - exiting");
roken_detach_finish(NULL, daemon_child);
#ifdef HAVE_SYSTEMD
if (getenv("NOTIFY_SOCKET") != NULL)
sd_notify(0, "READY=1");
#endif
wait_for_connection(contextp, socks, num_socks);
free(socks);
+120 -19
View File
@@ -32,30 +32,131 @@
*/
#include "kadmin_locl.h"
#include <base64.h>
#define RANDOM_PASSWORD_BYTES 12
/* This file defines some a function that generates a random password,
that can be used when creating a large amount of principals (such
as for a batch of students). Since this is a political matter, you
should think about how secure generated passwords has to be.
Both methods defined here will give you at least 55 bits of
entropy.
*/
/* If you want OTP-style passwords, define OTP_STYLE */
#ifdef OTP_STYLE
#include <otp.h>
#else
static void generate_password(char **pw, int num_classes, ...);
#endif
void
random_password(char *pw, size_t len)
{
unsigned char random[RANDOM_PASSWORD_BYTES];
char *password = NULL;
size_t password_len;
#ifdef OTP_STYLE
{
OtpKey newkey;
if (len == 0)
return;
krb5_generate_random_block(random, sizeof(random));
if (rk_base64url_encode(random, sizeof(random), &password) < 0 ||
password == NULL) {
memset_s(random, sizeof(random), 0, sizeof(random));
krb5_abortx(NULL, "Failed to encode random password");
krb5_generate_random_block(&newkey, sizeof(newkey));
otp_print_stddict (newkey, pw, len);
strlwr(pw);
}
password_len = strlen(password);
strlcpy(pw, password, len);
memset_s(random, sizeof(random), 0, sizeof(random));
memset_s(password, password_len, 0, password_len);
free(password);
#else
char *pass;
generate_password(&pass, 3,
"abcdefghijklmnopqrstuvwxyz", 7,
"ABCDEFGHIJKLMNOPQRSTUVWXYZ", 2,
"@$%&*()-+=:,/<>1234567890", 1);
strlcpy(pw, pass, len);
len = strlen(pass);
memset_s(pass, len, 0, len);
free(pass);
#endif
}
/* some helper functions */
#ifndef OTP_STYLE
/* return a random value in range 0-127 */
static int
RND(unsigned char *key, int keylen, int *left)
{
if(*left == 0){
krb5_generate_random_block(key, keylen);
*left = keylen;
}
(*left)--;
return ((unsigned char*)key)[*left];
}
/* This a helper function that generates a random password with a
number of characters from a set of character classes.
If there are n classes, and the size of each class is Pi, and the
number of characters from each class is Ni, the number of possible
passwords are (given that the character classes are disjoint):
n n
----- / ---- \
| | Ni | \ |
| | Pi | \ Ni| !
| | ---- * | / |
| | Ni! | /___ |
i=1 \ i=1 /
Since it uses the RND function above, neither the size of each
class, nor the total length of the generated password should be
larger than 127 (without fixing RND).
*/
static void
generate_password(char **pw, int num_classes, ...)
{
struct {
const char *str;
int len;
int freq;
} *classes;
va_list ap;
int len, i;
unsigned char rbuf[8]; /* random buffer */
int rleft = 0;
*pw = NULL;
classes = malloc(num_classes * sizeof(*classes));
if(classes == NULL)
return;
va_start(ap, num_classes);
len = 0;
for(i = 0; i < num_classes; i++){
classes[i].str = va_arg(ap, const char*);
classes[i].len = strlen(classes[i].str);
classes[i].freq = va_arg(ap, int);
len += classes[i].freq;
}
va_end(ap);
*pw = malloc(len + 1);
if(*pw == NULL) {
free(classes);
return;
}
for(i = 0; i < len; i++) {
int j;
int x = RND(rbuf, sizeof(rbuf), &rleft) % (len - i);
int t = 0;
for(j = 0; j < num_classes; j++) {
if(x < t + classes[j].freq) {
(*pw)[i] = classes[j].str[RND(rbuf, sizeof(rbuf), &rleft)
% classes[j].len];
classes[j].freq--;
break;
}
t += classes[j].freq;
}
}
(*pw)[len] = '\0';
memset_s(rbuf, sizeof(rbuf), 0, sizeof(rbuf));
free(classes);
}
#endif
+1 -44
View File
@@ -68,49 +68,6 @@ test_time(void)
return errors;
}
static int
test_random_password(void)
{
static const char alphabet[] =
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_";
char pw[128];
char small[5];
char zero[1] = { 'x' };
size_t i, j;
int errors = 0;
for (i = 0; i < 128; i++) {
random_password(pw, sizeof(pw));
if (strlen(pw) != 16) {
printf("wrong random password length: %lu\n",
(unsigned long)strlen(pw));
errors++;
}
for (j = 0; pw[j] != '\0'; j++) {
if (strchr(alphabet, pw[j]) == NULL) {
printf("random password contains invalid byte: 0x%02x\n",
(unsigned char)pw[j]);
errors++;
}
}
}
random_password(small, sizeof(small));
if (strlen(small) != sizeof(small) - 1) {
printf("wrong short random password length: %lu\n",
(unsigned long)strlen(small));
errors++;
}
random_password(zero, 0);
if (zero[0] != 'x') {
printf("zero-length random password buffer was modified\n");
errors++;
}
return errors;
}
int
main(int argc, char **argv)
@@ -125,9 +82,9 @@ main(int argc, char **argv)
ret = 0;
ret += test_time();
ret += test_random_password();
krb5_free_context(context);
return ret;
}
+2 -2
View File
@@ -4,7 +4,7 @@ include $(top_srcdir)/Makefile.am.common
WFLAGS += $(WFLAGS_ENUM_CONV)
AM_CPPFLAGS += $(INCLUDE_libintl) $(INCLUDE_openssl_crypto) -I$(srcdir)/../lib/krb5
AM_CPPFLAGS += $(INCLUDE_libintl) $(INCLUDE_openssl_crypto) -I$(srcdir)/../lib/krb5 $(SYSTEMD_CFLAGS)
lib_LTLIBRARIES = ipc_csr_authorizer.la \
libkdc.la
@@ -174,7 +174,7 @@ hpropd_LDADD = \
$(LIB_kdb) \
$(top_builddir)/lib/asn1/libasn1.la \
$(LIB_roken) \
$(DB3LIB) $(DB1LIB) $(LMDBLIB) $(NDBMLIB)
$(DB3LIB) $(DB1LIB) $(LMDBLIB) $(NDBMLIB) $(SYSTEMD_LIBS)
if PKINIT
LIB_pkinit = $(top_builddir)/lib/hx509/libhx509.la
+9
View File
@@ -32,6 +32,9 @@
*/
#include "kdc_locl.h"
#ifdef HAVE_SYSTEMD
#include <systemd/sd-daemon.h>
#endif
/*
* a tuple describing on what to listen
@@ -1208,6 +1211,12 @@ start_kdc(krb5_context context,
#endif
roken_detach_finish(NULL, daemon_child);
#ifdef HAVE_SYSTEMD
/* If built with systemd support and running under systemd, notify readiness.
We check NOTIFY_SOCKET to avoid unnecessary calls when not under systemd. */
if (getenv("NOTIFY_SOCKET") != NULL)
sd_notify(0, "READY=1");
#endif
#ifdef HAVE_FORK
if (!testing_flag) {
+4 -6
View File
@@ -460,7 +460,6 @@ fast_unwrap_request(astgs_request_t r,
char *armor_client_principal_name = NULL;
char *armor_server_principal_name = NULL;
PA_FX_FAST_REQUEST fxreq;
krb5_auth_context free_ac = NULL;
krb5_auth_context ac = NULL;
krb5_ticket *ticket = NULL;
krb5_flags ap_req_options;
@@ -582,7 +581,7 @@ fast_unwrap_request(astgs_request_t r,
goto out;
}
ret = krb5_verify_ap_req2(r->context, &free_ac,
ret = krb5_verify_ap_req2(r->context, &ac,
&ap_req,
armor_server_principal,
&r->armor_key->key,
@@ -594,8 +593,6 @@ fast_unwrap_request(astgs_request_t r,
if (ret)
goto out;
ac = free_ac;
ret = krb5_unparse_name(r->context, armor_server_principal,
&armor_server_principal_name);
if (ret)
@@ -624,6 +621,7 @@ fast_unwrap_request(astgs_request_t r,
"<out of memory>");
if (ac->remote_subkey == NULL) {
krb5_auth_con_free(r->context, ac);
kdc_log(r->context, r->config, 2,
"FAST AP-REQ remote subkey missing");
ret = KRB5KDC_ERR_PREAUTH_FAILED;
@@ -749,8 +747,8 @@ fast_unwrap_request(astgs_request_t r,
kdc_log(r->context, r->config, 5, "Client selected FAST");
out:
if (free_ac)
krb5_auth_con_free(r->context, free_ac);
if (ac && ac != tgs_ac)
krb5_auth_con_free(r->context, ac);
krb5_free_principal(r->context, armor_server_principal);
krb5_xfree(armor_client_principal_name);
+8
View File
@@ -32,6 +32,9 @@
*/
#include "hprop.h"
#ifdef HAVE_SYSTEMD
#include <systemd/sd-daemon.h>
#endif
static int inetd_flag = -1;
static int help_flag;
@@ -156,6 +159,11 @@ main(int argc, char **argv)
mini_inetd (krb5_getportbyname (context, "hprop", "tcp",
HPROP_PORT), &sock);
}
#ifdef HAVE_SYSTEMD
/* Notify systemd that the service is ready when running standalone */
if (getenv("NOTIFY_SOCKET") != NULL)
sd_notify(0, "READY=1");
#endif
socket_set_keepalive(sock, 1);
sin_len = sizeof(ss);
if (getpeername(sock, sa, &sin_len) < 0)
+1 -28
View File
@@ -51,7 +51,7 @@ static const char *kdc_plugin_deps[] = {
static struct heim_plugin_data kdc_plugin_data = {
"krb5",
"kdc",
KRB5_PLUGIN_KDC_VERSION_11,
KRB5_PLUGIN_KDC_VERSION_10,
kdc_plugin_deps,
kdc_get_instance
};
@@ -239,33 +239,6 @@ _kdc_referral_policy(astgs_request_t r)
return ret;
}
static krb5_error_code KRB5_LIB_CALL
hwauth_policy(krb5_context context, const void *plug, void *plugctx, void *userctx)
{
const krb5plugin_kdc_ftable *ft = plug;
if (ft->hwauth_policy == NULL) {
return KRB5_PLUGIN_NO_HANDLE;
}
return ft->hwauth_policy(rk_UNCONST(plug), userctx);
}
krb5_error_code
_kdc_hwauth_policy(astgs_request_t r)
{
krb5_error_code ret = KRB5_PLUGIN_NO_HANDLE;
if (have_plugin) {
ret = _krb5_plugin_run_f(r->context, &kdc_plugin_data, 0, r, hwauth_policy);
}
if (ret != KRB5_PLUGIN_NO_HANDLE) {
return ret;
}
return r->client->flags.require_hwauth ? KRB5KDC_ERR_POLICY : 0;
}
static krb5_error_code KRB5_LIB_CALL
finalize_reply(krb5_context context, const void *plug, void *plugctx, void *userctx)
{
+1 -12
View File
@@ -95,16 +95,6 @@ typedef krb5_error_code
typedef krb5_error_code
(KRB5_CALLCONV *krb5plugin_kdc_referral_policy)(void *, astgs_request_t);
/*
* A hardware authentication policy plugin can indicate what is to
* happen when a client authenticates using a method other than
* hardware authentication. It can return zero to allow the
* authentication, or an appropriate error code to deny it.
*/
typedef krb5_error_code
(KRB5_CALLCONV *krb5plugin_kdc_hwauth_policy)(void *, astgs_request_t);
/*
* Update the AS or TGS reply immediately prior to encoding.
*/
@@ -127,7 +117,7 @@ typedef krb5_error_code
* Plugins should carefully check API contract notes for changes
* between plugin API versions.
*/
#define KRB5_PLUGIN_KDC_VERSION_11 11
#define KRB5_PLUGIN_KDC_VERSION_10 10
typedef struct krb5plugin_kdc_ftable {
HEIM_PLUGIN_FTABLE_COMMON_ELEMENTS(krb5_context);
@@ -135,7 +125,6 @@ typedef struct krb5plugin_kdc_ftable {
krb5plugin_kdc_pac_verify pac_verify;
krb5plugin_kdc_client_access client_access;
krb5plugin_kdc_referral_policy referral_policy;
krb5plugin_kdc_hwauth_policy hwauth_policy;
krb5plugin_kdc_finalize_reply finalize_reply;
krb5plugin_kdc_audit audit;
} krb5plugin_kdc_ftable;
+1 -1
View File
@@ -228,5 +228,5 @@ There should be a way to specify protocol, port, and address triplets,
not just addresses and protocol, port tuples.
.Sh SEE ALSO
.Xr kinit 1 ,
.Xr krb5.conf 5 ,
.Xr krb5.conf 5,
.Xr getservbyname 3
+13 -19
View File
@@ -37,15 +37,16 @@
#if SIZEOF_TIME_T == 4
#define MAX_TIME ((time_t)INT32_MAX)
#elif SIZEOF_TIME_T == 8
#define MAX_TIME ((time_t)INT64_MAX)
#define MAX_TIME ((time_t)INT32_MAX)
#else
#error "Unexpected sizeof(time_t)"
#endif
#else
#if SIZEOF_TIME_T == 4
#define MAX_TIME ((time_t)UINT32_MAX)
#define MAX_TIME ((time_t)INT32_MAX)
#else
#define MAX_TIME ((time_t)UINT64_MAX)
#define MAX_TIME ((time_t)INT32_MAX)
#endif
#endif
@@ -535,11 +536,7 @@ pa_pkinit_validate(astgs_request_t r, const PA_DATA *pa)
ret = _kdc_pk_rd_padata(r, pa, &pkp);
if (ret || pkp == NULL) {
if (ret == KRB5_KDC_ERR_REVOKED_CERTIFICATE) {
ret = KRB5_KDC_ERR_CLIENT_NOT_TRUSTED;
} else {
ret = KRB5KRB_AP_ERR_BAD_INTEGRITY;
}
ret = KRB5KRB_AP_ERR_BAD_INTEGRITY;
_kdc_r_log(r, 4, "Failed to decode PKINIT PA-DATA -- %s",
r->cname);
goto out;
@@ -938,9 +935,6 @@ pa_enc_ts_validate(astgs_request_t r, const PA_DATA *pa)
goto out;
}
free_EncryptedData(&enc_data);
if (ret) {
goto out;
}
ret = decode_PA_ENC_TS_ENC(ts_data.data,
ts_data.length,
&p,
@@ -952,7 +946,7 @@ pa_enc_ts_validate(astgs_request_t r, const PA_DATA *pa)
r->cname);
goto out;
}
if (krb5_time_abs(kdc_time, p.patimestamp) > r->context->max_skew) {
if (labs(kdc_time - p.patimestamp) > r->context->max_skew) {
char client_time[100];
krb5_format_time(r->context, p.patimestamp,
@@ -962,7 +956,7 @@ pa_enc_ts_validate(astgs_request_t r, const PA_DATA *pa)
_kdc_r_log(r, 4, "Too large time skew, "
"client time %s is out by %u > %u seconds -- %s",
client_time,
(unsigned)krb5_time_abs(kdc_time, p.patimestamp),
(unsigned)labs(kdc_time - p.patimestamp),
r->context->max_skew,
r->cname);
kdc_audit_setkv_number((kdc_request_t)r, KDC_REQUEST_KV_AUTH_EVENT,
@@ -2269,12 +2263,12 @@ _kdc_as_rep(astgs_request_t r)
ret = KRB5KDC_ERR_C_PRINCIPAL_UNKNOWN;
goto out;
}
if (!(pat[n].flags & PA_HARDWARE_AUTH)) {
ret = _kdc_hwauth_policy(r);
if (ret) {
kdc_log(r->context, config, 4, "Hardware authentication required for %s", r->cname);
goto out;
}
if (r->client->flags.require_hwauth &&
!(pat[n].flags & PA_HARDWARE_AUTH)) {
kdc_log(r->context, config, 4, "Hardware authentication required for %s", r->cname);
ret = KRB5KDC_ERR_POLICY;
goto out;
}
kdc_audit_addkv((kdc_request_t)r, KDC_AUDIT_VIS, "pa", "%s",
pat[n].name);
+19 -12
View File
@@ -399,6 +399,7 @@ mk_error_response(krb5_context context,
Kx509Response rep;
const char *msg;
char *freeme0 = NULL;
char *freeme1 = NULL;
va_list ap;
if (code != 0) {
@@ -416,6 +417,9 @@ mk_error_response(krb5_context context,
va_end(ap);
}
if (!reqctx->config->enable_kx509)
code = KRB5KDC_ERR_POLICY;
/* Make sure we only send RFC4120 and friends wire protocol error codes */
if (code) {
if (code == KX509_ERR_NONE) {
@@ -437,6 +441,12 @@ mk_error_response(krb5_context context,
msg = freeme0;
va_end(ap);
if (!reqctx->config->enable_kx509 &&
asprintf(&freeme1, "kx509 service is disabled (%s)", msg) > -1 &&
freeme1 != NULL) {
msg = freeme1;
}
rep.hash = NULL;
rep.certificate = NULL;
rep.error_code = code;
@@ -458,6 +468,7 @@ mk_error_response(krb5_context context,
free(rep.e_text);
free(rep.hash);
free(freeme0);
free(freeme1);
return ret;
}
@@ -889,15 +900,14 @@ _kdc_do_kx509(kx509_req_context r)
if (r->req.authenticator.length == 0) {
/*
* Unauthenticated kx509 service availability probe.
*
* mk_error_response() will check whether the service is enabled and
* possibly change the error code and message.
*/
is_probe = 1;
kdc_audit_addkv((kdc_request_t)r, 0, "probe", "unauthenticated");
if (!r->config->enable_kx509)
ret = mk_error_response(r->context, r, 4, KRB5KDC_ERR_POLICY,
"kx509 service is disabled");
else
ret = mk_error_response(r->context, r, 4, 0,
"kx509 service is available");
ret = mk_error_response(r->context, r, 4, 0,
"kx509 service is available");
goto out;
}
@@ -928,12 +938,6 @@ _kdc_do_kx509(kx509_req_context r)
* Provided we got the session key, errors past this point will be
* authenticated.
*/
if (ret == 0 && !r->config->enable_kx509) {
ret = mk_error_response(r->context, r, 4, KRB5KDC_ERR_POLICY,
"kx509 service is disabled");
goto out;
}
if (ret == 0)
ret = krb5_ticket_get_client(r->context, ticket, &cprincipal);
@@ -979,6 +983,9 @@ _kdc_do_kx509(kx509_req_context r)
if (r->req.pk_key.length == 0) {
/*
* The request is an authenticated kx509 service availability probe.
*
* mk_error_response() will check whether the service is enabled and
* possibly change the error code and message.
*/
is_probe = 1;
kdc_audit_addkv((kdc_request_t)r, 0, "probe", "authenticated");
+2 -4
View File
@@ -432,7 +432,7 @@ pk_check_pkauthenticator_win2k(krb5_context context,
krb5_timeofday (context, &now);
/* XXX cusec */
if (a->ctime == 0 || krb5_time_abs(a->ctime, now) > context->max_skew) {
if (a->ctime == 0 || labs(a->ctime - now) > context->max_skew) {
krb5_clear_error_message(context);
return KRB5KRB_AP_ERR_SKEW;
}
@@ -451,7 +451,7 @@ pk_check_pkauthenticator(krb5_context context,
krb5_timeofday (context, &now);
/* XXX cusec */
if (a->ctime == 0 || krb5_time_abs(a->ctime, now) > context->max_skew) {
if (a->ctime == 0 || labs(a->ctime - now) > context->max_skew) {
krb5_clear_error_message(context);
return KRB5KRB_AP_ERR_SKEW;
}
@@ -797,8 +797,6 @@ _kdc_pk_rd_padata(astgs_request_t priv,
hx509_verify_attach_anchors(cp->verify_ctx, trust_anchors);
hx509_certs_free(&trust_anchors);
hx509_verify_attach_revoke(cp->verify_ctx, kdc_identity->revokectx);
if (config->pkinit_allow_proxy_certs)
hx509_verify_set_proxy_certificate(cp->verify_ctx, 1);
+8
View File
@@ -744,6 +744,14 @@ doit(krb5_keytab keytab, int port)
krb5_errx(context, 1, "No sockets!");
roken_detach_finish(NULL, daemon_child);
#ifdef HAVE_SYSTEMD
/* If built with systemd support and running under systemd, notify readiness.
We check NOTIFY_SOCKET to avoid unnecessary calls when not under systemd. */
if (getenv("NOTIFY_SOCKET") != NULL) {
extern int sd_notify(int, const char *);
(void) sd_notify(0, "READY=1");
}
#endif
while (exit_flag == 0) {
krb5_ssize_t retx;
+2 -4
View File
@@ -1104,8 +1104,7 @@ get_new_tickets(krb5_context context,
}
if (ticket_life != 0) {
if (krb5_time_abs(cred.times.endtime - cred.times.starttime,
ticket_life) > 30) {
if (labs(cred.times.endtime - cred.times.starttime - ticket_life) > 30) {
char life[64];
unparse_time_approx(cred.times.endtime - cred.times.starttime,
life, sizeof(life));
@@ -1113,8 +1112,7 @@ get_new_tickets(krb5_context context,
}
}
if (renew_life) {
if (krb5_time_abs(cred.times.renew_till - cred.times.starttime,
renew) > 30) {
if (labs(cred.times.renew_till - cred.times.starttime - renew) > 30) {
char life[64];
unparse_time_approx(cred.times.renew_till - cred.times.starttime,
life, sizeof(life));
+4
View File
@@ -1,5 +1,8 @@
include $(top_srcdir)/Makefile.am.common
if LIBEDIT
dir_editline = libedit
endif
if DCE
dir_dce = kdfs
endif
@@ -18,6 +21,7 @@ SUBDIRS = \
vers \
$(dir_com_err) \
base \
$(dir_editline) \
sl \
wind \
asn1 \
+1 -3
View File
@@ -97,10 +97,8 @@ der_print_hex_heim_integer (const heim_integer *data, char **p)
if (data->negative) {
len = asprintf(&q, "-%s", *p);
free(*p);
if (len < 0) {
*p = NULL;
if (len < 0)
return ENOMEM;
}
*p = q;
}
return 0;
-3
View File
@@ -191,7 +191,6 @@ init_generate (const char *filename, const char *base)
fprintf (headerfile,
"#include <stddef.h>\n"
"#include <stdint.h>\n"
"#include <errno.h>\n"
"#include <time.h>\n\n");
fprintf (headerfile,
"#ifndef __asn1_common_definitions__\n"
@@ -600,8 +599,6 @@ generate_constant (const Symbol *s)
/* header file */
gen_upper = strdup(s->gen_name);
if (gen_upper == NULL)
errx(1, "malloc");
len = strlen(gen_upper);
for (i = 0; i < len; i++)
gen_upper[i] = toupper((unsigned char)s->gen_name[i]);
-6
View File
@@ -289,11 +289,7 @@ static struct tlist *
tlist_new(const char *name)
{
struct tlist *tl = calloc(1, sizeof(*tl));
if (tl == NULL)
errx(1, "malloc");
tl->name = strdup(name);
if (tl->name == NULL)
errx(1, "malloc");
HEIM_TAILQ_INIT(&tl->template);
return tl;
}
@@ -425,8 +421,6 @@ add_line(struct templatehead *t, const char *fmt, ...)
{
struct template *q = calloc(1, sizeof(*q));
va_list ap;
if (q == NULL)
errx(1, "malloc");
va_start(ap, fmt);
if (vasprintf(&q->line, fmt, ap) < 0 || q->line == NULL)
errx(1, "malloc");
+14 -22
View File
@@ -38,26 +38,12 @@
#include <vis.h>
#include <vis-extras.h>
#include <heimbase.h>
#include <errno.h>
#ifndef ENOTSUP
/* Very old MSVC CRTs don't have ENOTSUP */
#define ENOTSUP EINVAL
#endif
static int
int32_ptr_equal(int32_t i, const void *ptr)
{
const intptr_t v = (intptr_t)ptr;
#if INTPTR_MAX > INT32_MAX || INTPTR_MIN < INT32_MIN
if (v > INT32_MAX || v < INT32_MIN)
return 0;
#endif
return i == (int32_t)v;
}
struct asn1_type_func asn1_template_prim[A1T_NUM_ENTRY] = {
#define el(name, type) { \
(asn1_type_encode)der_put_##name, \
@@ -1507,7 +1493,9 @@ _asn1_encode(const struct asn1_template *t, unsigned char *p, size_t len, const
} else if (tdefval->tt & A1_DV_INTEGER32) {
const int32_t *i = el;
if (int32_ptr_equal(*i, tdefval->ptr))
if ((int64_t)(intptr_t)tdefval->ptr <= INT_MAX &&
(int64_t)(intptr_t)tdefval->ptr >= INT_MIN &&
*i == (int32_t)(intptr_t)tdefval->ptr)
break;
} else if (tdefval->tt & A1_DV_INTEGER) {
const struct heim_integer *i = el;
@@ -1579,7 +1567,9 @@ _asn1_encode(const struct asn1_template *t, unsigned char *p, size_t len, const
} else if (tdefval->tt & A1_DV_INTEGER32) {
const int32_t *i = data;
if (int32_ptr_equal(*i, tdefval->ptr))
if ((int64_t)(intptr_t)tdefval->ptr <= INT_MAX &&
(int64_t)(intptr_t)tdefval->ptr >= INT_MIN &&
*i == (int32_t)(intptr_t)tdefval->ptr)
exclude = 1;
} else if (tdefval->tt & A1_DV_INTEGER) {
const struct heim_integer *i = data;
@@ -2082,7 +2072,9 @@ _asn1_length(const struct asn1_template *t, const void *data)
} else if (tdefval->tt & A1_DV_INTEGER32) {
const int32_t *i = el;
if (int32_ptr_equal(*i, tdefval->ptr))
if ((int64_t)(intptr_t)tdefval->ptr <= INT_MAX &&
(int64_t)(intptr_t)tdefval->ptr >= INT_MIN &&
*i == (int32_t)(intptr_t)tdefval->ptr)
break;
} else if (tdefval->tt & A1_DV_INTEGER) {
const struct heim_integer *i = el;
@@ -2139,7 +2131,9 @@ _asn1_length(const struct asn1_template *t, const void *data)
} else if (tdefval->tt & A1_DV_INTEGER32) {
const int32_t *i = data;
if (int32_ptr_equal(*i, tdefval->ptr))
if ((int64_t)(intptr_t)tdefval->ptr <= INT_MAX &&
(int64_t)(intptr_t)tdefval->ptr >= INT_MIN &&
*i == (int32_t)(intptr_t)tdefval->ptr)
exclude = 1;
} else if (tdefval->tt & A1_DV_INTEGER) {
const struct heim_integer *i = data;
@@ -2489,10 +2483,8 @@ _asn1_print_open_type(const struct asn1_template *t, /* object set template */
}
if (!(t->tt & A1_OS_OT_IS_ARRAY)) {
size_t offset = t->offset + sizeof(*elementp);
offset += (sizeof(void *) - offset % sizeof(void *)) % sizeof(void *);
dp = DPOC(data, offset);
unsigned align = 8 - ((t->offset + sizeof(*elementp)) & 0x7);
dp = DPOC(data, t->offset + sizeof(*elementp) + align);
if (*dp) {
struct rk_strpool *r2 = NULL;
char *s = NULL;
+2 -17
View File
@@ -46,21 +46,6 @@ static const unsigned ndays[2][12] ={
{31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31},
{31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}};
static time_t
_clamp_time_t(uint64_t t)
{
#if SIZEOF_TIME_T < 8
#ifdef TIME_T_UNSIGNED
#define MAX_TIME ((UINT64_C(1) << (SIZEOF_TIME_T * 8)) - 1)
#else
#define MAX_TIME ((UINT64_C(1) << ((SIZEOF_TIME_T * 8) - 1)) - 1)
#endif
return t < MAX_TIME ? t : MAX_TIME;
#else
return t;
#endif
}
/*
* This is a simplifed version of timegm(3) that doesn't accept out of
* bound values that timegm(3) normally accepts but those are not
@@ -70,7 +55,7 @@ _clamp_time_t(uint64_t t)
time_t
_der_timegm (struct tm *tm)
{
uint64_t res = 0;
time_t res = 0;
int i;
/*
@@ -104,7 +89,7 @@ _der_timegm (struct tm *tm)
res += tm->tm_min;
res *= 60;
res += tm->tm_sec;
return _clamp_time_t(res);
return res;
}
struct tm *
+3 -23
View File
@@ -86,26 +86,6 @@ static heim_error_code parse_list(struct fileptr *f, unsigned *lineno,
heim_config_binding **parent,
const char **err_message);
static int
todash(int c)
{
if (c == '_')
return '-';
return c;
}
static int
strcmp_du(const char *s1, const char *s2)
{
while (todash((unsigned char)*s1) == todash((unsigned char)*s2)) {
if (*s1 == '\0')
return 0;
s1++;
s2++;
}
return todash((unsigned char)*s1) - todash((unsigned char)*s2);
}
heim_config_section *
heim_config_get_entry(heim_config_section **parent, const char *name, int type)
{
@@ -114,7 +94,7 @@ heim_config_get_entry(heim_config_section **parent, const char *name, int type)
for (q = parent; *q != NULL; q = &(*q)->next)
if (type == heim_config_list &&
(unsigned)type == (*q)->type &&
strcmp_du(name, (*q)->name) == 0)
strcmp(name, (*q)->name) == 0)
return *q;
*q = calloc(1, sizeof(**q));
if (*q == NULL)
@@ -808,7 +788,7 @@ vget_next(heim_context context,
const char *p = va_arg(args, const char *);
while (b != NULL) {
if (strcmp_du(b->name, name) == 0) {
if (strcmp(b->name, name) == 0) {
if (b->type == (unsigned)type && p == NULL) {
*pointer = b;
return b->u.generic;
@@ -846,7 +826,7 @@ heim_config_vget_next(heim_context context,
/* we were called again, so just look for more entries with the
same name and type */
for (b = (*pointer)->next; b != NULL; b = b->next) {
if(strcmp_du(b->name, (*pointer)->name) == 0 && b->type == (unsigned)type) {
if(strcmp(b->name, (*pointer)->name) == 0 && b->type == (unsigned)type) {
*pointer = b;
return b->u.generic;
}
+9 -28
View File
@@ -355,12 +355,11 @@ open_file(heim_context context, heim_log_facility *fac, int min, int max,
return ret;
}
static heim_error_code
addlog_dest(heim_context context, heim_log_facility *f,
const char *orig, int default_min, int default_max)
heim_error_code
heim_addlog_dest(heim_context context, heim_log_facility *f, const char *orig)
{
heim_error_code ret = 0;
int min = default_min, max = default_max, n;
int min = 0, max = 3, n;
char c;
const char *p = orig;
#ifdef _WIN32
@@ -394,6 +393,8 @@ addlog_dest(heim_context context, heim_log_facility *f,
return HEIM_ERR_LOG_PARSE;
}
p++;
} else {
max = 5;
}
if (strcmp(p, "STDERR") == 0) {
ret = open_file(context, f, min, max, NULL, "a", stderr,
@@ -444,12 +445,6 @@ addlog_dest(heim_context context, heim_log_facility *f,
return ret;
}
heim_error_code
heim_addlog_dest(heim_context context, heim_log_facility *f, const char *orig)
{
return addlog_dest(context, f, orig, 0, 5);
}
heim_error_code
heim_openlog(heim_context context,
const char *program,
@@ -653,9 +648,9 @@ heim_add_warn_dest(heim_context context, const char *program,
return 0;
}
static heim_error_code
add_debug_dest(heim_context context, const char *program,
const char *log_spec, int default_min, int default_max)
heim_error_code
heim_add_debug_dest(heim_context context, const char *program,
const char *log_spec)
{
heim_log_facility *fac;
heim_error_code ret;
@@ -667,26 +662,12 @@ add_debug_dest(heim_context context, const char *program,
heim_set_debug_dest(context, fac);
}
ret = addlog_dest(context, fac, log_spec, default_min, default_max);
ret = heim_addlog_dest(context, fac, log_spec);
if (ret)
return ret;
return 0;
}
heim_error_code
heim_add_debug_dest(heim_context context, const char *program,
const char *log_spec)
{
return add_debug_dest(context, program, log_spec, 0, 5);
}
heim_error_code
heim_add_trace_dest(heim_context context, const char *program,
const char *log_spec)
{
return add_debug_dest(context, program, log_spec, 0, -1);
}
struct heim_audit_kv_tuple {
heim_string_t key;
heim_object_t value;
-78
View File
@@ -142,83 +142,6 @@ test_rwlock(void)
return 0;
}
static int
file_contains(const char *filename, const char *needle)
{
char buf[1024];
FILE *f;
int found = 0;
f = fopen(filename, "r");
if (f == NULL)
return 0;
while (fgets(buf, sizeof(buf), f) != NULL) {
if (strstr(buf, needle) != NULL) {
found = 1;
break;
}
}
fclose(f);
return found;
}
static int
test_log_dest(void)
{
const char *normal = "test-log-dest.log";
const char *trace = "test-trace-dest.log";
const char *explicit = "test-trace-explicit-dest.log";
heim_log_facility *fac = NULL;
heim_context context;
int ret;
unlink(normal);
unlink(trace);
unlink(explicit);
context = heim_context_init();
heim_assert(context != NULL, "heim_context_init failed");
ret = heim_initlog(context, "test_base", &fac);
heim_assert(ret == 0, "heim_initlog failed");
ret = heim_addlog_dest(context, fac, normal);
heim_assert(ret == 0, "heim_addlog_dest failed");
heim_log(context, fac, 10, "normal level 10");
heim_log(context, fac, 5, "normal level 5");
heim_closelog(context, fac);
heim_assert(!file_contains(normal, "normal level 10"),
"normal log destination traced level 10 by default");
heim_assert(file_contains(normal, "normal level 5"),
"normal log destination did not log level 5 by default");
ret = heim_add_trace_dest(context, "test_base", trace);
heim_assert(ret == 0, "heim_add_trace_dest failed");
ret = heim_add_trace_dest(context, "test_base",
"5/FILE:test-trace-explicit-dest.log");
heim_assert(ret == 0, "heim_add_trace_dest with explicit level failed");
heim_debug(context, 10, "trace level 10");
heim_debug(context, 5, "trace level 5");
heim_assert(file_contains(trace, "trace level 10"),
"trace log destination did not trace level 10 by default");
heim_assert(!file_contains(explicit, "trace level 10"),
"explicit trace destination ignored its level filter");
heim_assert(file_contains(explicit, "trace level 5"),
"explicit trace destination did not log matching level");
heim_context_free(&context);
unlink(normal);
unlink(trace);
unlink(explicit);
return 0;
}
static int
test_dict(void)
{
@@ -1442,7 +1365,6 @@ main(int argc, char **argv)
res |= test_memory();
res |= test_mutex();
res |= test_rwlock();
res |= test_log_dest();
res |= test_dict();
res |= test_auto_release();
res |= test_string();
-1
View File
@@ -10,7 +10,6 @@ HEIMDAL_BASE_1.0 {
heim_abort;
heim_abortv;
heim_add_debug_dest;
heim_add_trace_dest;
heim_add_et_list;
heim_addlog_dest;
heim_addlog_func;
-6
View File
@@ -15,7 +15,6 @@
.Fl r
.Op Fl MNln
.Op Fl C Ar ccache
.Op Fl L Ar localuser
.Op Fl S Ar maxsize
.Op Fl c count
.Op Fl m mech
@@ -36,11 +35,6 @@ write an accepted delegated credential into
This only makes sense if
.Fl r
is specified.
.It Fl L Ar localuser
try to authorize as
.Ar localuser
with
.Fn gss_authorize_localname .
.It Fl D
delegate credentials.
This only makes sense as a client, that is when
+7 -37
View File
@@ -435,13 +435,11 @@ initiate_many(gss_name_t service, int delegate, int negotiate, int memcache,
}
static int
accept_one(gss_name_t service, const char *ccname, const char *localuser,
int negotiate)
accept_one(gss_name_t service, const char *ccname, int negotiate)
{
gss_cred_id_t cred = NULL;
gss_cred_id_t deleg_creds = NULL;
gss_name_t client = GSS_C_NO_NAME;
gss_name_t lname = GSS_C_NO_NAME;
gss_name_t client;
gss_OID mech_oid;
gss_ctx_id_t ctx = GSS_C_NO_CONTEXT;
gss_buffer_desc in = GSS_C_EMPTY_BUFFER;
@@ -497,23 +495,8 @@ accept_one(gss_name_t service, const char *ccname, const char *localuser,
printf("Authenticated: %.*s\n", (int)dname.length,
(char *)dname.value);
(void) gss_release_buffer(&min, &dname);
if (localuser) {
gss_buffer_desc lnamebuf;
lnamebuf.length = strlen(localuser);
lnamebuf.value = rk_UNCONST(localuser);
maj = gss_import_name(&min, &lnamebuf,
GSS_C_NT_USER_NAME, &lname);
GBAIL("gss_import_name", maj, min);
maj = gss_authorize_localname(&min, client, lname);
GBAIL("gss_authorize_localname", maj, min);
if (!nflag)
printf("Authorized: %s\n", localuser);
}
(void) gss_release_name(&min, &client);
(void) gss_delete_sec_context(&min, &ctx, GSS_C_NO_BUFFER);
if (ccname) {
#ifdef HAVE_GSS_STORE_CRED_INTO
@@ -549,12 +532,6 @@ bail:
gss_release_cred(&min, &cred);
if (deleg_creds)
gss_release_cred(&min, &deleg_creds);
if (lname)
gss_release_name(&min, &lname);
if (client)
gss_release_name(&min, &client);
if (ctx != GSS_C_NO_CONTEXT)
gss_delete_sec_context(&min, &ctx, GSS_C_NO_BUFFER);
free(in.value);
@@ -608,8 +585,8 @@ usage(int ecode)
{
FILE *f = ecode == 0 ? stdout : stderr;
fprintf(f, "Usage: gss-token [-DNn] [-c count] service@host\n");
fprintf(f, " gss-token -r [-Nln] [-C ccache] [-L localuser] "
"[-c count] [service@host]\n");
fprintf(f, " gss-token -r [-Nln] [-C ccache] [-c count] "
"[service@host]\n");
exit(ecode);
}
@@ -629,14 +606,12 @@ main(int argc, char **argv)
int ret = 0;
int optidx = 0;
char *ccname = NULL;
char *localuser = NULL;
char *mech = NULL;
struct getargs args[] = {
{ "help", 'h', arg_flag, &hflag, NULL, NULL },
{ "version", 0, arg_flag, &version_flag, NULL, NULL },
{ NULL, 'C', arg_string, &ccname, NULL, NULL },
{ NULL, 'D', arg_flag, &Dflag, NULL, NULL },
{ NULL, 'L', arg_string, &localuser, NULL, NULL },
{ NULL, 'M', arg_flag, &Mflag, NULL, NULL },
{ NULL, 'N', arg_flag, &Nflag, NULL, NULL },
{ NULL, 'S', arg_integer, &Sflag, NULL, NULL },
@@ -687,11 +662,6 @@ main(int argc, char **argv)
"make sense without -r.\n");
usage(1);
}
if (localuser) {
fprintf(stderr, "Specifying a local user doesn't make "
"sense without -r.\n");
usage(1);
}
ret = initiate_many(service, Dflag, Nflag, Mflag, count);
goto done;
}
@@ -703,7 +673,7 @@ main(int argc, char **argv)
}
do {
ret = accept_one(service, ccname, localuser, Nflag);
ret = accept_one(service, ccname, Nflag);
} while (lflag && !ret && !feof(stdin));
done:
+1 -1
View File
@@ -926,7 +926,7 @@ OM_uint32 GSSAPI_CALLCONV _gsskrb5_acquire_cred_from
NULL, time_rec, NULL, actual_mechs);
if (ret != GSS_S_COMPLETE) {
if (handle->mechanisms != NULL)
gss_release_oid_set(minor_status, &handle->mechanisms);
gss_release_oid_set(NULL, &handle->mechanisms);
HEIMDAL_MUTEX_destroy(&handle->cred_id_mutex);
krb5_free_principal(context, handle->principal);
free(handle);
+1 -2
View File
@@ -238,7 +238,6 @@ OM_uint32 GSSAPI_CALLCONV _gsskrb5_add_cred_from (
failure:
if (handle) {
OM_uint32 tmp_status;
if (handle->principal)
krb5_free_principal(context, handle->principal);
if (handle->keytab)
@@ -246,7 +245,7 @@ failure:
if (handle->ccache)
krb5_cc_destroy(context, handle->ccache);
if (handle->mechanisms)
gss_release_oid_set(&tmp_status, &handle->mechanisms);
gss_release_oid_set(NULL, &handle->mechanisms);
free(handle);
}
if (cred && output_cred_handle)
+15 -15
View File
@@ -308,7 +308,7 @@ _gssapi_get_mic_arcfour(OM_uint32 * minor_status,
}
if (EVP_CIPHER_CTX_init(rc4_key) != 1 ||
EVP_CipherInit_ex(rc4_key, context->ossl->rc4, NULL, k6_data, NULL, 1) != 1 ||
EVP_Cipher(rc4_key, p, p, 8) != 8) {
EVP_Cipher(rc4_key, p, p, 8) != 1) {
EVP_CIPHER_CTX_free(rc4_key);
_krb5_debug_openssl(context, 4, "Could not encrypt with RC4 with OpenSSL");
*minor_status = KRB5_CRYPTO_INTERNAL;
@@ -392,7 +392,7 @@ _gssapi_verify_mic_arcfour(OM_uint32 * minor_status,
}
if (EVP_CIPHER_CTX_init(rc4_key) != 1 ||
EVP_CipherInit_ex(rc4_key, context->ossl->rc4, NULL, (void *)k6_data, NULL, 0) != 1 ||
EVP_Cipher(rc4_key, SND_SEQ, p, 8) != 8) {
EVP_Cipher(rc4_key, SND_SEQ, p, 8) != 1) {
_krb5_debug_openssl(context, 4, "Could not encrypt with RC4 with OpenSSL");
*minor_status = KRB5_CRYPTO_INTERNAL;
return GSS_S_FAILURE;
@@ -553,7 +553,7 @@ _gssapi_wrap_arcfour(OM_uint32 * minor_status,
}
if (EVP_CIPHER_CTX_init(rc4_key) != 1 ||
EVP_CipherInit_ex(rc4_key, context->ossl->rc4, NULL, k6_data, NULL, 1) != 1 ||
EVP_Cipher(rc4_key, p0 + 24, p0 + 24, 8 + datalen) != 8 + datalen) {
EVP_Cipher(rc4_key, p0 + 24, p0 + 24, 8 + datalen) != 1) {
EVP_CIPHER_CTX_free(rc4_key);
_krb5_debug_openssl(context, 4, "Could not encrypt with RC4 with OpenSSL");
*minor_status = KRB5_CRYPTO_INTERNAL;
@@ -581,7 +581,7 @@ _gssapi_wrap_arcfour(OM_uint32 * minor_status,
}
if (EVP_CIPHER_CTX_init(rc4_key) != 1 ||
EVP_CipherInit_ex(rc4_key, context->ossl->rc4, NULL, k6_data, NULL, 1) != 1 ||
EVP_Cipher(rc4_key, p0 + 8, p0 + 8 /* SND_SEQ */, 8) != 8) {
EVP_Cipher(rc4_key, p0 + 8, p0 + 8 /* SND_SEQ */, 8) != 1) {
EVP_CIPHER_CTX_free(rc4_key);
_krb5_debug_openssl(context, 4, "Could not encrypt with RC4 with OpenSSL");
*minor_status = KRB5_CRYPTO_INTERNAL;
@@ -690,7 +690,7 @@ OM_uint32 _gssapi_unwrap_arcfour(OM_uint32 *minor_status,
}
if (EVP_CIPHER_CTX_init(rc4_key) != 1 ||
EVP_CipherInit_ex(rc4_key, context->ossl->rc4, NULL, k6_data, NULL, 1) != 1 ||
EVP_Cipher(rc4_key, SND_SEQ, p0 + 8, 8) != 8) {
EVP_Cipher(rc4_key, SND_SEQ, p0 + 8, 8) != 1) {
EVP_CIPHER_CTX_free(rc4_key);
_krb5_debug_openssl(context, 4, "Could not decrypt with RC4 with OpenSSL");
*minor_status = KRB5_CRYPTO_INTERNAL;
@@ -747,8 +747,8 @@ OM_uint32 _gssapi_unwrap_arcfour(OM_uint32 *minor_status,
}
if (EVP_CIPHER_CTX_init(rc4_key) != 1 ||
EVP_CipherInit_ex(rc4_key, context->ossl->rc4, NULL, k6_data, NULL, 1) != 1 ||
EVP_Cipher(rc4_key, Confounder, p0 + 24, 8) != 8 ||
EVP_Cipher(rc4_key, output_message_buffer->value, p0 + GSS_ARCFOUR_WRAP_TOKEN_SIZE, datalen) != datalen) {
EVP_Cipher(rc4_key, Confounder, p0 + 24, 8) != 1 ||
EVP_Cipher(rc4_key, output_message_buffer->value, p0 + GSS_ARCFOUR_WRAP_TOKEN_SIZE, datalen) != 1) {
EVP_CIPHER_CTX_free(rc4_key);
_krb5_debug_openssl(context, 4, "Could not decrypt with RC4 with OpenSSL");
*minor_status = KRB5_CRYPTO_INTERNAL;
@@ -1149,7 +1149,7 @@ _gssapi_wrap_iov_arcfour(OM_uint32 *minor_status,
if (EVP_CIPHER_CTX_init(rc4_key) != 1 ||
EVP_CipherInit_ex(rc4_key, context->ossl->rc4, NULL, k6_data, NULL, 1) != 1 ||
/* Confounder */
EVP_Cipher(rc4_key, p0 + 24, p0 + 24, 8) != 8) {
EVP_Cipher(rc4_key, p0 + 24, p0 + 24, 8) != 1) {
EVP_CIPHER_CTX_free(rc4_key);
_krb5_debug_openssl(context, 4, "Could not encrypt with RC4 with OpenSSL");
*minor_status = KRB5_CRYPTO_INTERNAL;
@@ -1166,7 +1166,7 @@ _gssapi_wrap_iov_arcfour(OM_uint32 *minor_status,
}
if (EVP_Cipher(rc4_key, iov[i].buffer.value,
iov[i].buffer.value, iov[i].buffer.length) != iov[i].buffer.length) {
iov[i].buffer.value, iov[i].buffer.length) != 1) {
EVP_CIPHER_CTX_free(rc4_key);
_krb5_debug_openssl(context, 4, "Could not encrypt with RC4 with OpenSSL");
*minor_status = KRB5_CRYPTO_INTERNAL;
@@ -1177,7 +1177,7 @@ _gssapi_wrap_iov_arcfour(OM_uint32 *minor_status,
/* Padding */
if (padding &&
EVP_Cipher(rc4_key, padding->buffer.value,
padding->buffer.value, padding->buffer.length) != padding->buffer.length) {
padding->buffer.value, padding->buffer.length) != 1) {
EVP_CIPHER_CTX_free(rc4_key);
_krb5_debug_openssl(context, 4, "Could not encrypt with RC4 with OpenSSL");
*minor_status = KRB5_CRYPTO_INTERNAL;
@@ -1206,7 +1206,7 @@ _gssapi_wrap_iov_arcfour(OM_uint32 *minor_status,
}
if (EVP_CIPHER_CTX_init(rc4_key) != 1 ||
EVP_CipherInit_ex(rc4_key, context->ossl->rc4, NULL, k6_data, NULL, 1) != 1 ||
EVP_Cipher(rc4_key, p0 + 8, p0 + 8, 8) != 8 /* SND_SEQ */) {
EVP_Cipher(rc4_key, p0 + 8, p0 + 8, 8) != 1 /* SND_SEQ */) {
EVP_CIPHER_CTX_free(rc4_key);
_krb5_debug_openssl(context, 4, "Could not encrypt with RC4 with OpenSSL");
*minor_status = KRB5_CRYPTO_INTERNAL;
@@ -1357,7 +1357,7 @@ _gssapi_unwrap_iov_arcfour(OM_uint32 *minor_status,
}
if (EVP_CIPHER_CTX_init(rc4_key) != 1 ||
EVP_CipherInit_ex(rc4_key, context->ossl->rc4, NULL, k6_data, NULL, 1) != 1 ||
EVP_Cipher(rc4_key, snd_seq, p0 + 8, 8) != 8 /* SND_SEQ */) {
EVP_Cipher(rc4_key, snd_seq, p0 + 8, 8) != 1 /* SND_SEQ */) {
EVP_CIPHER_CTX_free(rc4_key);
_krb5_debug_openssl(context, 4, "Could not decrypt with RC4 with OpenSSL");
*minor_status = KRB5_CRYPTO_INTERNAL;
@@ -1410,7 +1410,7 @@ _gssapi_unwrap_iov_arcfour(OM_uint32 *minor_status,
if (EVP_CIPHER_CTX_init(rc4_key) != 1 ||
EVP_CipherInit_ex(rc4_key, context->ossl->rc4, NULL, k6_data, NULL, 1) != 1 ||
/* Confounder */
EVP_Cipher(rc4_key, Confounder, p0 + 24, 8) != 8) {
EVP_Cipher(rc4_key, Confounder, p0 + 24, 8) != 1) {
EVP_CIPHER_CTX_free(rc4_key);
_krb5_debug_openssl(context, 4, "Could not decrypt with RC4 with OpenSSL");
*minor_status = KRB5_CRYPTO_INTERNAL;
@@ -1427,7 +1427,7 @@ _gssapi_unwrap_iov_arcfour(OM_uint32 *minor_status,
}
if (EVP_Cipher(rc4_key, iov[i].buffer.value,
iov[i].buffer.value, iov[i].buffer.length) != iov[i].buffer.length) {
iov[i].buffer.value, iov[i].buffer.length) != 1) {
EVP_CIPHER_CTX_free(rc4_key);
_krb5_debug_openssl(context, 4, "Could not decrypt with RC4 with OpenSSL");
*minor_status = KRB5_CRYPTO_INTERNAL;
@@ -1438,7 +1438,7 @@ _gssapi_unwrap_iov_arcfour(OM_uint32 *minor_status,
/* Padding */
if (padding &&
EVP_Cipher(rc4_key, padding->buffer.value,
padding->buffer.value, padding->buffer.length) != padding->buffer.length) {
padding->buffer.value, padding->buffer.length) != 1) {
EVP_CIPHER_CTX_free(rc4_key);
_krb5_debug_openssl(context, 4, "Could not encrypt with RC4 with OpenSSL");
*minor_status = KRB5_CRYPTO_INTERNAL;
+3 -4
View File
@@ -100,12 +100,11 @@ OM_uint32 GSSAPI_CALLCONV _gsskrb5_inquire_context (
return GSS_S_COMPLETE;
failed:
{ OM_uint32 tmp_status;
if (src_name)
_gsskrb5_release_name(&tmp_status, src_name);
_gsskrb5_release_name(NULL, src_name);
if (targ_name)
_gsskrb5_release_name(&tmp_status, targ_name);
}
_gsskrb5_release_name(NULL, targ_name);
HEIMDAL_MUTEX_unlock(&ctx->ctx_id_mutex);
return ret;
}
+1 -2
View File
@@ -40,7 +40,6 @@ OM_uint32 GSSAPI_CALLCONV _gsskrb5_inquire_mechs_for_name (
)
{
OM_uint32 ret;
OM_uint32 tmp_status;
ret = gss_create_empty_oid_set(minor_status, mech_types);
if (ret)
@@ -50,7 +49,7 @@ OM_uint32 GSSAPI_CALLCONV _gsskrb5_inquire_mechs_for_name (
GSS_KRB5_MECHANISM,
mech_types);
if (ret)
gss_release_oid_set(&tmp_status, mech_types);
gss_release_oid_set(NULL, mech_types);
return ret;
}
+1 -2
View File
@@ -48,7 +48,6 @@ OM_uint32 GSSAPI_CALLCONV _gsskrb5_inquire_names_for_mech (
)
{
OM_uint32 ret;
OM_uint32 tmp_status;
int i;
*minor_status = 0;
@@ -72,7 +71,7 @@ OM_uint32 GSSAPI_CALLCONV _gsskrb5_inquire_names_for_mech (
}
if (ret != GSS_S_COMPLETE)
gss_release_oid_set(&tmp_status, name_types);
gss_release_oid_set(NULL, name_types);
return GSS_S_COMPLETE;
}
+2 -19
View File
@@ -83,25 +83,8 @@ set_proc(OM_uint32 *minor, gss_buffer_set_t env)
#ifndef WIN32
size_t i;
for (i = 0; i < env->count; i++) {
char *var = (char *)env->elements[i].value;
char *eq = strchr(var, '=');
char *val;
int e;
if (eq == NULL) {
*minor = EINVAL;
return GSS_S_FAILURE;
}
val = eq + 1;
*eq = '\0';
e = setenv(var, val, 1);
*eq = '=';
if (e != 0) {
*minor = errno ? errno : EINVAL;
return GSS_S_FAILURE;
}
}
for (i = 0; i < env->count; i++)
putenv(env->elements[i].value);
#endif
return GSS_S_COMPLETE;
}
+1 -10
View File
@@ -265,14 +265,12 @@ gss_accept_sec_context(OM_uint32 *minor_status,
*delegated_cred_handle = GSS_C_NO_CREDENTIAL;
_mg_buffer_zero(output_token);
_gss_mg_log(10, "gss-asc: enter ctx=%p", ctx);
if (!*context_handle) {
ctx = calloc(1, sizeof(*ctx));
if (!ctx) {
*minor_status = ENOMEM;
return (GSS_S_DEFECTIVE_TOKEN);
}
_gss_mg_log(10, "gss-asc: allocated ctx=%p", ctx);
*context_handle = (gss_ctx_id_t)ctx;
ctx->gc_initial = 1;
}
@@ -320,9 +318,6 @@ gss_accept_sec_context(OM_uint32 *minor_status,
&mech_ret_flags,
time_rec,
&delegated_mc);
_gss_mg_log(10, "gss-asc: ctx=%p tried \"%s\", "
"returned %u", ctx, m->gm_name,
major_status);
if (major_status == GSS_S_DEFECTIVE_TOKEN) {
/*
* Try to retain and output one error token for
@@ -365,9 +360,6 @@ gss_accept_sec_context(OM_uint32 *minor_status,
&mech_ret_flags,
time_rec,
&delegated_mc);
_gss_mg_log(10, "gss-asc: ctx=%p tried \"%s\", "
"returned %u", ctx, m->gm_name,
major_status);
if (major_status == GSS_S_DEFECTIVE_TOKEN) {
if (output_token->length &&
defective_token_error.length == 0) {
@@ -518,8 +510,7 @@ got_one:
}
}
_gss_mg_log(10, "gss-asc: ctx=%p return %d/%d", ctx,
(int)major_status, (int)*minor_status);
_gss_mg_log(10, "gss-asc: return %d/%d", (int)major_status, (int)*minor_status);
if (ret_flags)
*ret_flags = mech_ret_flags;
-3
View File
@@ -38,7 +38,6 @@ gss_display_name(OM_uint32 *minor_status,
struct _gss_name *name = rk_UNCONST(input_name);
struct _gss_mechanism_name *mn;
_gss_mg_log(10, "gdn: enter gss_display_name: %p", input_name);
_mg_buffer_zero(output_name_buffer);
if (output_name_type)
*output_name_type = GSS_C_NO_OID;
@@ -69,8 +68,6 @@ gss_display_name(OM_uint32 *minor_status,
return (GSS_S_COMPLETE);
} else {
HEIM_TAILQ_FOREACH(mn, &name->gn_mn, gmn_link) {
_gss_mg_log(10, "gdn: trying mech \"%s\"",
mn->gmn_mech->gm_name);
major_status = mn->gmn_mech->gm_display_name(
minor_status, mn->gmn_name,
output_name_buffer,
-34
View File
@@ -28,8 +28,6 @@
#include "mech_locl.h"
#include <vis.h>
static OM_uint32
_gss_import_export_name(OM_uint32 *minor_status,
const gss_buffer_t input_name_buffer,
@@ -46,8 +44,6 @@ _gss_import_export_name(OM_uint32 *minor_status,
gss_name_t new_canonical_name;
int composite = 0;
_gss_mg_log(10, "gin: importing exported name");
*minor_status = 0;
*output_name = 0;
@@ -173,32 +169,6 @@ _gss_import_export_name(OM_uint32 *minor_status,
return (GSS_S_COMPLETE);
}
static void
log_import_name(gss_buffer_t input_name_buffer)
{
char *name;
size_t len;
if (!_gss_mg_log_level(10))
return;
if (input_name_buffer->length > (SIZE_MAX - 1) / 4) {
_gss_mg_log(10, "gin: importing name (%zu bytes)",
input_name_buffer->length);
return;
}
len = input_name_buffer->length * 4 + 1;
name = malloc(len);
if (name == NULL)
return;
strsvisx(name, input_name_buffer->value, input_name_buffer->length,
VIS_CSTYLE | VIS_TAB | VIS_NL, "\"");
_gss_mg_log(10, "gin: importing name \"%s\"", name);
free(name);
}
/**
* Convert a GGS-API name from contiguous string to internal form.
*
@@ -260,7 +230,6 @@ gss_import_name(OM_uint32 *minor_status,
name_type, output_name);
}
log_import_name(input_name_buffer);
*minor_status = 0;
name = _gss_create_name(NULL, NULL);
@@ -293,9 +262,6 @@ gss_import_name(OM_uint32 *minor_status,
HEIM_TAILQ_FOREACH(m, &_gss_mechs, gm_link) {
int present = 0;
_gss_mg_log(10, "gin: attempting mech \"%s\"",
m->gm_mech.gm_name);
if ((m->gm_mech.gm_flags & GM_USE_MG_NAME))
continue;
+2 -5
View File
@@ -167,8 +167,7 @@ do { \
m->gm_mech.gm_ ## name = (_gss_##name##_t *)dlsym(so, "gss_" #name); \
if (!m->gm_mech.gm_ ## name || \
m->gm_mech.gm_ ##name == gss_ ## name) { \
_gss_mg_log(1, "can't find symbol gss_" #name \
" in %s", lib); \
_gss_mg_log(1, "can't find symbol gss_" #name "\n"); \
goto bad; \
} \
} while (0)
@@ -335,11 +334,9 @@ _gss_load_mech(void)
/*
* Check for duplicates, already loaded mechs.
*/
_gss_mg_log(10, "loading \"%s\"", name);
found = 0;
HEIM_TAILQ_FOREACH(m, &_gss_mechs, gm_link) {
if (gss_oid_equal(&m->gm_mech.gm_mech_oid, mech_oid)) {
_gss_mg_log(10, "duplicate mech, not loading");
found = 1;
break;
}
@@ -349,7 +346,7 @@ _gss_load_mech(void)
so = dlopen(lib, RTLD_LAZY | RTLD_LOCAL | RTLD_GROUP);
if (so == NULL) {
_gss_mg_log(1, "dlopen: %s", dlerror());
_gss_mg_log(1, "dlopen: %s\n", dlerror());
goto bad;
}
+21 -168
View File
@@ -99,8 +99,6 @@ static int help_flag = 0;
static int env_flag = 0;
static int def_flag = 0;
static int overwrite_flag = 0;
static int store_cred_flag = 0;
static char *password = NULL;
static struct getargs args[] = {
{"version", 0, arg_flag, &version_flag, "print version", NULL },
@@ -111,133 +109,16 @@ static struct getargs args[] = {
"switch credential store default principal", NULL },
{"overwrite", 0, arg_flag, &overwrite_flag,
"overwrite matching credential", NULL },
{"store-cred", 0, arg_flag, &store_cred_flag,
"use gss_store_cred instead of gss_store_cred_into2", NULL },
{"password", 0, arg_string, &password,
"acquire source credential with this password", "password" },
};
static void
usage(int ret)
{
arg_printusage(args, sizeof(args)/sizeof(*args),
NULL, "from_ccache to_ccache | source_name target_name");
NULL, "from_ccache to_ccache");
exit(ret);
}
static void
add_krb5_mech(gss_OID_set *mechs)
{
OM_uint32 major, minor;
major = gss_create_empty_oid_set(&minor, mechs);
if (major != GSS_S_COMPLETE)
gss_err(1, major, minor, GSS_C_NO_OID,
"failed to create OID set");
major = gss_add_oid_set_member(&minor, GSS_KRB5_MECHANISM, mechs);
if (major != GSS_S_COMPLETE)
gss_err(1, major, minor, GSS_C_NO_OID,
"failed to add krb5 mechanism to OID set");
}
static void
acquire_from_password(const char *source_name,
const char *source_password,
gss_cred_id_t *cred)
{
OM_uint32 major, minor;
gss_buffer_desc namebuf, pwbuf;
gss_name_t name = GSS_C_NO_NAME;
gss_OID_set mechs = GSS_C_NO_OID_SET;
namebuf.value = rk_UNCONST(source_name);
namebuf.length = strlen(source_name);
major = gss_import_name(&minor, &namebuf, GSS_C_NT_USER_NAME, &name);
if (major != GSS_S_COMPLETE)
gss_err(1, major, minor, GSS_C_NO_OID,
"failed to import source name %s", source_name);
pwbuf.value = rk_UNCONST(source_password);
pwbuf.length = strlen(source_password);
add_krb5_mech(&mechs);
major = gss_acquire_cred_with_password(&minor, name, &pwbuf,
GSS_C_INDEFINITE, mechs,
GSS_C_INITIATE, cred, NULL, NULL);
(void) gss_release_oid_set(&minor, &mechs);
(void) gss_release_name(&minor, &name);
if (major != GSS_S_COMPLETE)
gss_err(1, major, minor, GSS_KRB5_MECHANISM,
"failed to acquire creds with password for %s", source_name);
}
static void
check_init_sec_context(gss_cred_id_t cred, const char *target)
{
OM_uint32 major, minor;
gss_buffer_desc namebuf;
gss_buffer_desc output_token = { 0, NULL };
gss_name_t target_name = GSS_C_NO_NAME;
gss_ctx_id_t ctx = GSS_C_NO_CONTEXT;
namebuf.value = rk_UNCONST(target);
namebuf.length = strlen(target);
major = gss_import_name(&minor, &namebuf, GSS_C_NT_HOSTBASED_SERVICE,
&target_name);
if (major != GSS_S_COMPLETE)
gss_err(1, major, minor, GSS_C_NO_OID,
"failed to import target name %s", target);
major = gss_init_sec_context(&minor, cred, &ctx, target_name,
GSS_KRB5_MECHANISM, 0, GSS_C_INDEFINITE,
GSS_C_NO_CHANNEL_BINDINGS,
GSS_C_NO_BUFFER, NULL, &output_token,
NULL, NULL);
(void) gss_release_buffer(&minor, &output_token);
(void) gss_delete_sec_context(&minor, &ctx, GSS_C_NO_BUFFER);
(void) gss_release_name(&minor, &target_name);
if (major != GSS_S_COMPLETE)
gss_err(1, major, minor, GSS_KRB5_MECHANISM,
"failed to use source cred for %s after storing", target);
}
static void
acquire_from_ccache(const char *ccache, gss_cred_id_t *cred)
{
OM_uint32 major, minor;
gss_key_value_element_desc element;
gss_key_value_set_desc store;
element.key = "ccache";
element.value = ccache;
store.count = 1;
store.elements = &element;
major = gss_add_cred_from(&minor, GSS_C_NO_CREDENTIAL, GSS_C_NO_NAME,
GSS_KRB5_MECHANISM, GSS_C_INITIATE,
GSS_C_INDEFINITE, GSS_C_INDEFINITE,
&store, cred, NULL, NULL, NULL);
if (major != GSS_S_COMPLETE)
gss_err(1, major, minor, GSS_KRB5_MECHANISM,
"failed to acquire stored creds from %s", ccache);
}
static void
check_default_ccache(gss_cred_id_t from_cred, const char *target)
{
OM_uint32 minor;
const char *ccache = getenv("KRB5CCNAME");
gss_cred_id_t to_cred = GSS_C_NO_CREDENTIAL;
if (ccache == NULL)
errx(1, "KRB5CCNAME not set");
acquire_from_ccache(ccache, &to_cred);
check_init_sec_context(from_cred, target);
check_init_sec_context(to_cred, target);
(void) gss_release_cred(&minor, &to_cred);
}
int
main(int argc, char **argv)
{
@@ -276,42 +157,30 @@ main(int argc, char **argv)
if (argc > 2)
errx(1, "too many arguments");
if (password) {
if (!store_cred_flag)
errx(1, "--password requires --store-cred");
acquire_from_password(argv[0], password, &from_cred);
} else {
from_elements.key = "ccache";
from_elements.value = argv[0];
from.count = 1;
from.elements = &from_elements;
from_elements.key = "ccache";
from_elements.value = argv[0];
from.count = 1;
from.elements = &from_elements;
major = gss_add_cred_from(&minor, GSS_C_NO_CREDENTIAL, GSS_C_NO_NAME,
GSS_KRB5_MECHANISM, GSS_C_INITIATE,
GSS_C_INDEFINITE, GSS_C_INDEFINITE,
&from, &from_cred, NULL, NULL, NULL);
if (major != GSS_S_COMPLETE)
gss_err(1, major, minor, GSS_KRB5_MECHANISM,
"failed to acquire creds from %s", argv[0]);
}
to_elements.key = "ccache";
to_elements.value = argv[1];
to.count = 1;
to.elements = &to_elements;
if (store_cred_flag) {
major = gss_store_cred(&minor, from_cred, GSS_C_INITIATE,
GSS_KRB5_MECHANISM, overwrite_flag, def_flag,
NULL, NULL);
} else {
to_elements.key = "ccache";
to_elements.value = argv[1];
to.count = 1;
to.elements = &to_elements;
major = gss_store_cred_into2(&minor, from_cred, GSS_C_INITIATE,
GSS_KRB5_MECHANISM, store_flags, &to, NULL,
NULL, env_flag ? &env : NULL);
}
major = gss_add_cred_from(&minor, GSS_C_NO_CREDENTIAL, GSS_C_NO_NAME,
GSS_KRB5_MECHANISM, GSS_C_INITIATE,
GSS_C_INDEFINITE, GSS_C_INDEFINITE,
&from, &from_cred, NULL, NULL, NULL);
if (major != GSS_S_COMPLETE)
gss_err(1, major, minor, GSS_KRB5_MECHANISM,
"failed to store creds");
"failed to acquire creds from %s", argv[0]);
major = gss_store_cred_into2(&minor, from_cred, GSS_C_INITIATE,
GSS_KRB5_MECHANISM, store_flags, &to, NULL,
NULL, env_flag ? &env : NULL);
if (major != GSS_S_COMPLETE)
gss_err(1, major, minor, GSS_KRB5_MECHANISM,
"failed to store creds into %s", argv[1]);
if (env_flag) {
size_t i;
@@ -335,22 +204,6 @@ main(int argc, char **argv)
"gss_store_cred_into2()");
}
if (password)
check_default_ccache(from_cred, argv[1]);
if (store_cred_flag) {
(void) gss_release_cred(&minor, &from_cred);
return 0;
}
major = gss_add_cred_from(&minor, GSS_C_NO_CREDENTIAL, GSS_C_NO_NAME,
GSS_KRB5_MECHANISM, GSS_C_INITIATE,
GSS_C_INDEFINITE, GSS_C_INDEFINITE,
&to, &to_cred, NULL, NULL, NULL);
if (major != GSS_S_COMPLETE)
gss_err(1, major, minor, GSS_KRB5_MECHANISM,
"failed to acquire stored creds from %s", argv[1]);
(void) gss_release_cred(&minor, &from_cred);
(void) gss_release_cred(&minor, &to_cred);
+1 -1
View File
@@ -483,7 +483,7 @@ loop(gss_OID mechoid,
if (*deleg_cred != GSS_C_NO_CREDENTIAL)
errx(1, "got delegated cred but didn't expect one");
} else if (*deleg_cred == GSS_C_NO_CREDENTIAL)
errx(1, "asked for delegated cred but did get one");
errx(1, "asked for delegarated cred but did get one");
} else if (*deleg_cred != GSS_C_NO_CREDENTIAL)
errx(1, "got deleg_cred cred but didn't ask");
+1 -5
View File
@@ -169,15 +169,12 @@ fuzz_jose_SOURCES = fuzz_jose.c
fuzz_jose_LDADD = libhx509.la $(LIB_roken) $(top_builddir)/lib/base/libheimbase.la
fuzz_jose.$(OBJEXT): $(HX509_PROTOS) $(nodist_include_HEADERS)
test_expr_LDADD = libhx509.la $(LIB_roken) $(top_builddir)/lib/asn1/libasn1.la
test_cert_binary_CPPFLAGS = $(AM_CPPFLAGS) -DSRCDIR=\"$(srcdir)\"
test_cert_binary_LDADD = libhx509.la $(LIB_roken) $(top_builddir)/lib/asn1/libasn1.la
TESTS = $(SCRIPT_TESTS) $(PROGRAM_TESTS)
PROGRAM_TESTS = \
test_name \
test_expr \
test_cert_binary
test_expr
SCRIPT_TESTS = \
test_ca \
@@ -339,7 +336,6 @@ EXTRA_DIST = \
data/key2.der \
data/nist-data \
data/nist-data2 \
data/notafter-2338.pem \
data/no-proxy-test.crt \
data/no-proxy-test.key \
data/ocsp-req1.der \
+2 -14
View File
@@ -66,18 +66,6 @@ struct hx509_ca_tbs {
AlgorithmIdentifier *sigalg;
};
static int
use_utc_time(time_t t)
{
if (t < 1)
return 1;
#if SIZEOF_TIME_T > 4 || defined(TIME_T_UNSIGNED)
if ((uint64_t)t >= 2524608000ULL)
return 0;
#endif
return 1;
}
/**
* Allocate an to-be-signed certificate object that will be converted
* into an certificate.
@@ -1785,13 +1773,13 @@ ca_sign(hx509_context context,
*
* Both, ...u.generalTime and ...u..utcTime are time_t.
*/
if (use_utc_time(notBefore))
if (notBefore < 1 || (int64_t)notBefore < 2524608000)
tbsc->validity.notBefore.element = choice_Time_utcTime;
else
tbsc->validity.notBefore.element = choice_Time_generalTime;
tbsc->validity.notBefore.u.generalTime = notBefore;
if (use_utc_time(notAfter))
if (notAfter < 1 || (int64_t)notAfter < 2524608000)
tbsc->validity.notAfter.element = choice_Time_utcTime;
else
tbsc->validity.notAfter.element = choice_Time_generalTime;
+1 -38
View File
@@ -78,7 +78,6 @@ struct hx509_cert_data {
unsigned int ref;
char *friendlyname;
Certificate *data;
heim_octet_string encoding;
hx509_private_key private_key;
struct _hx509_cert_attrs attrs;
hx509_name basename;
@@ -636,8 +635,6 @@ cert_init(hx509_context context, heim_error_t *error)
cert->release = NULL;
cert->ctx = NULL;
cert->data= NULL;
cert->encoding.data = NULL;
cert->encoding.length = 0;
return cert;
}
@@ -696,23 +693,7 @@ hx509_cert_copy_no_private_key(hx509_context context,
hx509_cert src,
heim_error_t *error)
{
hx509_cert cert;
int ret;
cert = hx509_cert_init(context, src->data, error);
if (cert == NULL)
return NULL;
ret = der_copy_octet_string(&src->encoding, &cert->encoding);
if (ret) {
hx509_cert_free(cert);
if (error)
*error = heim_error_create_enomem();
errno = ret;
return NULL;
}
return cert;
return hx509_cert_init(context, src->data, error);
}
/**
@@ -766,7 +747,6 @@ hx509_cert_init_data(hx509_context context,
heim_error_t *error)
{
hx509_cert cert;
heim_octet_string os;
Certificate t;
size_t size;
int ret;
@@ -789,19 +769,6 @@ hx509_cert_init_data(hx509_context context,
cert = hx509_cert_init(context, &t, error);
free_Certificate(&t);
if (cert == NULL)
return NULL;
os.length = len;
os.data = rk_UNCONST(ptr);
ret = der_copy_octet_string(&os, &cert->encoding);
if (ret) {
hx509_cert_free(cert);
if (error)
*error = heim_error_create_enomem();
errno = ret;
return NULL;
}
return cert;
}
@@ -857,7 +824,6 @@ hx509_cert_free(hx509_cert cert)
if (cert->data)
free_Certificate(cert->data);
free(cert->data);
der_free_octet_string(&cert->encoding);
for (i = 0; i < cert->attrs.len; i++) {
der_free_octet_string(&cert->attrs.val[i]->data);
@@ -4091,9 +4057,6 @@ hx509_cert_binary(hx509_context context, hx509_cert c, heim_octet_string *os)
os->data = NULL;
os->length = 0;
if (c->encoding.data != NULL)
return der_copy_octet_string(&c->encoding, os);
ASN1_MALLOC_ENCODE(Certificate, os->data, os->length,
_hx509_get_cert(c), &size, ret);
if (ret) {
-25
View File
@@ -1,25 +0,0 @@
-----BEGIN CERTIFICATE-----
MIIFATCCAumgAwIBAgIBAjANBgkqhkiG9w0BAQUFADAqMRswGQYDVQQDDBJoeDUwOSBUZXN0IFJv
b3QgQ0ExCzAJBgNVBAYTAlNFMCAXDTE5MDMyMjIyMjUwMloYDzIzMzgwMTE5MDMxNDA4WjAhMQsw
CQYDVQQGEwJTRTESMBAGA1UEAwwJVGVzdCBjZXJ0MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIIC
CgKCAgEA2h1NylGd8Z/XpHpF+HWYZrLFfVPeQjV0gc0en/ND16eDf/uizjxEN4BPITam9slRdJ7i
m7+t5OtyEWQ2iLOpkWPH7jjE9YwGceUJt+tXXb/bW3IHxSnobzOzoifvH1DwVTNjQSPgsvchd0ur
nXMqu7ZOiH985cY3PrYgwVc+bVd47w1H6UHn+rYtMj9CBY1Wr/XEuG6ZGucH1aE/KX3OsjmmqwZ6
4iY52JaeO8iveT6aJE5Lsq/kBw5x3C9wJ5c8ovppm1dLxVNeKAywx1cforImD1+/00V4kFos/Gpn
M7bBfs0XwFieuoXFFVpaZ9u/LwXNONmUyZV/m2iwYv83ks/Yd77Lcj0PuYBEV8DJEAH9ByUw69hI
Ba+Y+sRkbVmmao0b1EvzB5ho47tZySH4EbSighsN6IzgpeEcccrDLZBDw+6ZLH1BSDnIAHINgDkj
oTon7QfKMo80yrudZxN9Me1K2zV6zrOJ42SdPkdO07e9qxIWELtm6Bp3TCrguRZpZhSDTkrzb6uF
anDGm86Tq3U2o6Wqn0XWon8Xx2/59ec1UaV1xQe+Js57Pyk6dGsXeU7PTAppdVjb66jd8ebMoxhT
pcWlWqHPN2qxn9PU6w8CQNKuaM68xUbj7viXiO7IpwF6oSOv8zEsKm8Sd9w8UZ1A9Joqe4UpHz7D
1TeObgkCAwEAAaM5MDcwCQYDVR0TBAIwADALBgNVHQ8EBAMCBeAwHQYDVR0OBBYEFBv07DRCuotn
rFXyN120aKnYXlh7MA0GCSqGSIb3DQEBBQUAA4ICAQCV9xyZckJP0726P3p1uwE6rc5re7c9XTtG
UeqaNpRwNhw7/Lqdiw1ENgitpnOCvCPt+VoJj51iEcGUfGFmH4u5Ctw6tesiVN6j5YqUEB+EUm3+
J8jly6WOqYMWlQ1sPleF4eyCBUdtKK0NhPpAoJb0hKrR4Qu3keJHTwWX+BCg6Fe97UhlVXXa5TTo
8SCV1kCMQr+02VXIMOjVztgdMGWQOevig+0RA80HwOHEkYSgl45tIuZ1dyF8MotI7dayGS6vJq19
bM4J4Xi2cmFgIpK430JrNGtfNe/x08Z/kgU80Ah3AWb3V7hl3tPSsb+TsYyjJ+bU4iubzZ2+MYJb
U91avTkFX4xW8n+bt+/mB5a/itmNu2KYht6qkcP+57unH/D9H2ymBATwwlGhkYya7vmHQjd+nCdy
WdxgqI7RgZfxFcPYqU6aCemBdjk2swih5V6XN7pDjwYacGk7/nmmXi0mBOm8X1fJ0IDCDUvHDt0E
5RVJndf/7qMcBFZ94qDTORpZvYWw61TqgYvhF5Sl/uMM0HRC7kr0ZpBJS2S8RzX1smCOdAXQptKU
tOAPSz816irgJFjBbtBlblj34ZACrkAjJemAmtKn6l38bfhFD9tTkVUyRuNqwFQKWkzoGh6mMz7+
7batz2o8L7JsR3XxKUMxacMMQlZb2biZe/8rUIc0Lg==
-----END CERTIFICATE-----
-17
View File
@@ -47,23 +47,6 @@ for a in $srcdir/data/*.crt; do
${hxtool} print --content FILE:"$a" > /dev/null 2>/dev/null
done
echo "print certificate with 2338 notAfter"
${hxtool} print --content FILE:$srcdir/data/notafter-2338.pem > cert-2338.tmp || exit 1
config=$objdir/../../include/config.h
if grep '^#define SIZEOF_TIME_T 4$' "$config" > /dev/null; then
if grep '^#define TIME_T_UNSIGNED' "$config" > /dev/null; then
notafter='notAfter 2106-02-07 06:28:15'
else
notafter='notAfter 2038-01-19 03:14:07'
fi
else
notafter='notAfter 2338-01-19 03:14:08'
fi
grep "$notafter" cert-2338.tmp > /dev/null || {
cat cert-2338.tmp
exit 1
}
echo "print NULL"
${hxtool} print --content NULL: > /dev/null || exit 1
-179
View File
@@ -1,179 +0,0 @@
#include "hx_locl.h"
#include <err.h>
#ifndef SRCDIR
#define SRCDIR "."
#endif
struct pem_cert {
heim_octet_string der;
int found;
};
static int
pem_cert_reader(hx509_context context, const char *type,
const hx509_pem_header *headers,
const void *data, size_t length, void *ctx)
{
struct pem_cert *pem = ctx;
(void)context;
(void)headers;
if (strcmp(type, "CERTIFICATE") != 0)
return 0;
if (pem->found)
return 0;
pem->der.data = malloc(length);
if (pem->der.data == NULL)
return ENOMEM;
memcpy(pem->der.data, data, length);
pem->der.length = length;
pem->found = 1;
return 0;
}
static void
read_cert_der(hx509_context context, const char *path, heim_octet_string *der)
{
struct pem_cert pem;
FILE *f;
int ret;
memset(&pem, 0, sizeof(pem));
f = fopen(path, "r");
if (f == NULL)
err(1, "fopen: %s", path);
ret = hx509_pem_read(context, f, pem_cert_reader, &pem);
fclose(f);
if (ret)
hx509_err(context, 1, ret, "hx509_pem_read: %s", path);
if (!pem.found)
errx(1, "did not find a certificate in %s", path);
*der = pem.der;
}
static void
compare_octet_string(const char *what,
const heim_octet_string *expected,
const heim_octet_string *actual)
{
if (actual->length != expected->length)
errx(1, "%s length changed from %lu to %lu",
what, (unsigned long)expected->length,
(unsigned long)actual->length);
if (memcmp(actual->data, expected->data, expected->length) != 0)
errx(1, "%s data changed", what);
}
static void
check_cert_binary(hx509_context context, const heim_octet_string *der)
{
heim_octet_string os;
hx509_cert cert;
int ret;
memset(&os, 0, sizeof(os));
cert = hx509_cert_init_data(context, der->data, der->length, NULL);
if (cert == NULL)
err(1, "hx509_cert_init_data");
ret = hx509_cert_binary(context, cert, &os);
if (ret)
hx509_err(context, 1, ret, "hx509_cert_binary");
compare_octet_string("certificate encoding", der, &os);
der_free_octet_string(&os);
hx509_cert_free(cert);
}
static char *
make_store_name(void)
{
char *store_name = NULL;
if (asprintf(&store_name, "FILE:%s/data/test.crt,%s/data/test.key",
SRCDIR, SRCDIR) == -1 || store_name == NULL)
err(1, "asprintf");
return store_name;
}
static void
check_keyless_store_cert_encoding(hx509_context context,
const heim_octet_string *der)
{
heim_octet_string os;
hx509_certs certs = NULL;
hx509_cert cert = NULL;
char *store_name;
int ret;
memset(&os, 0, sizeof(os));
ret = hx509_certs_init(context, "MEMORY:test-keyless-certs",
HX509_CERTS_NO_PRIVATE_KEYS, NULL, &certs);
if (ret)
hx509_err(context, 1, ret, "hx509_certs_init");
store_name = make_store_name();
ret = hx509_certs_append(context, certs, NULL, store_name);
free(store_name);
if (ret)
hx509_err(context, 1, ret, "hx509_certs_append");
ret = hx509_get_one_cert(context, certs, &cert);
if (ret)
hx509_err(context, 1, ret, "hx509_get_one_cert");
if (hx509_cert_have_private_key(cert))
errx(1, "HX509_CERTS_NO_PRIVATE_KEYS store kept a private key");
ret = hx509_cert_binary(context, cert, &os);
if (ret)
hx509_err(context, 1, ret, "hx509_cert_binary on keyless cert");
compare_octet_string("keyless store certificate encoding", der, &os);
der_free_octet_string(&os);
hx509_cert_free(cert);
hx509_certs_free(&certs);
}
int
main(int argc, char **argv)
{
heim_octet_string der;
hx509_context context;
char *cert_path = NULL;
int ret;
(void)argc;
(void)argv;
memset(&der, 0, sizeof(der));
ret = hx509_context_init(&context);
if (ret)
errx(1, "hx509_context_init failed with %d", ret);
if (asprintf(&cert_path, "%s/data/test.crt", SRCDIR) == -1 ||
cert_path == NULL)
err(1, "asprintf");
read_cert_der(context, cert_path, &der);
free(cert_path);
check_cert_binary(context, &der);
check_keyless_store_cert_encoding(context, &der);
der_free_octet_string(&der);
hx509_context_free(&context);
return 0;
}
+3 -13
View File
@@ -46,23 +46,14 @@ if have_gcd
# stops building on recent OS X releases unless we disable this warning.
WFLAGS += -Wno-deprecated-declarations
heim_ipc.stamp: heim_ipc.defs
heim_ipc.h heim_ipcUser.c heim_ipcServer.c heim_ipcServer.h: heim_ipc.defs
mig -header heim_ipc.h -user heim_ipcUser.c -sheader heim_ipcServer.h -server heim_ipcServer.c -I$(srcdir) $(srcdir)/heim_ipc.defs
touch $@
heim_ipc.h heim_ipcUser.c heim_ipcServer.c heim_ipcServer.h: heim_ipc.stamp
heim_ipc_async.stamp: heim_ipc_async.defs
heim_ipc_async.h heim_ipc_asyncUser.c heim_ipc_asyncServer.c heim_ipc_asyncServer.h: heim_ipc_async.defs
mig -header heim_ipc_async.h -user heim_ipc_asyncUser.c -sheader heim_ipc_asyncServer.h -server heim_ipc_asyncServer.c -I$(srcdir) $(srcdir)/heim_ipc_async.defs
touch $@
heim_ipc_async.h heim_ipc_asyncUser.c heim_ipc_asyncServer.c heim_ipc_asyncServer.h: heim_ipc_async.stamp
heim_ipc_reply.stamp: heim_ipc_reply.defs
heim_ipc_reply.h heim_ipc_replyUser.c: heim_ipc_reply.defs
mig -header heim_ipc_reply.h -user heim_ipc_replyUser.c -sheader /dev/null -server /dev/null -I$(srcdir) $(srcdir)/heim_ipc_reply.defs
touch $@
heim_ipc_reply.h heim_ipc_replyUser.c: heim_ipc_reply.stamp
built_ipcc = heim_ipc.h heim_ipcUser.c
built_ipcc += heim_ipc_asyncServer.c heim_ipc_asyncServer.h
@@ -78,7 +69,6 @@ nodist_libheim_ipcs_la_SOURCES = $(built_ipcs)
libheim_ipcs_la_LIBADD += -lbsm
CLEANFILES = $(built_ipcc) $(built_ipcs)
CLEANFILES += heim_ipc.stamp heim_ipc_async.stamp heim_ipc_reply.stamp
$(srcdir)/client.c: $(built_ipcc)
$(srcdir)/server.c: $(built_ipcs)
+2
View File
@@ -41,6 +41,8 @@
#include <sys/un.h>
#endif
#include <poll.h>
#include <ctype.h>
#include <stdio.h>
#include <stdlib.h>
+38 -111
View File
@@ -86,46 +86,37 @@ make_signal_socket (krb5_context context)
#endif
}
static int
listen_port(krb5_context context, const char *port_str)
{
int port;
if (port_str) {
port = krb5_getportbyname(context, port_str, "tcp", 0);
if (port == 0) {
char *ptr;
long num;
num = strtol(port_str, &ptr, 10);
if (num == 0 && ptr == port_str)
krb5_errx(context, 1, "bad port `%s'", port_str);
port = htons(num);
}
} else {
port = krb5_getportbyname(context, IPROP_SERVICE,
"tcp", IPROP_PORT);
}
return port;
}
static krb5_socket_t
make_listen_socket(krb5_context context, int port)
make_listen_socket (krb5_context context, const char *port_str)
{
krb5_socket_t fd;
int one = 1;
struct sockaddr_in addr;
fd = socket(AF_INET, SOCK_STREAM, 0);
fd = socket (AF_INET, SOCK_STREAM, 0);
if (rk_IS_BAD_SOCKET(fd))
krb5_err (context, 1, rk_SOCK_ERRNO, "socket AF_INET");
(void) setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (void *)&one, sizeof(one));
memset (&addr, 0, sizeof(addr));
addr.sin_family = AF_INET;
addr.sin_port = port;
addr.sin_addr.s_addr = htonl(INADDR_ANY);
if (port_str) {
addr.sin_port = krb5_getportbyname (context,
port_str, "tcp",
0);
if (addr.sin_port == 0) {
char *ptr;
long port;
port = strtol (port_str, &ptr, 10);
if (port == 0 && ptr == port_str)
krb5_errx (context, 1, "bad port `%s'", port_str);
addr.sin_port = htons(port);
}
} else {
addr.sin_port = krb5_getportbyname (context, IPROP_SERVICE,
"tcp", IPROP_PORT);
}
if(bind(fd, (struct sockaddr *)&addr, sizeof(addr)) < 0)
krb5_err (context, 1, errno, "bind");
if (listen(fd, SOMAXCONN) < 0)
@@ -133,64 +124,10 @@ make_listen_socket(krb5_context context, int port)
return fd;
}
#ifdef AF_INET6
static krb5_socket_t
make_listen_socket6(krb5_context context, int port)
{
krb5_socket_t fd;
int one = 1;
struct sockaddr_in6 addr;
fd = socket(AF_INET6, SOCK_STREAM, 0);
if (rk_IS_BAD_SOCKET(fd)) {
#ifdef EAFNOSUPPORT
if (rk_SOCK_ERRNO != EAFNOSUPPORT)
#endif
krb5_warn(context, rk_SOCK_ERRNO, "socket AF_INET6");
return rk_INVALID_SOCKET;
}
(void) setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (void *)&one, sizeof(one));
socket_set_ipv6only(fd, 1);
memset(&addr, 0, sizeof(addr));
addr.sin6_family = AF_INET6;
addr.sin6_port = port;
addr.sin6_addr = in6addr_any;
if (bind(fd, (struct sockaddr *)&addr, sizeof(addr)) < 0) {
krb5_warn(context, errno, "bind AF_INET6");
rk_closesocket(fd);
return rk_INVALID_SOCKET;
}
if (listen(fd, SOMAXCONN) < 0) {
krb5_warn (context, errno, "listen AF_INET6");
rk_closesocket(fd);
return rk_INVALID_SOCKET;
}
return fd;
}
#endif
static void
make_listen_sockets(krb5_context context, const char *port_str,
krb5_socket_t *fds, int *num_fds)
{
krb5_socket_t fd;
int port = listen_port(context, port_str);
*num_fds = 0;
#ifdef AF_INET6
fd = make_listen_socket6(context, port);
if (!rk_IS_BAD_SOCKET(fd))
fds[(*num_fds)++] = fd;
#endif
fds[(*num_fds)++] = make_listen_socket(context, port);
}
struct slave {
krb5_socket_t fd;
struct sockaddr_storage addr;
struct sockaddr_in addr;
char *name;
krb5_auth_context ac;
uint32_t version;
@@ -1677,14 +1614,13 @@ main(int argc, char **argv)
void *kadm_handle;
kadm5_server_context *server_context;
kadm5_config_params conf;
krb5_socket_t signal_fd, listen_fds[2];
krb5_socket_t signal_fd, listen_fd;
slave *slaves = NULL;
uint32_t current_version = 0, old_version = 0;
krb5_keytab keytab;
char **files;
int aret;
int optidx = 0;
int num_listen_fds = 0;
int restarter_fd = -1;
struct stat st;
@@ -1794,7 +1730,7 @@ main(int argc, char **argv)
&current_version, NULL);
signal_fd = make_signal_socket (context);
make_listen_sockets(context, port_str, listen_fds, &num_listen_fds);
listen_fd = make_listen_socket (context, port_str);
krb5_warnx(context, "ipropd-master started at version: %lu",
(unsigned long)current_version);
@@ -1806,28 +1742,22 @@ main(int argc, char **argv)
slave *p;
fd_set readset, writeset;
int max_fd = 0;
int nready;
int i;
struct timeval to = {30, 0};
uint32_t vers;
struct stat st2;
#ifndef NO_LIMIT_FD_SETSIZE
if (signal_fd >= FD_SETSIZE || restarter_fd >= FD_SETSIZE)
if (signal_fd >= FD_SETSIZE || listen_fd >= FD_SETSIZE ||
restarter_fd >= FD_SETSIZE)
krb5_errx (context, IPROPD_RESTART, "fd too large");
for (i = 0; i < num_listen_fds; i++)
if (listen_fds[i] >= FD_SETSIZE)
krb5_errx (context, IPROPD_RESTART, "fd too large");
#endif
FD_ZERO(&readset);
FD_ZERO(&writeset);
FD_SET(signal_fd, &readset);
max_fd = max(max_fd, signal_fd);
for (i = 0; i < num_listen_fds; i++) {
FD_SET(listen_fds[i], &readset);
max_fd = max(max_fd, listen_fds[i]);
}
FD_SET(listen_fd, &readset);
max_fd = max(max_fd, listen_fd);
if (restarter_fd > -1) {
FD_SET(restarter_fd, &readset);
max_fd = max(max_fd, restarter_fd);
@@ -1849,7 +1779,6 @@ main(int argc, char **argv)
else
krb5_err (context, IPROPD_RESTART, errno, "select");
}
nready = ret;
if (stat(server_context->log_context.log_file, &st2) == -1) {
krb5_warn(context, errno, "could not stat log file by path");
@@ -1872,7 +1801,7 @@ main(int argc, char **argv)
&current_version, NULL);
}
if (nready == 0) {
if (ret == 0) {
kadm5_log_get_version_fd(server_context, -1, LOG_VERSION_LAST,
&current_version, NULL);
@@ -1896,12 +1825,12 @@ main(int argc, char **argv)
}
}
if (nready && restarter_fd > -1 && FD_ISSET(restarter_fd, &readset)) {
if (ret && FD_ISSET(restarter_fd, &readset)) {
exit_flag = SIGTERM;
break;
}
if (nready && FD_ISSET(signal_fd, &readset)) {
if (ret && FD_ISSET(signal_fd, &readset)) {
#ifndef NO_UNIX_SOCKETS
struct sockaddr_un peer_addr;
#else
@@ -1914,8 +1843,8 @@ main(int argc, char **argv)
krb5_warn (context, errno, "recvfrom");
continue;
}
--nready;
assert(nready >= 0);
--ret;
assert(ret >= 0);
old_version = current_version;
kadm5_log_get_version_fd(server_context, -1, LOG_VERSION_LAST,
&current_version, NULL);
@@ -1972,9 +1901,9 @@ main(int argc, char **argv)
for(p = slaves; p != NULL; p = p->next) {
if (p->flags & SLAVE_F_DEAD)
continue;
if (nready && FD_ISSET(p->fd, &readset)) {
--nready;
assert(nready >= 0);
if (ret && FD_ISSET(p->fd, &readset)) {
--ret;
assert(ret >= 0);
ret = process_msg(server_context, p, database,
current_version);
if (ret && ret != EWOULDBLOCK) {
@@ -1987,12 +1916,10 @@ main(int argc, char **argv)
send_are_you_there (context, p);
}
for (i = 0; nready && i < num_listen_fds; i++) {
if (FD_ISSET(listen_fds[i], &readset)) {
add_slave(context, keytab, &slaves, listen_fds[i]);
--nready;
assert(nready >= 0);
}
if (ret && FD_ISSET(listen_fd, &readset)) {
add_slave (context, keytab, &slaves, listen_fd);
--ret;
assert(ret >= 0);
}
write_stats(context, slaves, current_version);
}
+11 -4
View File
@@ -124,14 +124,16 @@ connect_to_master (krb5_context context, const char *master,
}
static void
get_creds(krb5_context context, krb5_ccache *cache)
get_creds(krb5_context context, krb5_ccache *cache, const char *serverhost)
{
krb5_keytab keytab;
krb5_principal client;
krb5_error_code ret;
krb5_get_init_creds_opt *init_opts;
krb5_creds creds;
char *server;
char keytab_buf[256];
int aret;
if (no_keytab_flag) {
/* We're using an externally refreshed ccache */
@@ -174,8 +176,13 @@ get_creds(krb5_context context, krb5_ccache *cache)
ret = krb5_get_init_creds_opt_alloc(context, &init_opts);
if (ret) krb5_err(context, 1, ret, "krb5_get_init_creds_opt_alloc");
aret = asprintf (&server, "%s/%s", IPROP_NAME, serverhost);
if (aret == -1 || server == NULL)
krb5_errx (context, 1, "malloc: no memory");
ret = krb5_get_init_creds_keytab(context, &creds, client, keytab,
0, NULL, init_opts);
0, server, init_opts);
free (server);
krb5_get_init_creds_opt_free(context, init_opts);
if(ret) krb5_err(context, 1, ret, "krb5_get_init_creds");
@@ -883,7 +890,7 @@ main(int argc, char **argv)
if (ret)
krb5_err(context, 1, ret, "db->close");
get_creds(context, &ccache);
get_creds(context, &ccache, master);
ret = krb5_sname_to_principal (context, master, IPROP_NAME,
KRB5_NT_SRV_HST, &server);
@@ -949,7 +956,7 @@ main(int argc, char **argv)
krb5_auth_con_free(context, auth_context);
auth_context = NULL;
}
get_creds(context, &ccache);
get_creds(context, &ccache, master);
if (verbose)
krb5_warnx(context, "authenticating to master");
ret = krb5_sendauth (context, &auth_context, &master_fd,
+30 -33
View File
@@ -704,30 +704,25 @@ change_password_loop (krb5_context context,
* do the SOCKS4a I/O.
*/
while (!_krb5_socks4a_connected(socks4a)) {
struct pollfd pfd;
fd_set readfds, writefds;
int nready;
pfd.fd = sock;
pfd.events = 0;
pfd.revents = 0;
FD_ZERO(&readfds);
FD_ZERO(&writefds);
if (_krb5_socks4a_reading(socks4a))
pfd.events |= POLLIN;
FD_SET(sock, &readfds);
if (_krb5_socks4a_writing(socks4a))
pfd.events |= POLLOUT;
nready = poll(&pfd, 1, -1); /* blocking */
if (nready < 0) {
if (errno == EINTR)
continue;
FD_SET(sock, &writefds);
nready = select(sock + 1, &readfds, &writefds,
/*exceptfds*/NULL, /*timeout*/NULL);
if (nready == -1) {
ret = errno;
break;
}
if (nready == 0) {
if (nready <= 0) {
ret = EIO; /* timeout should be impossible */
break;
}
ret = _krb5_socks4a_io(socks4a);
if (ret)
break;
@@ -738,6 +733,9 @@ change_password_loop (krb5_context context,
}
for (i = 0; !done && i < 5; ++i) {
fd_set fdset;
struct timeval tv;
if (!replied) {
replied = 0;
@@ -755,28 +753,27 @@ change_password_loop (krb5_context context,
}
}
struct pollfd pfd;
int timeout_ms;
timeout_ms = (1 + (1 << i)) * 1000;
pfd.fd = sock;
pfd.events = POLLIN;
pfd.revents = 0;
ret = poll(&pfd, 1, timeout_ms);
if (ret < 0) {
if (errno == EINTR)
continue;
rk_closesocket(sock);
ret = errno;
goto out;
#ifndef NO_LIMIT_FD_SETSIZE
if (sock >= FD_SETSIZE) {
ret = ERANGE;
krb5_set_error_message(context, ret,
"fd %d too large", sock);
rk_closesocket (sock);
goto out;
}
#endif
if (ret == 0) {
ret = KRB5_KDC_UNREACH;
continue;
FD_ZERO(&fdset);
FD_SET(sock, &fdset);
tv.tv_usec = 0;
tv.tv_sec = 1 + (1 << i);
ret = select (sock + 1, &fdset, NULL, NULL, &tv);
if (rk_IS_SOCKET_ERROR(ret) && rk_SOCK_ERRNO != EINTR) {
rk_closesocket(sock);
goto out;
}
if (pfd.revents & (POLLIN | POLLERR | POLLHUP | POLLNVAL)) {
if (ret == 1) {
ret = (*proc->process_rep) (context,
auth_context,
is_stream,
+4 -4
View File
@@ -489,7 +489,7 @@ init_context_from_config_file(krb5_context context)
tmp = secure_getenv("KRB5_TRACE");
if (tmp)
heim_add_trace_dest(context->hcontext, "libkrb5", tmp);
heim_add_debug_dest(context->hcontext, "libkrb5", tmp);
s = krb5_config_get_strings(context, NULL, "logging", "krb5", NULL);
if (s) {
char **p;
@@ -1108,15 +1108,15 @@ krb5_kerberos_enctypes(krb5_context context)
};
static const krb5_enctype weak[] = {
ETYPE_AES256_CTS_HMAC_SHA384_192,
ETYPE_AES128_CTS_HMAC_SHA256_128,
ETYPE_AES256_CTS_HMAC_SHA1_96,
ETYPE_AES128_CTS_HMAC_SHA1_96,
ETYPE_AES256_CTS_HMAC_SHA384_192,
ETYPE_AES128_CTS_HMAC_SHA256_128,
ETYPE_ARCFOUR_HMAC_MD5,
ETYPE_NULL
};
if (krb5_enctype_valid(context, ETYPE_ARCFOUR_HMAC_MD5) == 0)
if (krb5_enctype_valid(context, ETYPE_ARCFOUR_HMAC_MD5))
return weak;
return strong;
-16
View File
@@ -608,12 +608,8 @@ krb5_create_checksum(krb5_context context,
}
if (arcfour_checksum_p(ct, crypto)) {
#ifdef HEIM_ARCFOUR
keyusage = usage;
_krb5_usage2arcfour(context, &keyusage);
#else
return KRB5_PROG_SUMTYPE_NOSUPP;
#endif /* HEIM_ARCFOUR */
} else
keyusage = CHECKSUM_USAGE(usage);
@@ -742,12 +738,8 @@ krb5_verify_checksum(krb5_context context,
}
if (arcfour_checksum_p(ct, crypto)) {
#ifdef HEIM_ARCFOUR
keyusage = usage;
_krb5_usage2arcfour(context, &keyusage);
#else
return KRB5_PROG_SUMTYPE_NOSUPP;
#endif /* HEIM_ARCFOUR */
} else
keyusage = CHECKSUM_USAGE(usage);
@@ -2075,12 +2067,8 @@ krb5_create_checksum_iov(krb5_context context,
}
if (arcfour_checksum_p(ct, crypto)) {
#ifdef HEIM_ARCFOUR
keyusage = usage;
_krb5_usage2arcfour(context, &keyusage);
#else
return KRB5_PROG_SUMTYPE_NOSUPP;
#endif /* HEIM_ARCFOUR */
} else
keyusage = CHECKSUM_USAGE(usage);
@@ -2146,12 +2134,8 @@ krb5_verify_checksum_iov(krb5_context context,
}
if (arcfour_checksum_p(ct, crypto)) {
#ifdef HEIM_ARCFOUR
keyusage = usage;
_krb5_usage2arcfour(context, &keyusage);
#else
return KRB5_PROG_SUMTYPE_NOSUPP;
#endif /* HEIM_ARCFOUR */
} else
keyusage = CHECKSUM_USAGE(usage);
+1 -1
View File
@@ -1081,6 +1081,7 @@ cred_delete(krb5_context context,
ret = krb5_storage_to_data(sp, &orig_cred_data);
if (ret)
goto out;
krb5_storage_free(sp);
cred_data_in_file = malloc(orig_cred_data.length);
if (cred_data_in_file == NULL)
@@ -1102,7 +1103,6 @@ cred_delete(krb5_context context,
goto out;
}
krb5_storage_free(sp);
sp = krb5_storage_emem();
if (sp == NULL)
goto out;
+1 -1
View File
@@ -645,7 +645,7 @@ get_cred_kdc(krb5_context context,
krb5_sendto_ctx stctx;
ret = krb5_sendto_ctx_alloc(context, &stctx);
if (ret)
goto out;
return ret;
krb5_sendto_ctx_set_func(stctx, _krb5_kdc_retry, NULL);
if (kdc_hostname)
+4 -6
View File
@@ -381,12 +381,10 @@ fkt_start_seq_get_int(krb5_context context,
return ret;
}
rk_cloexec(c->fd);
if (exclusive) {
ret = _krb5_xlock(context, c->fd, exclusive, d->filename);
if (ret) {
close(c->fd);
return ret;
}
ret = _krb5_xlock(context, c->fd, exclusive, d->filename);
if (ret) {
close(c->fd);
return ret;
}
if ((flags & O_ACCMODE) == O_RDWR && (flags & O_APPEND))
stdio_mode = "ab+";
+26 -6
View File
@@ -35,6 +35,7 @@
.Dt KRB5_CONTEXT 3
.Os HEIMDAL
.Sh NAME
.Nm krb5_add_et_list ,
.Nm krb5_add_extra_addresses ,
.Nm krb5_add_ignore_addresses ,
.Nm krb5_context ,
@@ -47,7 +48,7 @@
.Nm krb5_get_ignore_addresses ,
.Nm krb5_get_kdc_sec_offset ,
.Nm krb5_get_max_time_skew ,
.Nm krb5_get_use_admin_kdc ,
.Nm krb5_get_use_admin_kdc
.Nm krb5_init_context ,
.Nm krb5_init_ets ,
.Nm krb5_prepend_config_files ,
@@ -58,7 +59,7 @@
.Nm krb5_set_fcache_version ,
.Nm krb5_set_ignore_addresses ,
.Nm krb5_set_max_time_skew ,
.Nm krb5_set_use_admin_kdc
.Nm krb5_set_use_admin_kdc ,
.Nd create, modify and delete krb5_context structures
.Sh LIBRARY
Kerberos 5 Library (libkrb5, -lkrb5)
@@ -80,6 +81,11 @@ Kerberos 5 Library (libkrb5, -lkrb5)
.Fa "krb5_context context"
.Fc
.Ft krb5_error_code
.Fo krb5_add_et_list
.Fa "krb5_context context"
.Fa "void (*func)(struct et_list **)"
.Fc
.Ft krb5_error_code
.Fo krb5_add_extra_addresses
.Fa "krb5_context context"
.Fa "krb5_addresses *addresses"
@@ -198,11 +204,23 @@ or that Kerberos should not be used
.Bq ENXIO .
.Pp
.Fn krb5_init_ets
is retained for ABI compatibility.
It does not perform any action.
Any initialization it used to provide is done by
adds all
.Xr com_err 3
libs to
.Fa context .
This is done by
.Fn krb5_init_context .
.Pp
.Fn krb5_add_et_list
adds a
.Xr com_err 3
error-code handler
.Fa func
to the specified
.Fa context .
The error handler must generated by the the re-rentrant version of the
.Xr compile_et 1
program.
.Fn krb5_add_extra_addresses
add a list of addresses that should be added when requesting tickets.
.Pp
@@ -284,5 +302,7 @@ and
get and sets the maximum allowed time skew between client and server.
.Sh SEE ALSO
.Xr errno 2 ,
.Xr krb5.conf 5 ,
.Xr krb5 3 ,
.Xr krb5_config 3 ,
.Xr krb5_context 3 ,
.Xr kerberos 8
+4 -6
View File
@@ -91,13 +91,11 @@ cleans the the structure, must be used before trying to pass it in to
.Fn krb5_verify_init_creds .
.Pp
.Fn krb5_verify_init_creds_opt_set_ap_req_nofail
controls the behavior if
controls controls the behavior if
.Fa ap_req_server
does not exist in the local keytab or in the KDC's database.
If it is true, those errors will not be ignored.
Errors from AP_REQ verification with a present key, such as an integrity
check failure, are always returned.
Note that ignoring the error is possibly insecure.
doesn't exists in the local keytab or in the KDC's database, if it's
true, the error will be ignored. Note that this use is possible
insecure.
.Sh SEE ALSO
.Xr krb5 3 ,
.Xr krb5_get_init_creds 3 ,
+5
View File
@@ -231,6 +231,11 @@ main(int argc, char **argv)
}
.Ed
.Sh SEE ALSO
.Xr krb5_cc_gen_new 3 ,
.Xr krb5_cc_initialize 3 ,
.Xr krb5_cc_resolve 3 ,
.Xr krb5_err 3 ,
.Xr krb5_free_principal 3 ,
.Xr krb5_init_context 3 ,
.Xr krb5_kt_default 3 ,
.Xr krb5.conf 5
+19 -25
View File
@@ -1193,35 +1193,29 @@ krcc_get_next(krb5_context context,
if (krcursor == NULL)
return KRB5_CC_END;
for (;;) {
if (krcursor->currkey >= krcursor->numkeys)
return KRB5_CC_END;
/*
* If we're pointing at the entry with the principal, or at the key
* with the time offsets, skip it.
*/
while (krcursor->keys[krcursor->currkey] == krcursor->princ_id ||
krcursor->keys[krcursor->currkey] == krcursor->offsets_id) {
krcursor->currkey++;
if (krcursor->currkey >= krcursor->numkeys)
return KRB5_CC_END;
/*
* If we're pointing at the entry with the principal, or at the key
* with the time offsets, skip it.
*/
while (krcursor->keys[krcursor->currkey] == krcursor->princ_id ||
krcursor->keys[krcursor->currkey] == krcursor->offsets_id) {
krcursor->currkey++;
if (krcursor->currkey >= krcursor->numkeys)
return KRB5_CC_END;
}
ret = keyctl_read_krb5_data(krcursor->keys[krcursor->currkey],
&payload);
krcursor->currkey++;
if (ret == KRB5_FCC_NOFILE)
continue;
if (ret) {
_krb5_debug(context, 10, "Error reading key %d: %s\n",
krcursor->keys[krcursor->currkey - 1],
strerror(errno));
return ret;
}
break;
}
ret = keyctl_read_krb5_data(krcursor->keys[krcursor->currkey], &payload);
if (ret) {
_krb5_debug(context, 10, "Error reading key %d: %s\n",
krcursor->keys[krcursor->currkey],
strerror(errno));
return ret;
}
krcursor->currkey++;
sp = krb5_storage_from_data(&payload);
if (sp == NULL) {
ret = KRB5_CC_IO;
+53 -69
View File
@@ -1084,6 +1084,13 @@ submit_request(krb5_context context, krb5_sendto_ctx ctx, krb5_krbhst_info *hi)
continue;
rk_cloexec(fd);
#ifndef NO_LIMIT_FD_SETSIZE
if (fd >= FD_SETSIZE) {
_krb5_debug(context, 0, "fd too large for select");
rk_closesocket(fd);
continue;
}
#endif
socket_set_nonblocking(fd, 1);
host = heim_alloc(sizeof(*host), "sendto-host", deallocate_host);
@@ -1155,11 +1162,9 @@ submit_request(krb5_context context, krb5_sendto_ctx ctx, krb5_krbhst_info *hi)
struct wait_ctx {
krb5_context context;
krb5_sendto_ctx ctx;
struct pollfd *pfds;
struct host **hosts;
nfds_t nfds;
fd_set rfds;
fd_set wfds;
rk_socket_t max_fd;
int got_reply;
time_t timenow;
};
@@ -1170,8 +1175,6 @@ wait_setup(heim_object_t obj, void *iter_ctx, int *stop)
struct wait_ctx *wait_ctx = iter_ctx;
struct host *h = (struct host *)obj;
short events = 0;
if (h->state == CONNECT) {
if (h->timeout >= wait_ctx->timenow)
return;
@@ -1195,32 +1198,31 @@ wait_setup(heim_object_t obj, void *iter_ctx, int *stop)
host_connected(wait_ctx->context, wait_ctx->ctx, h);
}
}
#ifndef NO_LIMIT_FD_SETSIZE
heim_assert(h->fd < FD_SETSIZE, "fd too large");
#endif
switch (h->state) {
case WAITING_REPLY:
events |= POLLIN;
FD_SET(h->fd, &wait_ctx->rfds);
break;
case CONNECTING:
case CONNECTED:
events |= POLLIN | POLLOUT;
FD_SET(h->fd, &wait_ctx->rfds);
FD_SET(h->fd, &wait_ctx->wfds);
break;
case PROXYING:
if (_krb5_socks4a_reading(h->socks4a))
events |= POLLIN;
FD_SET(h->fd, &wait_ctx->rfds);
if (_krb5_socks4a_writing(h->socks4a))
events |= POLLOUT;
FD_SET(h->fd, &wait_ctx->wfds);
break;
default:
debug_host(wait_ctx->context, 5, h, "invalid sendto host state");
heim_abort("invalid sendto host state");
}
wait_ctx->pfds[wait_ctx->nfds].fd = h->fd;
wait_ctx->pfds[wait_ctx->nfds].events = events;
wait_ctx->pfds[wait_ctx->nfds].revents = 0;
wait_ctx->hosts[wait_ctx->nfds] = h;
wait_ctx->nfds++;
if (h->fd > wait_ctx->max_fd || wait_ctx->max_fd == rk_INVALID_SOCKET)
wait_ctx->max_fd = h->fd;
}
static int
@@ -1240,39 +1242,39 @@ wait_accelerate(heim_object_t obj, void *ctx, int *stop)
}
static void
wait_process(struct wait_ctx *wait_ctx)
wait_process(heim_object_t obj, void *ctx, int *stop)
{
for (nfds_t i = 0; i < wait_ctx->nfds; i++) {
struct host *h = wait_ctx->hosts[i];
struct pollfd *pfd = &wait_ctx->pfds[i];
struct wait_ctx *wait_ctx = ctx;
struct host *h = (struct host *)obj;
int readable, writeable;
heim_assert(h->state != DEAD, "dead host resurected");
int readable = pfd->revents & (POLLIN | POLLERR | POLLHUP | POLLNVAL);
int writeable = pfd->revents & POLLOUT;
#ifndef NO_LIMIT_FD_SETSIZE
heim_assert(h->fd < FD_SETSIZE, "fd too large");
#endif
readable = FD_ISSET(h->fd, &wait_ctx->rfds);
writeable = FD_ISSET(h->fd, &wait_ctx->wfds);
if (readable || writeable || h->state == CONNECT)
wait_ctx->got_reply |= eval_host_state(
wait_ctx->context,
wait_ctx->ctx,
h,
readable,
writeable
);
if (readable || writeable || h->state == CONNECT)
wait_ctx->got_reply |= eval_host_state(wait_ctx->context, wait_ctx->ctx, h, readable, writeable);
if (wait_ctx->got_reply)
return;
}
/* if there is already a reply, just fall though the array */
if (wait_ctx->got_reply)
*stop = 1;
}
static krb5_error_code
wait_response(krb5_context context, int *action, krb5_sendto_ctx ctx)
{
struct wait_ctx wait_ctx;
struct timeval tv;
int ret;
memset(&wait_ctx, 0, sizeof(wait_ctx));
wait_ctx.context = context;
wait_ctx.ctx = ctx;
FD_ZERO(&wait_ctx.rfds);
FD_ZERO(&wait_ctx.wfds);
wait_ctx.max_fd = rk_INVALID_SOCKET;
/* oh, we have a reply, it must be a plugin that got it for us */
if (ctx->response.length) {
@@ -1282,8 +1284,10 @@ wait_response(krb5_context context, int *action, krb5_sendto_ctx ctx)
wait_ctx.timenow = time(NULL);
size_t max_hosts = heim_array_get_length(ctx->hosts);
if (max_hosts == 0) {
heim_array_iterate_f(ctx->hosts, &wait_ctx, wait_setup);
heim_array_filter_f(ctx->hosts, &wait_ctx, wait_filter_dead);
if (heim_array_get_length(ctx->hosts) == 0) {
if (ctx->stateflags & KRBHST_COMPLETED) {
_krb5_debug(context, 5, "no more hosts to send/recv packets to/from "
"trying to pulling more hosts");
@@ -1296,18 +1300,7 @@ wait_response(krb5_context context, int *action, krb5_sendto_ctx ctx)
return 0;
}
wait_ctx.pfds = calloc(max_hosts, sizeof(struct pollfd));
wait_ctx.hosts = calloc(max_hosts, sizeof(struct host *));
if (!wait_ctx.pfds || !wait_ctx.hosts) {
free(wait_ctx.pfds);
free(wait_ctx.hosts);
return ENOMEM;
}
heim_array_filter_f(ctx->hosts, &wait_ctx, wait_filter_dead);
heim_array_iterate_f(ctx->hosts, &wait_ctx, wait_setup);
if (wait_ctx.nfds == 0) {
if (wait_ctx.max_fd == rk_INVALID_SOCKET) {
/*
* If we don't find a host which can make progress, then
* we accelerate the process by moving all of the contestants
@@ -1315,36 +1308,27 @@ wait_response(krb5_context context, int *action, krb5_sendto_ctx ctx)
*/
_krb5_debug(context, 5, "wait_response: moving the contestants forward");
heim_array_iterate_f(ctx->hosts, &wait_ctx, wait_accelerate);
free(wait_ctx.pfds);
free(wait_ctx.hosts);
return 0;
}
ret = poll(wait_ctx.pfds, wait_ctx.nfds, 1000); /* 1s */
tv.tv_sec = 1;
tv.tv_usec = 0;
if (ret < 0) {
free(wait_ctx.pfds);
free(wait_ctx.hosts);
return errno;
}
ret = select(wait_ctx.max_fd + 1, &wait_ctx.rfds, &wait_ctx.wfds, NULL, &tv);
if (ret < 0)
return errno;
if (ret == 0) {
*action = KRB5_SENDTO_TIMEOUT;
free(wait_ctx.pfds);
free(wait_ctx.hosts);
return 0;
*action = KRB5_SENDTO_TIMEOUT;
return 0;
}
wait_ctx.got_reply = 0;
wait_process(&wait_ctx);
heim_array_iterate_f(ctx->hosts, &wait_ctx, wait_process);
if (wait_ctx.got_reply)
*action = KRB5_SENDTO_FILTER;
else
*action = KRB5_SENDTO_CONTINUE;
free(wait_ctx.pfds);
free(wait_ctx.hosts);
return 0;
}
+1 -2294
View File
File diff suppressed because it is too large Load Diff
-37
View File
@@ -239,47 +239,10 @@ check_escaped_strings(void)
krb5_free_context(context);
}
static void
check_dash_underscore(void)
{
krb5_context context;
krb5_config_section *c = NULL;
krb5_error_code ret;
const char *s;
char **ps;
ret = krb5_init_context(&context);
if (ret)
errx(1, "krb5_init_context %d", ret);
ret = krb5_config_parse_file(context, "test_config_strings.out", &c);
if (ret)
krb5_errx(context, 1, "krb5_config_parse_file()");
s = krb5_config_get_string(context, c, "dash-test", "final-value", NULL);
if (s == NULL || strcmp(s, "through-section") != 0)
errx(1, "dash/underscore lookup failed");
ps = krb5_config_get_strings(context, c, "dash-test", "same-name", NULL);
if (ps == NULL ||
ps[0] == NULL || strcmp(ps[0], "first") != 0 ||
ps[1] == NULL || strcmp(ps[1], "second") != 0 ||
ps[2] != NULL)
errx(1, "dash/underscore iteration failed");
krb5_config_free_strings(ps);
ret = krb5_config_file_free(context, c);
if (ret)
krb5_errx(context, 1, "krb5_config_file_free()");
krb5_free_context(context);
}
int
main(int argc, char **argv)
{
check_config_files();
check_escaped_strings();
check_dash_underscore();
return 0;
}
-5
View File
@@ -10,8 +10,3 @@
internal2 = "TownOf Sandwich: Massachusetts"Oldest Town In "Cape Cod"
internal3 = "Begins and"ends In One String
longer_strings = "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. Neither the name of the Institute nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission." "THIS SOFTWARE IS PROVIDED BY THE INSTITUTE 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 INSTITUTE 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." "Why do we test with such long strings? Because some people have config files" That look "Like this."
[dash_test]
final_value = through-section
same_name = first
same-name = second
-90
View File
@@ -63,89 +63,6 @@ test_empty_keytab(krb5_context context, const char *keytab)
krb5_err(context, 1, ret, "krb5_kt_close");
}
static void
test_verify_user_empty_keytab(krb5_context context, const char *keytab)
{
krb5_error_code ret;
krb5_keytab id;
krb5_principal principal;
krb5_verify_opt opt;
ret = krb5_kt_resolve(context, keytab, &id);
if (ret)
krb5_err(context, 1, ret, "krb5_kt_resolve");
ret = krb5_parse_name(context, "lha@SU.SE", &principal);
if (ret)
krb5_err(context, 1, ret, "krb5_parse_name");
krb5_verify_opt_init(&opt);
krb5_verify_opt_set_keytab(&opt, id);
ret = krb5_verify_user_opt(context, principal, "password", &opt);
if (ret != KRB5_KT_NOTFOUND)
krb5_errx(context, 1,
"krb5_verify_user_opt returned %d, expected %d",
(int)ret, (int)KRB5_KT_NOTFOUND);
krb5_free_principal(context, principal);
ret = krb5_kt_close(context, id);
if (ret)
krb5_err(context, 1, ret, "krb5_kt_close");
}
static void
test_verify_user_wrong_keytab(krb5_context context, const char *keytab)
{
krb5_error_code ret;
krb5_keytab id;
krb5_keytab_entry entry;
krb5_principal principal;
krb5_verify_opt opt;
ret = krb5_kt_resolve(context, keytab, &id);
if (ret)
krb5_err(context, 1, ret, "krb5_kt_resolve");
memset(&entry, 0, sizeof(entry));
ret = krb5_parse_name(context, "not-host/foo@SU.SE", &entry.principal);
if (ret)
krb5_err(context, 1, ret, "krb5_parse_name");
entry.vno = 1;
ret = krb5_generate_random_keyblock(context,
ETYPE_AES256_CTS_HMAC_SHA1_96,
&entry.keyblock);
if (ret)
krb5_err(context, 1, ret, "krb5_generate_random_keyblock");
ret = krb5_kt_add_entry(context, id, &entry);
if (ret)
krb5_err(context, 1, ret, "krb5_kt_add_entry");
ret = krb5_parse_name(context, "lha@SU.SE", &principal);
if (ret)
krb5_err(context, 1, ret, "krb5_parse_name");
krb5_verify_opt_init(&opt);
krb5_verify_opt_set_keytab(&opt, id);
ret = krb5_verify_user_opt(context, principal, "password", &opt);
if (ret != KRB5_KT_NOTFOUND)
krb5_errx(context, 1,
"krb5_verify_user_opt returned %d, expected %d",
(int)ret, (int)KRB5_KT_NOTFOUND);
krb5_free_principal(context, principal);
krb5_kt_remove_entry(context, id, &entry);
krb5_free_principal(context, entry.principal);
krb5_free_keyblock_contents(context, &entry.keyblock);
ret = krb5_kt_close(context, id);
if (ret)
krb5_err(context, 1, ret, "krb5_kt_close");
}
/*
* Test that memory keytab are refcounted.
*/
@@ -364,13 +281,6 @@ main(int argc, char **argv)
test_empty_keytab(context, "MEMORY:foo");
test_empty_keytab(context, "FILE:foo");
ret = krb5_set_default_realm(context, "SU.SE");
if (ret)
krb5_err(context, 1, ret, "krb5_set_default_realm");
test_verify_user_empty_keytab(context, "MEMORY:verify-user-empty");
test_verify_user_wrong_keytab(context, "MEMORY:verify-user-wrong");
test_memory_keytab(context, "MEMORY:foo", "MEMORY:foo2");
}
+2 -2
View File
@@ -57,8 +57,8 @@ check_set_time(krb5_context context)
diff2 = krb5_time_abs(sec, tv.tv_sec);
if (diff2 < 9 || diff > 11)
krb5_errx(context, 1, "set time error: diff: %lld",
(long long)krb5_time_abs(sec, tv.tv_sec));
krb5_errx(context, 1, "set time error: diff: %ld",
krb5_time_abs(sec, tv.tv_sec));
}
+1 -44
View File
@@ -33,40 +33,6 @@
#include "krb5_locl.h"
static krb5_error_code
check_server_keytab(krb5_context context, krb5_keytab keytab,
const char *service)
{
krb5_error_code ret, ret2;
krb5_keytab_entry entry;
krb5_keytab kt = keytab;
krb5_principal server;
ret = krb5_sname_to_principal(context, NULL, service, KRB5_NT_SRV_HST,
&server);
if (ret)
return ret;
if (kt == NULL) {
ret = krb5_kt_default(context, &kt);
if (ret)
goto out;
}
ret = krb5_kt_get_entry(context, kt, server, 0, 0, &entry);
if (ret == 0)
krb5_kt_free_entry(context, &entry);
if (keytab == NULL) {
ret2 = krb5_kt_close(context, kt);
if (ret == 0)
ret = ret2;
}
out:
krb5_free_principal(context, server);
return ret;
}
static krb5_error_code
verify_common (krb5_context context,
krb5_principal principal,
@@ -219,16 +185,7 @@ krb5_verify_user_opt(krb5_context context,
const char *password,
krb5_verify_opt *opt)
{
krb5_error_code ret = 0;
#define OPT(V, D) ((opt && (opt->V)) ? (opt->V) : (D))
if (opt == NULL || opt->secure) {
ret = check_server_keytab(context, OPT(keytab, NULL),
OPT(service, "host"));
}
#undef OPT
if (ret)
return ret;
krb5_error_code ret;
if(opt && (opt->flags & KRB5_VERIFY_LREALMS)) {
krb5_realm *realms, *r;
+30
View File
@@ -0,0 +1,30 @@
Copyright (c) 1992, 1993
The Regents of the University of California. All rights reserved.
This code is derived from software contributed to Berkeley by
Christos Zoulas of Cornell University.
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. Neither the name of the University nor the names of its contributors
may be used to endorse or promote products derived from this software
without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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.
+300
View File
@@ -0,0 +1,300 @@
* See also NetBSD changelog:
http://cvsweb.netbsd.org/bsdweb.cgi/src/lib/libedit
2011-02-27 Jess Thrysoee
* version-info: 0:36:0
* all: sync with upstream source.
2010-04-24 Jess Thrysoee
* version-info: 0:35:0
* all: sync with upstream source.
Now with UTF-8 support. To enable this run 'configure --enable-widec'.
For now an UTF-32 encoded wchar_t is required.
This requirement is met on NetBSD, Solaris and OS X for any UTF-8 locale,
and any system that define __STDC_ISO_10646__ (e.g. GNU libc on Linux).
2009-09-23 Jess Thrysoee
* version-info: 0:34:0
* all: apply Apple patches from:
http://opensource.apple.com/source/libedit/libedit-11/patches
2009-09-05 Jess Thrysoee
* version-info: 0:33:0
* all: Use predefined macro __sun to identify Solaris
* src/el.c: Ignore comment lines in .editrc
2009-07-23 Jess Thrysoee
* version-info: 0:32:0
* all: sync with upstream source.
2009-06-10 Jess Thrysoee
* version-info: 0:31:0
* all: sync with upstream source.
2009-05-03 Jess Thrysoee
* version-info: 0:30:0
* all: sync with upstream source.
2009-04-05 Jess Thrysoee
* version-info: 0:29:0
* all: sync with upstream source.
2009-01-11 Jess Thrysoee
* version-info: 0:28:0
* all: sync with upstream source. MAJOR.MINOR version is now 3.0.
This is due to NetBSD changing time_t and dev_t to 64 bits. It does
not really effect this package.
* configure.ac: Remove '--enable-debug' configure flag. The autoconf way
to control flags is by specifying them when running configure,
e.g. 'CFLAGS="-O0 -g" ./configure'
2008-07-12 Jess Thrysoee
* version-info: 0:27:0
* configure.ac: Added '--enable-debug' configure flag, to produce debugging
information.
* examples/fileman.c: cast stat struct members, st_nlink and st_size,
appropriately (see also 'man 2 stat'). Patch by Alex Elder.
* all: sync with upstream source. MINOR version is now 11.
2007-08-31 Jess Thrysoee
* version-info: 0:26:0
* libedit.pc.in,Makefile.am,configure.ac,patches/extra_dist_list.sh:
Added pkg-config support for libedit. Patch by Masatake YAMATO.
2007-08-13 Jess Thrysoee
* version-info: 0:25:0
* all: sync with upstream source.
2007-03-02 Jess Thrysoee
* version-info: 0:24:0
* all: sync with upstream source.
2006-10-22 Jess Thrysoee
* version-info: 0:23:0
* src/shlib_version: Upstream bumped minor version from 9 to 10.
* all: sync with upstream source. More readline functions.
2006-10-22 Jess Thrysoee
* version-info: 0:22:0
* all: sync with upstream source.
2006-08-29 Jess Thrysoee
* version-info: 0:21:0
* all: License cleanup. All 4-clause advertising BSD licenses has been
changed to the 3-clause version by upstream.
* src/fgetln.c: use src/tools/compat/fgetln.c instead of
othersrc/libexec/tnftpd/libnetbsd/fgetln.c
2006-08-16 Jess Thrysoee
* version-info: 0:20:0
* all: sync with upstream source.
2006-06-03 Jess Thrysoee
* version-info: 0:19:0
* COPYING: added global license file
* all: sync with upstream source.
2006-02-13 Jess Thrysoee
* version-info: 0:18:0
* src/readline.c: Partial rl_getc_function support, patch by Kjeld Borch
Egevang.
* src/readline.c: Make write_history and read_history returncode readline
compatible. Upstream patch.
2006-01-03 Jess Thrysoee
* version-info: 0:17:0
* patches/cvs_export.sh: strlcat.c and strlcpy.c was moved to
src/common/lib/libc/string in the upstream cvs repository.
* all: sync with upstream source.
2005-10-22 Jess Thrysoee
* version-info: 0:16:0
* patches/*.patch, configure.ac: define SCCSID, undef LIBC_SCCS. Remove
fourteen cosmetic patches.
* all: sync with upstream source.
2005-09-11 Jess Thrysoee
* version-info: 0:15:0
* src/Makefile.am: fix typo that meant generated files were distributes,
and make generated file targets dependent on the the 'makelist' input
files.
* all: sync with upstream source. This is just a manpage update
2005-08-28 Jess Thrysoee
* version-info: 0:14:0
* src/sys.h: include config.h to avoid "redefinition of
`u_int32_t'". Patch by Norihiko Murase.
* src/search.c: explicitly include sys/types.h, because regex.h on
FreeBSD needs it and does not include it itself. Patch by Norihiko Murase.
* acinclude.m4: added EL_GETPW_R_DRAFT test and use AC_TRY_LINK instead
of AC_TRY_COMPILE. Suggested by Norihiko Murase.
* all: sync with upstream source.
2005-08-16 Jess Thrysoee
* version-info: 0:13:0
* all: sync with upstream source.
2005-08-05 Jess Thrysoee
* version-info: 0:12:0
* all: sync with upstream source.
2005-07-24 Jess Thrysoee
* version-info: 0:11:0
* histedit.h, histedit.c, readline.c, editline/readline.h: From
upstream; added remove_history().
2005-07-07 Jess Thrysoee
* version-info: 0:10:0
* history.c, key.c: From upstream source; Fix memory leaks found by
valgrind.
2005-06-28 Jess Thrysoee
* version-info: 0:9:0
* src/readline.c: getpwent_r is not POSIX, always use getpwent.
Reported by Gerrit P. Haase.
* src/Makefile.am: Added libtool -no-undefined. This is needed on Cygwin
to get a shared editline library. Should not affect other platforms.
Suggested by Gerrit P. Haase.
2005-06-15 Jess Thrysoee
* version-info: 0:8:0
* all: sync with upstream source.
2005-06-01 Jess Thrysoee
* version-info: 0:7:0
* all: sync with upstream source.
* src/readline.c, src/filecomplete.c: Solaris use POSIX draft versions
of getpwent_r, getpwnam_r and getpwuid_r which return 'struct passwd *'.
Define HAVE_GETPW_R_POSIX if these functions are (non draft) POSIX
compatible. Patch by Julien Torrès.
2005-05-28 Jess Thrysoee
* version-info: 0:6:0
* all: sync with upstream source.
2005-03-11 Jess Thrysoee
* version-info: 0:5:0
* all: sync with upstream source.
2004-12-07 Jess Thrysoee
* version-info: 0:4:0
* src/readline.c: d_namlen (in struct dirent) is not portable, always
use strlen. Patch by Scott Rankin.
2004-11-27 Jess Thrysoee
* version-info: 0:3:0
* src/history.c: bug #26785 fixed upstream, removed local patch.
2004-11-06 Jess Thrysoee
* version-info: 0:2:0
* all: sync with upstream source.
* doc/Makefile.am: If mdoc2man fails, remove empty file. Patch by
Darren Tucker.
2004-10-14 Jess Thrysoee
* version-info: 0:1:0
* doc/Makefile.am: 'make install' twice fails. Remove old links before
trying to link the man pages. Patch by Rick Richardson.
2004-09-28 Jess Thrysoee
* version-info: 0:0:0
* acinclude.m4 configure.ac src/Makefile.am: Adhere to
LibTools library interface versions recommendation.
http://www.gnu.org/software/libtool/manual.html#SEC32
* doc/Makefile.am: name all manpage links as el_* (e.g. el_history.3)
to avoid conflicts.
2004-09-08 Jess Thrysoee
* all: Initial package.
+229
View File
@@ -0,0 +1,229 @@
Copyright (C) 1994, 1995, 1996, 1999, 2000, 2001, 2002 Free Software
Foundation, Inc.
This file is free documentation; the Free Software Foundation gives
unlimited permission to copy, distribute and modify it.
Basic Installation
==================
These are generic installation instructions.
The `configure' shell script attempts to guess correct values for
various system-dependent variables used during compilation. It uses
those values to create a `Makefile' in each directory of the package.
It may also create one or more `.h' files containing system-dependent
definitions. Finally, it creates a shell script `config.status' that
you can run in the future to recreate the current configuration, and a
file `config.log' containing compiler output (useful mainly for
debugging `configure').
It can also use an optional file (typically called `config.cache'
and enabled with `--cache-file=config.cache' or simply `-C') that saves
the results of its tests to speed up reconfiguring. (Caching is
disabled by default to prevent problems with accidental use of stale
cache files.)
If you need to do unusual things to compile the package, please try
to figure out how `configure' could check whether to do them, and mail
diffs or instructions to the address given in the `README' so they can
be considered for the next release. If you are using the cache, and at
some point `config.cache' contains results you don't want to keep, you
may remove or edit it.
The file `configure.ac' (or `configure.in') is used to create
`configure' by a program called `autoconf'. You only need
`configure.ac' if you want to change it or regenerate `configure' using
a newer version of `autoconf'.
The simplest way to compile this package is:
1. `cd' to the directory containing the package's source code and type
`./configure' to configure the package for your system. If you're
using `csh' on an old version of System V, you might need to type
`sh ./configure' instead to prevent `csh' from trying to execute
`configure' itself.
Running `configure' takes awhile. While running, it prints some
messages telling which features it is checking for.
2. Type `make' to compile the package.
3. Optionally, type `make check' to run any self-tests that come with
the package.
4. Type `make install' to install the programs and any data files and
documentation.
5. You can remove the program binaries and object files from the
source code directory by typing `make clean'. To also remove the
files that `configure' created (so you can compile the package for
a different kind of computer), type `make distclean'. There is
also a `make maintainer-clean' target, but that is intended mainly
for the package's developers. If you use it, you may have to get
all sorts of other programs in order to regenerate files that came
with the distribution.
Compilers and Options
=====================
Some systems require unusual options for compilation or linking that
the `configure' script does not know about. Run `./configure --help'
for details on some of the pertinent environment variables.
You can give `configure' initial values for configuration parameters
by setting variables in the command line or in the environment. Here
is an example:
./configure CC=c89 CFLAGS=-O2 LIBS=-lposix
*Note Defining Variables::, for more details.
Compiling For Multiple Architectures
====================================
You can compile the package for more than one kind of computer at the
same time, by placing the object files for each architecture in their
own directory. To do this, you must use a version of `make' that
supports the `VPATH' variable, such as GNU `make'. `cd' to the
directory where you want the object files and executables to go and run
the `configure' script. `configure' automatically checks for the
source code in the directory that `configure' is in and in `..'.
If you have to use a `make' that does not support the `VPATH'
variable, you have to compile the package for one architecture at a
time in the source code directory. After you have installed the
package for one architecture, use `make distclean' before reconfiguring
for another architecture.
Installation Names
==================
By default, `make install' will install the package's files in
`/usr/local/bin', `/usr/local/man', etc. You can specify an
installation prefix other than `/usr/local' by giving `configure' the
option `--prefix=PATH'.
You can specify separate installation prefixes for
architecture-specific files and architecture-independent files. If you
give `configure' the option `--exec-prefix=PATH', the package will use
PATH as the prefix for installing programs and libraries.
Documentation and other data files will still use the regular prefix.
In addition, if you use an unusual directory layout you can give
options like `--bindir=PATH' to specify different values for particular
kinds of files. Run `configure --help' for a list of the directories
you can set and what kinds of files go in them.
If the package supports it, you can cause programs to be installed
with an extra prefix or suffix on their names by giving `configure' the
option `--program-prefix=PREFIX' or `--program-suffix=SUFFIX'.
Optional Features
=================
Some packages pay attention to `--enable-FEATURE' options to
`configure', where FEATURE indicates an optional part of the package.
They may also pay attention to `--with-PACKAGE' options, where PACKAGE
is something like `gnu-as' or `x' (for the X Window System). The
`README' should mention any `--enable-' and `--with-' options that the
package recognizes.
For packages that use the X Window System, `configure' can usually
find the X include and library files automatically, but if it doesn't,
you can use the `configure' options `--x-includes=DIR' and
`--x-libraries=DIR' to specify their locations.
Specifying the System Type
==========================
There may be some features `configure' cannot figure out
automatically, but needs to determine by the type of machine the package
will run on. Usually, assuming the package is built to be run on the
_same_ architectures, `configure' can figure that out, but if it prints
a message saying it cannot guess the machine type, give it the
`--build=TYPE' option. TYPE can either be a short name for the system
type, such as `sun4', or a canonical name which has the form:
CPU-COMPANY-SYSTEM
where SYSTEM can have one of these forms:
OS KERNEL-OS
See the file `config.sub' for the possible values of each field. If
`config.sub' isn't included in this package, then this package doesn't
need to know the machine type.
If you are _building_ compiler tools for cross-compiling, you should
use the `--target=TYPE' option to select the type of system they will
produce code for.
If you want to _use_ a cross compiler, that generates code for a
platform different from the build platform, you should specify the
"host" platform (i.e., that on which the generated programs will
eventually be run) with `--host=TYPE'.
Sharing Defaults
================
If you want to set default values for `configure' scripts to share,
you can create a site shell script called `config.site' that gives
default values for variables like `CC', `cache_file', and `prefix'.
`configure' looks for `PREFIX/share/config.site' if it exists, then
`PREFIX/etc/config.site' if it exists. Or, you can set the
`CONFIG_SITE' environment variable to the location of the site script.
A warning: not all `configure' scripts look for a site script.
Defining Variables
==================
Variables not defined in a site shell script can be set in the
environment passed to `configure'. However, some packages may run
configure again during the build, and the customized values of these
variables may be lost. In order to avoid this problem, you should set
them in the `configure' command line, using `VAR=value'. For example:
./configure CC=/usr/local2/bin/gcc
will cause the specified gcc to be used as the C compiler (unless it is
overridden in the site shell script).
`configure' Invocation
======================
`configure' recognizes the following options to control how it
operates.
`--help'
`-h'
Print a summary of the options to `configure', and exit.
`--version'
`-V'
Print the version of Autoconf used to generate the `configure'
script, and exit.
`--cache-file=FILE'
Enable the cache: use and save the results of the tests in FILE,
traditionally `config.cache'. FILE defaults to `/dev/null' to
disable caching.
`--config-cache'
`-C'
Alias for `--cache-file=config.cache'.
`--quiet'
`--silent'
`-q'
Do not print messages saying which checks are being made. To
suppress all normal output, redirect it to `/dev/null' (any error
messages will still be shown).
`--srcdir=DIR'
Look for the package's source code in directory DIR. Usually
`configure' can determine that directory automatically.
`configure' also accepts some other, not widely useful, options. Run
`configure --help' for more details.
+9
View File
@@ -0,0 +1,9 @@
AUTOMAKE_OPTIONS = foreign
#SUBDIRS = src examples doc
SUBDIRS = src
#EXTRA_DIST = libedit.pc.in
#pkgconfigdir = $(libdir)/pkgconfig
#pkgconfig_DATA = libedit.pc
+1
View File
@@ -0,0 +1 @@
Thanks to the NetBSD Project maintainers of libedit!
+66
View File
@@ -0,0 +1,66 @@
dnl
dnl read lib version from file (and trim trailing newline)
dnl
define([EL_RELEASE], [patsubst(esyscmd([. src/shlib_version; echo $major.$minor]), [
])])
dnl
dnl read cvsexport timestamp from file (and trim trailing newline)
dnl
define([EL_TIMESTAMP], [patsubst(esyscmd([date +"%Y%m%d"]), [
])])
dnl
dnl NetBSD use the -mdoc macro package for manpages, but e.g.
dnl AIX and Solaris only support the -man package.
dnl
AC_DEFUN([EL_MANTYPE],
[
MANTYPE=
TestPath="/usr/bin${PATH_SEPARATOR}/usr/ucb"
AC_PATH_PROGS(NROFF, nroff awf, /bin/false, $TestPath)
if ${NROFF} -mdoc ${srcdir}/doc/editrc.5.roff >/dev/null 2>&1; then
MANTYPE=mdoc
fi
AC_SUBST(MANTYPE)
])
dnl
dnl Check if getpwnam_r and getpwuid_r are POSIX.1 compatible
dnl POSIX draft version returns 'struct passwd *' (used on Solaris)
dnl NOTE: getpwent_r is not POSIX so we always use getpwent
dnl
AC_DEFUN([EL_GETPW_R_POSIX],
[
AC_MSG_CHECKING([whether getpwnam_r and getpwuid_r are posix like])
# The prototype for the POSIX version is:
# int getpwnam_r(char *, struct passwd *, char *, size_t, struct passwd **)
# int getpwuid_r(uid_t, struct passwd *, char *, size_t, struct passwd **);
AC_TRY_LINK([#include <stdlib.h>
#include <sys/types.h>
#include <pwd.h>],
[getpwnam_r(NULL, NULL, NULL, (size_t)0, NULL);
getpwuid_r((uid_t)0, NULL, NULL, (size_t)0, NULL);],
[AC_DEFINE([HAVE_GETPW_R_POSIX], 1, [Define to 1 if you have getpwnam_r and getpwuid_r that are POSIX.1 compatible.])
AC_MSG_RESULT(yes)],
[AC_MSG_RESULT(no)])
])
AC_DEFUN([EL_GETPW_R_DRAFT],
[
AC_MSG_CHECKING([whether getpwnam_r and getpwuid_r are posix _draft_ like])
# The prototype for the POSIX draft version is:
# struct passwd *getpwuid_r(uid_t, struct passwd *, char *, int);
# struct passwd *getpwnam_r(char *, struct passwd *, char *, int);
AC_TRY_LINK([#include <stdlib.h>
#include <sys/types.h>
#include <pwd.h>],
[getpwnam_r(NULL, NULL, NULL, (size_t)0);
getpwuid_r((uid_t)0, NULL, NULL, (size_t)0);],
[AC_DEFINE([HAVE_GETPW_R_DRAFT], 1, [Define to 1 if you have getpwnam_r and getpwuid_r that are draft POSIX.1 versions.])
AC_MSG_RESULT(yes)],
[AC_MSG_RESULT(no)])
])
+282
View File
@@ -0,0 +1,282 @@
/* config.h.in. Generated from configure.ac by autoheader. */
/* Define to 1 if you have the <curses.h> header file. */
#undef HAVE_CURSES_H
/* Define to 1 if you have the <dirent.h> header file, and it defines `DIR'.
*/
#undef HAVE_DIRENT_H
/* Define to 1 if you have the <dlfcn.h> header file. */
#undef HAVE_DLFCN_H
/* Define to 1 if you have the <fcntl.h> header file. */
#undef HAVE_FCNTL_H
/* Define to 1 if you have the `fork' function. */
#undef HAVE_FORK
/* Define to 1 if you have the `getline' function. */
#undef HAVE_GETLINE
/* Define to 1 if you have getpwnam_r and getpwuid_r that are draft POSIX.1
versions. */
#undef HAVE_GETPW_R_DRAFT
/* Define to 1 if you have getpwnam_r and getpwuid_r that are POSIX.1
compatible. */
#undef HAVE_GETPW_R_POSIX
/* Define to 1 if you have the <inttypes.h> header file. */
#undef HAVE_INTTYPES_H
/* Define to 1 if you have the `isascii' function. */
#undef HAVE_ISASCII
/* Define to 1 if you have the `issetugid' function. */
#undef HAVE_ISSETUGID
/* Define to 1 if you have the `curses' library (-lcurses). */
#undef HAVE_LIBCURSES
/* Define to 1 if you have the `ncurses' library (-lncurses). */
#undef HAVE_LIBNCURSES
/* Define to 1 if you have the `tinfo' library (-ltinfo). */
#undef HAVE_LIBTINFO
/* Define to 1 if you have the <limits.h> header file. */
#undef HAVE_LIMITS_H
/* Define to 1 if you have the <minix/config.h> header file. */
#undef HAVE_MINIX_CONFIG_H
/* Define to 1 if you have the <ncurses.h> header file. */
#undef HAVE_NCURSES_H
/* Define to 1 if you have the <ndir.h> header file, and it defines `DIR'. */
#undef HAVE_NDIR_H
/* Define to 1 if if your system has SIZE_MAX */
#undef HAVE_SIZE_MAX
/* Define to 1 if `stat' has the bug that it succeeds when given the
zero-length file name argument. */
#undef HAVE_STAT_EMPTY_STRING_BUG
/* Define to 1 if you have the <stdint.h> header file. */
#undef HAVE_STDINT_H
/* Define to 1 if you have the <stdio.h> header file. */
#undef HAVE_STDIO_H
/* Define to 1 if you have the <stdlib.h> header file. */
#undef HAVE_STDLIB_H
/* Define to 1 if you have the <strings.h> header file. */
#undef HAVE_STRINGS_H
/* Define to 1 if you have the <string.h> header file. */
#undef HAVE_STRING_H
/* Define to 1 if struct dirent has member d_namlen */
#undef HAVE_STRUCT_DIRENT_D_NAMLEN
/* Define to 1 if you have the <sys/cdefs.h> header file. */
#undef HAVE_SYS_CDEFS_H
/* Define to 1 if you have the <sys/dir.h> header file, and it defines `DIR'.
*/
#undef HAVE_SYS_DIR_H
/* Define to 1 if you have the <sys/ioctl.h> header file. */
#undef HAVE_SYS_IOCTL_H
/* Define to 1 if you have the <sys/ndir.h> header file, and it defines `DIR'.
*/
#undef HAVE_SYS_NDIR_H
/* Define to 1 if you have the <sys/param.h> header file. */
#undef HAVE_SYS_PARAM_H
/* Define to 1 if you have the <sys/stat.h> header file. */
#undef HAVE_SYS_STAT_H
/* Define to 1 if you have the <sys/types.h> header file. */
#undef HAVE_SYS_TYPES_H
/* Define to 1 if you have <sys/wait.h> that is POSIX.1 compatible. */
#undef HAVE_SYS_WAIT_H
/* Define to 1 if you have the <term.h> header file. */
#undef HAVE_TERM_H
/* Define to 1 if you have the <unistd.h> header file. */
#undef HAVE_UNISTD_H
/* Define to 1 if the system has the type `u_int32_t'. */
#undef HAVE_U_INT32_T
/* Define to 1 if you have the `vfork' function. */
#undef HAVE_VFORK
/* Define to 1 if you have the <vfork.h> header file. */
#undef HAVE_VFORK_H
/* Define to 1 if you have the <wchar.h> header file. */
#undef HAVE_WCHAR_H
/* Define to 1 if you have the `wcsdup' function. */
#undef HAVE_WCSDUP
/* Define to 1 if `fork' works. */
#undef HAVE_WORKING_FORK
/* Define to 1 if `vfork' works. */
#undef HAVE_WORKING_VFORK
/* Define to 1 if `lstat' dereferences a symlink specified with a trailing
slash. */
#undef LSTAT_FOLLOWS_SLASHED_SYMLINK
/* Define to the sub-directory where libtool stores uninstalled libraries. */
#undef LT_OBJDIR
/* Name of package */
#undef PACKAGE
/* Define to the address where bug reports for this package should be sent. */
#undef PACKAGE_BUGREPORT
/* Define to the full name of this package. */
#undef PACKAGE_NAME
/* Define to the full name and version of this package. */
#undef PACKAGE_STRING
/* Define to the one symbol short name of this package. */
#undef PACKAGE_TARNAME
/* Define to the home page for this package. */
#undef PACKAGE_URL
/* Define to the version of this package. */
#undef PACKAGE_VERSION
/* Define as the return type of signal handlers (`int' or `void'). */
#undef RETSIGTYPE
/* Define to 1 if all of the C90 standard headers exist (not just the ones
required in a freestanding environment). This macro is provided for
backward compatibility; new code need not use it. */
#undef STDC_HEADERS
/* Enable extensions on AIX 3, Interix. */
#ifndef _ALL_SOURCE
# undef _ALL_SOURCE
#endif
/* Enable general extensions on macOS. */
#ifndef _DARWIN_C_SOURCE
# undef _DARWIN_C_SOURCE
#endif
/* Enable general extensions on Solaris. */
#ifndef __EXTENSIONS__
# undef __EXTENSIONS__
#endif
/* Enable GNU extensions on systems that have them. */
#ifndef _GNU_SOURCE
# undef _GNU_SOURCE
#endif
/* Enable X/Open compliant socket functions that do not require linking
with -lxnet on HP-UX 11.11. */
#ifndef _HPUX_ALT_XOPEN_SOCKET_API
# undef _HPUX_ALT_XOPEN_SOCKET_API
#endif
/* Identify the host operating system as Minix.
This macro does not affect the system headers' behavior.
A future release of Autoconf may stop defining this macro. */
#ifndef _MINIX
# undef _MINIX
#endif
/* Enable general extensions on NetBSD.
Enable NetBSD compatibility extensions on Minix. */
#ifndef _NETBSD_SOURCE
# undef _NETBSD_SOURCE
#endif
/* Enable OpenBSD compatibility extensions on NetBSD.
Oddly enough, this does nothing on OpenBSD. */
#ifndef _OPENBSD_SOURCE
# undef _OPENBSD_SOURCE
#endif
/* Define to 1 if needed for POSIX-compatible behavior. */
#ifndef _POSIX_SOURCE
# undef _POSIX_SOURCE
#endif
/* Define to 2 if needed for POSIX-compatible behavior. */
#ifndef _POSIX_1_SOURCE
# undef _POSIX_1_SOURCE
#endif
/* Enable POSIX-compatible threading on Solaris. */
#ifndef _POSIX_PTHREAD_SEMANTICS
# undef _POSIX_PTHREAD_SEMANTICS
#endif
/* Enable extensions specified by ISO/IEC TS 18661-5:2014. */
#ifndef __STDC_WANT_IEC_60559_ATTRIBS_EXT__
# undef __STDC_WANT_IEC_60559_ATTRIBS_EXT__
#endif
/* Enable extensions specified by ISO/IEC TS 18661-1:2014. */
#ifndef __STDC_WANT_IEC_60559_BFP_EXT__
# undef __STDC_WANT_IEC_60559_BFP_EXT__
#endif
/* Enable extensions specified by ISO/IEC TS 18661-2:2015. */
#ifndef __STDC_WANT_IEC_60559_DFP_EXT__
# undef __STDC_WANT_IEC_60559_DFP_EXT__
#endif
/* Enable extensions specified by ISO/IEC TS 18661-4:2015. */
#ifndef __STDC_WANT_IEC_60559_FUNCS_EXT__
# undef __STDC_WANT_IEC_60559_FUNCS_EXT__
#endif
/* Enable extensions specified by ISO/IEC TS 18661-3:2015. */
#ifndef __STDC_WANT_IEC_60559_TYPES_EXT__
# undef __STDC_WANT_IEC_60559_TYPES_EXT__
#endif
/* Enable extensions specified by ISO/IEC TR 24731-2:2010. */
#ifndef __STDC_WANT_LIB_EXT2__
# undef __STDC_WANT_LIB_EXT2__
#endif
/* Enable extensions specified by ISO/IEC 24747:2009. */
#ifndef __STDC_WANT_MATH_SPEC_FUNCS__
# undef __STDC_WANT_MATH_SPEC_FUNCS__
#endif
/* Enable extensions on HP NonStop. */
#ifndef _TANDEM_SOURCE
# undef _TANDEM_SOURCE
#endif
/* Enable X/Open extensions. Define to 500 only if necessary
to make mbstate_t available. */
#ifndef _XOPEN_SOURCE
# undef _XOPEN_SOURCE
#endif
/* Version number of package */
#undef VERSION
/* Define to empty if `const' does not conform to ANSI C. */
#undef const
/* Define as a signed integer type capable of holding a process identifier. */
#undef pid_t
/* Define to `unsigned int' if <sys/types.h> does not define. */
#undef size_t
/* Define as `fork' if `vfork' does not work. */
#undef vfork
#include "sys.h"
#define SCCSID
#undef LIBC_SCCS
#define lint
+111
View File
@@ -0,0 +1,111 @@
# -*- Autoconf -*-
# Process this file with autoconf to produce a configure script.
#
# Compile with debug symbols:
# CFLAGS="-ggdb -pedandic -O0" ./configure
# CFLAGS="-ggdb -Wall -Wextra -pedantic -O0" ./configure
#
# Verbose output can be enabled with
# "./configure --disable-silent-rules" or "make V=1"
#
AC_PREREQ(2.61)
AC_INIT(libedit, [EL_RELEASE],, libedit-[EL_TIMESTAMP])
AC_CONFIG_SRCDIR([src/el.c])
AC_CONFIG_HEADER([config.h])
# features of Posix that are extensions to C (define _GNU_SOURCE)
AC_USE_SYSTEM_EXTENSIONS
AM_INIT_AUTOMAKE
AM_MAINTAINER_MODE
AC_PROG_LIBTOOL
# libtool -version-info
AC_SUBST(LT_VERSION, [0:36:0])
m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES([yes])])
# Checks for programs.
AC_PROG_CC_C99
#AC_PROG_CC
AC_PROG_LN_S
AC_PROG_AWK
EL_MANTYPE
AC_CHECK_LIB(curses, tgetent,,
[AC_CHECK_LIB(ncurses, tgetent,,
[AC_CHECK_LIB(tinfo, tgetent,,
[AC_MSG_ERROR([libcurses, libncurses, or tinfo are required!])] )] )] )
# Checks for header files.
AC_HEADER_DIRENT
AC_HEADER_STDC
AC_HEADER_SYS_WAIT
AC_CHECK_HEADERS([fcntl.h limits.h stdint.h stdlib.h string.h sys/ioctl.h sys/param.h unistd.h curses.h ncurses.h sys/cdefs.h])
AC_CHECK_HEADER([termios.h], [], [AC_MSG_ERROR([termios.h is required!])],[])
## include curses.h to prevent "Present But Cannot Be Compiled"
AC_CHECK_HEADERS([term.h],,,
[[#if HAVE_CURSES_H
# include <curses.h>
#elif HAVE_NCURSES_H
# include <ncurses.h>
#endif
]])
# Checks for typedefs, structures, and compiler characteristics.
AC_C_CONST
AC_TYPE_PID_T
AC_TYPE_SIZE_T
AC_CHECK_TYPES([u_int32_t])
AC_TRY_COMPILE([
#include <limits.h>
#include <stddef.h>
#if HAVE_STDINT_H
# include <stdint.h>
#endif
],
[size_t x = SIZE_MAX;],
[have_size_max=yes],
[have_size_max=no])
if test "$have_size_max" = yes; then
AC_DEFINE([HAVE_SIZE_MAX], [1],
[Define to 1 if if your system has SIZE_MAX])
fi
# Checks for library functions.
AC_FUNC_FORK
AC_PROG_GCC_TRADITIONAL
## _AIX is offended by rpl_malloc and rpl_realloc
#AC_FUNC_MALLOC
#AC_FUNC_REALLOC
AC_TYPE_SIGNAL
AC_FUNC_STAT
AC_CHECK_FUNCS([getline isascii issetugid wcsdup])
EL_GETPW_R_POSIX
EL_GETPW_R_DRAFT
AC_CHECK_MEMBER(struct dirent.d_namlen,
AC_DEFINE([HAVE_STRUCT_DIRENT_D_NAMLEN],[1],
[Define to 1 if struct dirent has member d_namlen]),,
[#if HAVE_DIRENT_H
#include <dirent.h>
#endif
])
AH_BOTTOM([
#include "sys.h"
#define SCCSID
#undef LIBC_SCCS
#define lint
])
AC_CONFIG_FILES([Makefile
src/Makefile
])
AC_OUTPUT
+33
View File
@@ -0,0 +1,33 @@
EL_MANS = editline.3 editrc.5
man_MANS = $(EL_MANS)
EL_MAN_LINKS = el_init.3 el_end.3 el_reset.3 el_gets.3 el_getc.3 \
el_push.3 el_parse.3 el_set.3 el_get.3 el_source.3 \
el_resize.3 el_line.3 el_insertstr.3 el_deletestr.3 \
el_history_init.3 el_history_end.3 el_history.3 el_tok_init.3 \
el_tok_end.3 el_tok_reset.3 el_tok_line.3 el_tok_str.3
install-data-hook: $(EL_MAN_LINKS)
$(EL_MAN_LINKS):
(cd $(DESTDIR)$(man3dir) && rm -f $@ && $(LN_S) editline.3 $@)
$(EL_MANS):
@if test "$(MANTYPE)" = "mdoc"; then\
cp $(srcdir)/$@.roff $@;\
else\
$(AWK) -f $(srcdir)/mdoc2man.awk $(srcdir)/$@.roff > $@ || rm -f $@;\
fi;
uninstall-local:
(cd $(DESTDIR)$(man3dir) && rm -f $(EL_MAN_LINKS))
CLEANFILES = $(EL_MANS)
EXTRA_DIST = editline.3.roff editrc.5.roff mdoc2man.awk
changelog.txt: ../ChangeLog
@sed 's/@/ (at)/g; s/&/\&amp;/g; s/</\&lt;/g; s/>/\&gt;/g;' $(srcdir)/$< > $@;
+883
View File
@@ -0,0 +1,883 @@
.\" $NetBSD: editline.3,v 1.74 2010/12/16 17:42:28 wiz Exp $
.\"
.\" Copyright (c) 1997-2003 The NetBSD Foundation, Inc.
.\" All rights reserved.
.\"
.\" This file was contributed to The NetBSD Foundation by Luke Mewburn.
.\"
.\" Redistribution and use in source and binary forms, with or without
.\" modification, are permitted provided that the following conditions
.\" are met:
.\" 1. Redistributions of source code must retain the above copyright
.\" notice, this list of conditions and the following disclaimer.
.\" 2. Redistributions in binary form must reproduce the above copyright
.\" notice, this list of conditions and the following disclaimer in the
.\" documentation and/or other materials provided with the distribution.
.\"
.\" THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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 January 3, 2010
.Dt EDITLINE 3
.Os
.Sh NAME
.Nm editline ,
.Nm el_init ,
.Nm el_end ,
.Nm el_reset ,
.Nm el_gets ,
.Nm el_wgets ,
.Nm el_getc ,
.Nm el_wgetc ,
.Nm el_push ,
.Nm el_wpush ,
.Nm el_parse ,
.Nm el_wparse ,
.Nm el_set ,
.Nm el_wset ,
.Nm el_get ,
.Nm el_wget ,
.Nm el_source ,
.Nm el_resize ,
.Nm el_line ,
.Nm el_wline ,
.Nm el_insertstr ,
.Nm el_winsertstr ,
.Nm el_deletestr ,
.Nm el_wdeletestr ,
.Nm history_init ,
.Nm history_winit ,
.Nm history_end ,
.Nm history_wend ,
.Nm history ,
.Nm history_w ,
.Nm tok_init ,
.Nm tok_winit ,
.Nm tok_end ,
.Nm tok_wend ,
.Nm tok_reset ,
.Nm tok_wreset ,
.Nm tok_line ,
.Nm tok_wline ,
.Nm tok_str
.Nm tok_wstr
.Nd line editor, history and tokenization functions
.Sh LIBRARY
.Lb libedit
.Sh SYNOPSIS
.In histedit.h
.Ft EditLine *
.Fn el_init "const char *prog" "FILE *fin" "FILE *fout" "FILE *ferr"
.Ft void
.Fn el_end "EditLine *e"
.Ft void
.Fn el_reset "EditLine *e"
.Ft const char *
.Fn el_gets "EditLine *e" "int *count"
.Ft const wchar_t *
.Fn el_wgets "EditLine *e" "int *count"
.Ft int
.Fn el_getc "EditLine *e" "char *ch"
.Ft int
.Fn el_wgetc "EditLine *e" "wchar_t *ch"
.Ft void
.Fn el_push "EditLine *e" "const char *str"
.Ft void
.Fn el_wpush "EditLine *e" "const wchar_t *str"
.Ft int
.Fn el_parse "EditLine *e" "int argc" "const char *argv[]"
.Ft int
.Fn el_wparse "EditLine *e" "int argc" "const wchar_t *argv[]"
.Ft int
.Fn el_set "EditLine *e" "int op" "..."
.Ft int
.Fn el_wset "EditLine *e" "int op" "..."
.Ft int
.Fn el_get "EditLine *e" "int op" "..."
.Ft int
.Fn el_wget "EditLine *e" "int op" "..."
.Ft int
.Fn el_source "EditLine *e" "const char *file"
.Ft void
.Fn el_resize "EditLine *e"
.Ft const LineInfo *
.Fn el_line "EditLine *e"
.Ft int
.Fn el_insertstr "EditLine *e" "const char *str"
.Ft int
.Fn el_winsertstr "EditLine *e" "const wchar_t *str"
.Ft void
.Fn el_deletestr "EditLine *e" "int count"
.Ft void
.Fn el_wdeletestr "EditLine *e" "int count"
.Ft History *
.Fn history_init
.Ft HistoryW *
.Fn history_winit
.Ft void
.Fn history_end "History *h"
.Ft void
.Fn history_wend "HistoryW *h"
.Ft int
.Fn history "History *h" "HistEvent *ev" "int op" "..."
.Ft int
.Fn history_w "HistoryW *h" "HistEventW *ev" "int op" "..."
.Ft Tokenizer *
.Fn tok_init "const char *IFS"
.Ft TokenizerW *
.Fn tok_winit "const wchar_t *IFS"
.Ft void
.Fn tok_end "Tokenizer *t"
.Ft void
.Fn tok_wend "TokenizerW *t"
.Ft void
.Fn tok_reset "Tokenizer *t"
.Ft void
.Fn tok_wreset "TokenizerW *t"
.Ft int
.Fn tok_line "Tokenizer *t" "const LineInfo *li" "int *argc" "const char **argv[]" "int *cursorc" "int *cursoro"
.Ft int
.Fn tok_wline "TokenizerW *t" "const LineInfoW *li" "int *argc" "const wchar_t **argv[]" "int *cursorc" "int *cursoro"
.Ft int
.Fn tok_str "Tokenizer *t" "const char *str" "int *argc" "const char **argv[]"
.Ft int
.Fn tok_wstr "TokenizerW *t" "const wchar_t *str" "int *argc" "const wchar_t **argv[]"
.Sh DESCRIPTION
The
.Nm
library provides generic line editing, history and tokenization functions,
similar to those found in
.Xr sh 1 .
.Pp
These functions are available in the
.Nm libedit
library (which needs the
.Nm libtermcap
library).
Programs should be linked with
.Fl ledit ltermcap .
.Sh LINE EDITING FUNCTIONS
The line editing functions use a common data structure,
.Fa EditLine ,
which is created by
.Fn el_init
and freed by
.Fn el_end .
.Pp
The wide-character functions behave the same way as their narrow
counterparts.
.Pp
The following functions are available:
.Bl -tag -width 4n
.It Fn el_init
Initialise the line editor, and return a data structure
to be used by all other line editing functions.
.Fa prog
is the name of the invoking program, used when reading the
.Xr editrc 5
file to determine which settings to use.
.Fa fin ,
.Fa fout
and
.Fa ferr
are the input, output, and error streams (respectively) to use.
In this documentation, references to
.Dq the tty
are actually to this input/output stream combination.
.It Fn el_end
Clean up and finish with
.Fa e ,
assumed to have been created with
.Fn el_init .
.It Fn el_reset
Reset the tty and the parser.
This should be called after an error which may have upset the tty's
state.
.It Fn el_gets
Read a line from the tty.
.Fa count
is modified to contain the number of characters read.
Returns the line read if successful, or
.Dv NULL
if no characters were read or if an error occurred.
If an error occurred,
.Fa count
is set to \-1 and
.Dv errno
contains the error code that caused it.
The return value may not remain valid across calls to
.Fn el_gets
and must be copied if the data is to be retained.
.It Fn el_getc
Read a character from the tty.
.Fa ch
is modified to contain the character read.
Returns the number of characters read if successful, \-1 otherwise.
.It Fn el_push
Pushes
.Fa str
back onto the input stream.
This is used by the macro expansion mechanism.
Refer to the description of
.Ic bind
.Fl s
in
.Xr editrc 5
for more information.
.It Fn el_parse
Parses the
.Fa argv
array (which is
.Fa argc
elements in size)
to execute builtin
.Nm
commands.
If the command is prefixed with
.Dq prog :
then
.Fn el_parse
will only execute the command if
.Dq prog
matches the
.Fa prog
argument supplied to
.Fn el_init .
The return value is
\-1 if the command is unknown,
0 if there was no error or
.Dq prog
didn't match, or
1 if the command returned an error.
Refer to
.Xr editrc 5
for more information.
.It Fn el_set
Set
.Nm
parameters.
.Fa op
determines which parameter to set, and each operation has its
own parameter list.
.Pp
The following values for
.Fa op
are supported, along with the required argument list:
.Bl -tag -width 4n
.It Dv EL_PROMPT , Fa "char *(*f)(EditLine *)"
Define prompt printing function as
.Fa f ,
which is to return a string that contains the prompt.
.It Dv EL_PROMPT_ESC , Fa "char *(*f)(EditLine *)" , Fa "char c"
Same as
.Dv EL_PROMPT ,
but the
.Fa c
argument indicates the start/stop literal prompt character.
.Pp
If a start/stop literal character is found in the prompt, the
character itself
is not printed, but characters after it are printed directly to the
terminal without affecting the state of the current line.
A subsequent second start/stop literal character ends this behavior.
This is typically used to embed literal escape sequences that change the
color/style of the terminal in the prompt.
.Dv 0
unsets it.
.It Dv EL_REFRESH
Re-display the current line on the next terminal line.
.It Dv EL_RPROMPT , Fa "char *(*f)(EditLine *)"
Define right side prompt printing function as
.Fa f ,
which is to return a string that contains the prompt.
.It Dv EL_RPROMPT_ESC , Fa "char *(*f)(EditLine *)" , Fa "char c"
Define the right prompt printing function but with a literal escape character.
.It Dv EL_TERMINAL , Fa "const char *type"
Define terminal type of the tty to be
.Fa type ,
or to
.Ev TERM
if
.Fa type
is
.Dv NULL .
.It Dv EL_EDITOR , Fa "const char *mode"
Set editing mode to
.Fa mode ,
which must be one of
.Dq emacs
or
.Dq vi .
.It Dv EL_SIGNAL , Fa "int flag"
If
.Fa flag
is non-zero,
.Nm
will install its own signal handler for the following signals when
reading command input:
.Dv SIGCONT ,
.Dv SIGHUP ,
.Dv SIGINT ,
.Dv SIGQUIT ,
.Dv SIGSTOP ,
.Dv SIGTERM ,
.Dv SIGTSTP ,
and
.Dv SIGWINCH .
Otherwise, the current signal handlers will be used.
.It Dv EL_BIND , Fa "const char *" , Fa "..." , Dv NULL
Perform the
.Ic bind
builtin command.
Refer to
.Xr editrc 5
for more information.
.It Dv EL_ECHOTC , Fa "const char *" , Fa "..." , Dv NULL
Perform the
.Ic echotc
builtin command.
Refer to
.Xr editrc 5
for more information.
.It Dv EL_SETTC , Fa "const char *" , Fa "..." , Dv NULL
Perform the
.Ic settc
builtin command.
Refer to
.Xr editrc 5
for more information.
.It Dv EL_SETTY , Fa "const char *" , Fa "..." , Dv NULL
Perform the
.Ic setty
builtin command.
Refer to
.Xr editrc 5
for more information.
.It Dv EL_TELLTC , Fa "const char *" , Fa "..." , Dv NULL
Perform the
.Ic telltc
builtin command.
Refer to
.Xr editrc 5
for more information.
.It Dv EL_ADDFN , Fa "const char *name" , Fa "const char *help" , \
Fa "unsigned char (*func)(EditLine *e, int ch)"
Add a user defined function,
.Fn func ,
referred to as
.Fa name
which is invoked when a key which is bound to
.Fa name
is entered.
.Fa help
is a description of
.Fa name .
At invocation time,
.Fa ch
is the key which caused the invocation.
The return value of
.Fn func
should be one of:
.Bl -tag -width "CC_REDISPLAY"
.It Dv CC_NORM
Add a normal character.
.It Dv CC_NEWLINE
End of line was entered.
.It Dv CC_EOF
EOF was entered.
.It Dv CC_ARGHACK
Expecting further command input as arguments, do nothing visually.
.It Dv CC_REFRESH
Refresh display.
.It Dv CC_REFRESH_BEEP
Refresh display, and beep.
.It Dv CC_CURSOR
Cursor moved, so update and perform
.Dv CC_REFRESH .
.It Dv CC_REDISPLAY
Redisplay entire input line.
This is useful if a key binding outputs extra information.
.It Dv CC_ERROR
An error occurred.
Beep, and flush tty.
.It Dv CC_FATAL
Fatal error, reset tty to known state.
.El
.It Dv EL_HIST , Fa "History *(*func)(History *, int op, ...)" , \
Fa "const char *ptr"
Defines which history function to use, which is usually
.Fn history .
.Fa ptr
should be the value returned by
.Fn history_init .
.It Dv EL_EDITMODE , Fa "int flag"
If
.Fa flag
is non-zero,
editing is enabled (the default).
Note that this is only an indication, and does not
affect the operation of
.Nm .
At this time, it is the caller's responsibility to
check this
(using
.Fn el_get )
to determine if editing should be enabled or not.
.It Dv EL_GETCFN , Fa "int (*f)(EditLine *, char *c)"
Define the character reading function as
.Fa f ,
which is to return the number of characters read and store them in
.Fa c .
This function is called internally by
.Fn el_gets
and
.Fn el_getc .
The builtin function can be set or restored with the special function
name
.Dq Dv EL_BUILTIN_GETCFN .
.It Dv EL_CLIENTDATA , Fa "void *data"
Register
.Fa data
to be associated with this EditLine structure.
It can be retrieved with the corresponding
.Fn el_get
call.
.It Dv EL_SETFP , Fa "int fd" , Fa "FILE *fp"
Set the current
.Nm editline
file pointer for
.Dq input
.Fa fd
=
.Dv 0 ,
.Dq output
.Fa fd
=
.Dv 1 ,
or
.Dq error
.Fa fd
=
.Dv 2
from
.Fa fp .
.El
.It Fn el_get
Get
.Nm
parameters.
.Fa op
determines which parameter to retrieve into
.Fa result .
Returns 0 if successful, \-1 otherwise.
.Pp
The following values for
.Fa op
are supported, along with actual type of
.Fa result :
.Bl -tag -width 4n
.It Dv EL_PROMPT , Fa "char *(*f)(EditLine *)" , Fa "char *c"
Return a pointer to the function that displays the prompt in
.Fa f .
If
.Fa c
is not
.Dv NULL ,
return the start/stop literal prompt character in it.
.It Dv EL_RPROMPT , Fa "char *(*f)(EditLine *)" , Fa "char *c"
Return a pointer to the function that displays the prompt in
.Fa f .
If
.Fa c
is not
.Dv NULL ,
return the start/stop literal prompt character in it.
.It Dv EL_EDITOR , Fa "const char **"
Return the name of the editor, which will be one of
.Dq emacs
or
.Dq vi .
.It Dv EL_GETTC , Fa "const char *name" , Fa "void *value"
Return non-zero if
.Fa name
is a valid
.Xr termcap 5
capability
and set
.Fa value
to the current value of that capability.
.It Dv EL_SIGNAL , Fa "int *"
Return non-zero if
.Nm
has installed private signal handlers (see
.Fn el_get
above).
.It Dv EL_EDITMODE , Fa "int *"
Return non-zero if editing is enabled.
.It Dv EL_GETCFN , Fa "int (**f)(EditLine *, char *)"
Return a pointer to the function that read characters, which is equal to
.Dq Dv EL_BUILTIN_GETCFN
in the case of the default builtin function.
.It Dv EL_CLIENTDATA , Fa "void **data"
Retrieve
.Fa data
previously registered with the corresponding
.Fn el_set
call.
.It Dv EL_UNBUFFERED , Fa "int"
Sets or clears unbuffered mode.
In this mode,
.Fn el_gets
will return immediately after processing a single character.
.It Dv EL_PREP_TERM , Fa "int"
Sets or clears terminal editing mode.
.It Dv EL_GETFP , Fa "int fd", Fa "FILE **fp"
Return in
.Fa fp
the current
.Nm editline
file pointer for
.Dq input
.Fa fd
=
.Dv 0 ,
.Dq output
.Fa fd
=
.Dv 1 ,
or
.Dq error
.Fa fd
=
.Dv 2 .
.El
.It Fn el_source
Initialise
.Nm
by reading the contents of
.Fa file .
.Fn el_parse
is called for each line in
.Fa file .
If
.Fa file
is
.Dv NULL ,
try
.Pa $PWD/.editrc
then
.Pa $HOME/.editrc .
Refer to
.Xr editrc 5
for details on the format of
.Fa file .
.It Fn el_resize
Must be called if the terminal size changes.
If
.Dv EL_SIGNAL
has been set with
.Fn el_set ,
then this is done automatically.
Otherwise, it's the responsibility of the application to call
.Fn el_resize
on the appropriate occasions.
.It Fn el_line
Return the editing information for the current line in a
.Fa LineInfo
structure, which is defined as follows:
.Bd -literal
typedef struct lineinfo {
const char *buffer; /* address of buffer */
const char *cursor; /* address of cursor */
const char *lastchar; /* address of last character */
} LineInfo;
.Ed
.Pp
.Fa buffer
is not NUL terminated.
This function may be called after
.Fn el_gets
to obtain the
.Fa LineInfo
structure pertaining to line returned by that function,
and from within user defined functions added with
.Dv EL_ADDFN .
.It Fn el_insertstr
Insert
.Fa str
into the line at the cursor.
Returns \-1 if
.Fa str
is empty or won't fit, and 0 otherwise.
.It Fn el_deletestr
Delete
.Fa count
characters before the cursor.
.El
.Sh HISTORY LIST FUNCTIONS
The history functions use a common data structure,
.Fa History ,
which is created by
.Fn history_init
and freed by
.Fn history_end .
.Pp
The following functions are available:
.Bl -tag -width 4n
.It Fn history_init
Initialise the history list, and return a data structure
to be used by all other history list functions.
.It Fn history_end
Clean up and finish with
.Fa h ,
assumed to have been created with
.Fn history_init .
.It Fn history
Perform operation
.Fa op
on the history list, with optional arguments as needed by the
operation.
.Fa ev
is changed accordingly to operation.
The following values for
.Fa op
are supported, along with the required argument list:
.Bl -tag -width 4n
.It Dv H_SETSIZE , Fa "int size"
Set size of history to
.Fa size
elements.
.It Dv H_GETSIZE
Get number of events currently in history.
.It Dv H_END
Cleans up and finishes with
.Fa h ,
assumed to be created with
.Fn history_init .
.It Dv H_CLEAR
Clear the history.
.It Dv H_FUNC , Fa "void *ptr" , Fa "history_gfun_t first" , \
Fa "history_gfun_t next" , Fa "history_gfun_t last" , \
Fa "history_gfun_t prev" , Fa "history_gfun_t curr" , \
Fa "history_sfun_t set" , Fa "history_vfun_t clear" , \
Fa "history_efun_t enter" , Fa "history_efun_t add"
Define functions to perform various history operations.
.Fa ptr
is the argument given to a function when it's invoked.
.It Dv H_FIRST
Return the first element in the history.
.It Dv H_LAST
Return the last element in the history.
.It Dv H_PREV
Return the previous element in the history.
.It Dv H_NEXT
Return the next element in the history.
.It Dv H_CURR
Return the current element in the history.
.It Dv H_SET
Set the cursor to point to the requested element.
.It Dv H_ADD , Fa "const char *str"
Append
.Fa str
to the current element of the history, or perform the
.Dv H_ENTER
operation with argument
.Fa str
if there is no current element.
.It Dv H_APPEND , Fa "const char *str"
Append
.Fa str
to the last new element of the history.
.It Dv H_ENTER , Fa "const char *str"
Add
.Fa str
as a new element to the history, and, if necessary,
removing the oldest entry to keep the list to the created size.
If
.Dv H_SETUNIQUE
was has been called with a non-zero arguments, the element
will not be entered into the history if its contents match
the ones of the current history element.
If the element is entered
.Fn history
returns 1, if it is ignored as a duplicate returns 0.
Finally
.Fn history
returns \-1 if an error occurred.
.It Dv H_PREV_STR , Fa "const char *str"
Return the closest previous event that starts with
.Fa str .
.It Dv H_NEXT_STR , Fa "const char *str"
Return the closest next event that starts with
.Fa str .
.It Dv H_PREV_EVENT , Fa "int e"
Return the previous event numbered
.Fa e .
.It Dv H_NEXT_EVENT , Fa "int e"
Return the next event numbered
.Fa e .
.It Dv H_LOAD , Fa "const char *file"
Load the history list stored in
.Fa file .
.It Dv H_SAVE , Fa "const char *file"
Save the history list to
.Fa file .
.It Dv H_SETUNIQUE , Fa "int unique"
Set flag that adjacent identical event strings should not be entered
into the history.
.It Dv H_GETUNIQUE
Retrieve the current setting if adjacent identical elements should
be entered into the history.
.It Dv H_DEL , Fa "int e"
Delete the event numbered
.Fa e .
This function is only provided for
.Xr readline 3
compatibility.
The caller is responsible for free'ing the string in the returned
.Fa HistEvent .
.El
.Pp
.Fn history
returns \*[Gt]= 0 if the operation
.Fa op
succeeds.
Otherwise, \-1 is returned and
.Fa ev
is updated to contain more details about the error.
.El
.Sh TOKENIZATION FUNCTIONS
The tokenization functions use a common data structure,
.Fa Tokenizer ,
which is created by
.Fn tok_init
and freed by
.Fn tok_end .
.Pp
The following functions are available:
.Bl -tag -width 4n
.It Fn tok_init
Initialise the tokenizer, and return a data structure
to be used by all other tokenizer functions.
.Fa IFS
contains the Input Field Separators, which defaults to
.Aq space ,
.Aq tab ,
and
.Aq newline
if
.Dv NULL .
.It Fn tok_end
Clean up and finish with
.Fa t ,
assumed to have been created with
.Fn tok_init .
.It Fn tok_reset
Reset the tokenizer state.
Use after a line has been successfully tokenized
by
.Fn tok_line
or
.Fn tok_str
and before a new line is to be tokenized.
.It Fn tok_line
Tokenize
.Fa li ,
If successful, modify:
.Fa argv
to contain the words,
.Fa argc
to contain the number of words,
.Fa cursorc
(if not
.Dv NULL )
to contain the index of the word containing the cursor,
and
.Fa cursoro
(if not
.Dv NULL )
to contain the offset within
.Fa argv[cursorc]
of the cursor.
.Pp
Returns
0 if successful,
\-1 for an internal error,
1 for an unmatched single quote,
2 for an unmatched double quote,
and
3 for a backslash quoted
.Aq newline .
A positive exit code indicates that another line should be read
and tokenization attempted again.
.
.It Fn tok_str
A simpler form of
.Fn tok_line ;
.Fa str
is a NUL terminated string to tokenize.
.El
.
.\"XXX.Sh EXAMPLES
.\"XXX: provide some examples
.Sh SEE ALSO
.Xr sh 1 ,
.Xr signal 3 ,
.Xr termcap 3 ,
.Xr editrc 5 ,
.Xr termcap 5
.Sh HISTORY
The
.Nm
library first appeared in
.Bx 4.4 .
.Dv CC_REDISPLAY
appeared in
.Nx 1.3 .
.Dv CC_REFRESH_BEEP ,
.Dv EL_EDITMODE
and the readline emulation appeared in
.Nx 1.4 .
.Dv EL_RPROMPT
appeared in
.Nx 1.5 .
.Sh AUTHORS
The
.Nm
library was written by Christos Zoulas.
Luke Mewburn wrote this manual and implemented
.Dv CC_REDISPLAY ,
.Dv CC_REFRESH_BEEP ,
.Dv EL_EDITMODE ,
and
.Dv EL_RPROMPT .
Jaromir Dolecek implemented the readline emulation.
Johny Mattsson implemented wide-character support.
.Sh BUGS
At this time, it is the responsibility of the caller to
check the result of the
.Dv EL_EDITMODE
operation of
.Fn el_get
(after an
.Fn el_source
or
.Fn el_parse )
to determine if
.Nm
should be used for further input.
I.e.,
.Dv EL_EDITMODE
is purely an indication of the result of the most recent
.Xr editrc 5
.Ic edit
command.
+490
View File
@@ -0,0 +1,490 @@
.\" $NetBSD: editrc.5,v 1.24 2009/04/11 22:17:52 wiz Exp $
.\"
.\" Copyright (c) 1997-2000 The NetBSD Foundation, Inc.
.\" All rights reserved.
.\"
.\" This file was contributed to The NetBSD Foundation by Luke Mewburn.
.\"
.\" Redistribution and use in source and binary forms, with or without
.\" modification, are permitted provided that the following conditions
.\" are met:
.\" 1. Redistributions of source code must retain the above copyright
.\" notice, this list of conditions and the following disclaimer.
.\" 2. Redistributions in binary form must reproduce the above copyright
.\" notice, this list of conditions and the following disclaimer in the
.\" documentation and/or other materials provided with the distribution.
.\"
.\" THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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 October 18, 2003
.Dt EDITRC 5
.Os
.Sh NAME
.Nm editrc
.Nd configuration file for editline library
.Sh SYNOPSIS
.Nm
.Sh DESCRIPTION
The
.Nm
file defines various settings to be used by the
.Xr editline 3
library.
.Pp
The format of each line is:
.Dl [prog:]command [arg [...]]
.Pp
.Ar command
is one of the
.Xr editline 3
builtin commands.
Refer to
.Sx BUILTIN COMMANDS
for more information.
.Pp
.Ar prog
is the program name string that a program defines when it calls
.Xr el_init 3
to set up
.Xr editline 3 ,
which is usually
.Va argv[0] .
.Ar command
will be executed for any program which matches
.Ar prog .
.Pp
.Ar prog
may also be a
.Xr regex 3
style
regular expression, in which case
.Ar command
will be executed for any program that matches the regular expression.
.Pp
If
.Ar prog
is absent,
.Ar command
is executed for all programs.
.Sh BUILTIN COMMANDS
The
.Nm editline
library has some builtin commands, which affect the way
that the line editing and history functions operate.
These are based on similar named builtins present in the
.Xr tcsh 1
shell.
.Pp
The following builtin commands are available:
.Bl -tag -width 4n
.It Ic bind Oo Fl a Oc Oo Fl e Oc Oo Fl k Oc Oo Fl l Oc Oo Fl r Oc \
Oo Fl s Oc Oo Fl v Oc Oo Ar key Op Ar command Oc
Without options, list all bound keys, and the editor command to which
each is bound.
If
.Ar key
is supplied, show the bindings for
.Ar key .
If
.Ar key command
is supplied, bind
.Ar command
to
.Ar key .
Options include:
.Bl -tag -width 4n
.It Fl e
Bind all keys to the standard GNU Emacs-like bindings.
.It Fl v
Bind all keys to the standard
.Xr vi 1 Ns -like
bindings.
.It Fl a
List or change key bindings in the
.Xr vi 1
mode alternate (command mode) key map.
.It Fl k
.Ar key
is interpreted as a symbolic arrow key name, which may be one of
.Sq up ,
.Sq down ,
.Sq left
or
.Sq right .
.It Fl l
List all editor commands and a short description of each.
.It Fl r
Remove a key's binding.
.It Fl s
.Ar command
is taken as a literal string and treated as terminal input when
.Ar key
is typed.
Bound keys in
.Ar command
are themselves reinterpreted, and this continues for ten levels of
interpretation.
.El
.Pp
.Ar command
may be one of the commands documented in
.Sx "EDITOR COMMANDS"
below, or another key.
.Pp
.Ar key
and
.Ar command
can contain control characters of the form
.Sm off
.Sq No ^ Ar character
.Sm on
.Po
e.g.
.Sq ^A
.Pc ,
and the following backslashed escape sequences:
.Pp
.Bl -tag -compact -offset indent -width 4n
.It Ic \ea
Bell
.It Ic \eb
Backspace
.It Ic \ee
Escape
.It Ic \ef
Formfeed
.It Ic \en
Newline
.It Ic \er
Carriage return
.It Ic \et
Horizontal tab
.It Ic \ev
Vertical tab
.Sm off
.It Sy \e Ar nnn
.Sm on
The ASCII character corresponding to the octal number
.Ar nnn .
.El
.Pp
.Sq \e
nullifies the special meaning of the following character,
if it has any, notably
.Sq \e
and
.Sq ^ .
.It Ic echotc Oo Fl sv Oc Ar arg Ar ...
Exercise terminal capabilities given in
.Ar arg Ar ... .
If
.Ar arg
is
.Sq baud ,
.Sq cols ,
.Sq lines ,
.Sq rows ,
.Sq meta or
.Sq tabs ,
the value of that capability is printed, with
.Dq yes
or
.Dq no
indicating that the terminal does or does not have that capability.
.Pp
.Fl s
returns an empty string for non-existent capabilities, rather than
causing an error.
.Fl v
causes messages to be verbose.
.It Ic edit Op Li on | Li off
Enable or disable the
.Nm editline
functionality in a program.
.It Ic history Ar list | Ar size Dv n | Ar unique Dv n
The
.Ar list
command lists all entries in the history.
The
.Ar size
command sets the history size to
.Dv n
entries.
The
.Ar unique
command controls if history should keep duplicate entries.
If
.Dv n
is non zero, only keep unique history entries.
If
.Dv n
is zero, then keep all entries (the default).
.It Ic telltc
List the values of all the terminal capabilities (see
.Xr termcap 5 ) .
.It Ic settc Ar cap Ar val
Set the terminal capability
.Ar cap
to
.Ar val ,
as defined in
.Xr termcap 5 .
No sanity checking is done.
.It Ic setty Oo Fl a Oc Oo Fl d Oc Oo Fl q Oc Oo Fl x Oc Oo Ar +mode Oc \
Oo Ar -mode Oc Oo Ar mode Oc Oo Ar char=c Oc
Control which tty modes that
.Nm
won't allow the user to change.
.Fl d ,
.Fl q
or
.Fl x
tells
.Ic setty
to act on the
.Sq edit ,
.Sq quote
or
.Sq execute
set of tty modes respectively; defaulting to
.Fl x .
.Pp
Without other arguments,
.Ic setty
lists the modes in the chosen set which are fixed on
.Po
.Sq +mode
.Pc
or off
.Po
.Sq -mode
.Pc .
.Fl a
lists all tty modes in the chosen set regardless of the setting.
With
.Ar +mode ,
.Ar -mode
or
.Ar mode ,
fixes
.Ar mode
on or off or removes control of
.Ar mode
in the chosen set.
.Pp
.Ic Setty
can also be used to set tty characters to particular values using
.Ar char=value .
If
.Ar value
is empty
then the character is set to
.Dv _POSIX_VDISABLE .
.El
.Sh EDITOR COMMANDS
The following editor commands are available for use in key bindings:
.\" Section automatically generated with makelist
.Bl -tag -width 4n
.It Ic vi-paste-next
Vi paste previous deletion to the right of the cursor.
.It Ic vi-paste-prev
Vi paste previous deletion to the left of the cursor.
.It Ic vi-prev-space-word
Vi move to the previous space delimited word.
.It Ic vi-prev-word
Vi move to the previous word.
.It Ic vi-next-space-word
Vi move to the next space delimited word.
.It Ic vi-next-word
Vi move to the next word.
.It Ic vi-change-case
Vi change case of character under the cursor and advance one character.
.It Ic vi-change-meta
Vi change prefix command.
.It Ic vi-insert-at-bol
Vi enter insert mode at the beginning of line.
.It Ic vi-replace-char
Vi replace character under the cursor with the next character typed.
.It Ic vi-replace-mode
Vi enter replace mode.
.It Ic vi-substitute-char
Vi replace character under the cursor and enter insert mode.
.It Ic vi-substitute-line
Vi substitute entire line.
.It Ic vi-change-to-eol
Vi change to end of line.
.It Ic vi-insert
Vi enter insert mode.
.It Ic vi-add
Vi enter insert mode after the cursor.
.It Ic vi-add-at-eol
Vi enter insert mode at end of line.
.It Ic vi-delete-meta
Vi delete prefix command.
.It Ic vi-end-word
Vi move to the end of the current space delimited word.
.It Ic vi-to-end-word
Vi move to the end of the current word.
.It Ic vi-undo
Vi undo last change.
.It Ic vi-command-mode
Vi enter command mode (use alternative key bindings).
.It Ic vi-zero
Vi move to the beginning of line.
.It Ic vi-delete-prev-char
Vi move to previous character (backspace).
.It Ic vi-list-or-eof
Vi list choices for completion or indicate end of file if empty line.
.It Ic vi-kill-line-prev
Vi cut from beginning of line to cursor.
.It Ic vi-search-prev
Vi search history previous.
.It Ic vi-search-next
Vi search history next.
.It Ic vi-repeat-search-next
Vi repeat current search in the same search direction.
.It Ic vi-repeat-search-prev
Vi repeat current search in the opposite search direction.
.It Ic vi-next-char
Vi move to the character specified next.
.It Ic vi-prev-char
Vi move to the character specified previous.
.It Ic vi-to-next-char
Vi move up to the character specified next.
.It Ic vi-to-prev-char
Vi move up to the character specified previous.
.It Ic vi-repeat-next-char
Vi repeat current character search in the same search direction.
.It Ic vi-repeat-prev-char
Vi repeat current character search in the opposite search direction.
.It Ic em-delete-or-list
Delete character under cursor or list completions if at end of line.
.It Ic em-delete-next-word
Cut from cursor to end of current word.
.It Ic em-yank
Paste cut buffer at cursor position.
.It Ic em-kill-line
Cut the entire line and save in cut buffer.
.It Ic em-kill-region
Cut area between mark and cursor and save in cut buffer.
.It Ic em-copy-region
Copy area between mark and cursor to cut buffer.
.It Ic em-gosmacs-transpose
Exchange the two characters before the cursor.
.It Ic em-next-word
Move next to end of current word.
.It Ic em-upper-case
Uppercase the characters from cursor to end of current word.
.It Ic em-capitol-case
Capitalize the characters from cursor to end of current word.
.It Ic em-lower-case
Lowercase the characters from cursor to end of current word.
.It Ic em-set-mark
Set the mark at cursor.
.It Ic em-exchange-mark
Exchange the cursor and mark.
.It Ic em-universal-argument
Universal argument (argument times 4).
.It Ic em-meta-next
Add 8th bit to next character typed.
.It Ic em-toggle-overwrite
Switch from insert to overwrite mode or vice versa.
.It Ic em-copy-prev-word
Copy current word to cursor.
.It Ic em-inc-search-next
Emacs incremental next search.
.It Ic em-inc-search-prev
Emacs incremental reverse search.
.It Ic ed-end-of-file
Indicate end of file.
.It Ic ed-insert
Add character to the line.
.It Ic ed-delete-prev-word
Delete from beginning of current word to cursor.
.It Ic ed-delete-next-char
Delete character under cursor.
.It Ic ed-kill-line
Cut to the end of line.
.It Ic ed-move-to-end
Move cursor to the end of line.
.It Ic ed-move-to-beg
Move cursor to the beginning of line.
.It Ic ed-transpose-chars
Exchange the character to the left of the cursor with the one under it.
.It Ic ed-next-char
Move to the right one character.
.It Ic ed-prev-word
Move to the beginning of the current word.
.It Ic ed-prev-char
Move to the left one character.
.It Ic ed-quoted-insert
Add the next character typed verbatim.
.It Ic ed-digit
Adds to argument or enters a digit.
.It Ic ed-argument-digit
Digit that starts argument.
.It Ic ed-unassigned
Indicates unbound character.
.It Ic ed-tty-sigint
Tty interrupt character.
.It Ic ed-tty-dsusp
Tty delayed suspend character.
.It Ic ed-tty-flush-output
Tty flush output characters.
.It Ic ed-tty-sigquit
Tty quit character.
.It Ic ed-tty-sigtstp
Tty suspend character.
.It Ic ed-tty-stop-output
Tty disallow output characters.
.It Ic ed-tty-start-output
Tty allow output characters.
.It Ic ed-newline
Execute command.
.It Ic ed-delete-prev-char
Delete the character to the left of the cursor.
.It Ic ed-clear-screen
Clear screen leaving current line at the top.
.It Ic ed-redisplay
Redisplay everything.
.It Ic ed-start-over
Erase current line and start from scratch.
.It Ic ed-sequence-lead-in
First character in a bound sequence.
.It Ic ed-prev-history
Move to the previous history line.
.It Ic ed-next-history
Move to the next history line.
.It Ic ed-search-prev-history
Search previous in history for a line matching the current.
.It Ic ed-search-next-history
Search next in history for a line matching the current.
.It Ic ed-prev-line
Move up one line.
.It Ic ed-next-line
Move down one line.
.It Ic ed-command
Editline extended command.
.El
.\" End of section automatically generated with makelist
.Sh SEE ALSO
.Xr editline 3 ,
.Xr regex 3 ,
.Xr termcap 5
.Sh AUTHORS
The
.Nm editline
library was written by Christos Zoulas,
and this manual was written by Luke Mewburn,
with some sections inspired by
.Xr tcsh 1 .

Some files were not shown because too many files have changed in this diff Show More