Compare commits
3 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
3a17ecb3e5
|
|||
|
19156b61f1
|
|||
|
63ad2a7931
|
@@ -3,7 +3,6 @@ name: Test Coverage
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- 'master'
|
||||
- 'coverage-*'
|
||||
|
||||
jobs:
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
'
|
||||
|
||||
@@ -62,7 +62,6 @@ jobs:
|
||||
- name: osx-clang
|
||||
os: macos-latest
|
||||
compiler: clang
|
||||
configureopts: '--with-libedit=yes'
|
||||
steps:
|
||||
- name: Install packages
|
||||
run: |
|
||||
|
||||
@@ -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
@@ -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-*
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
[](https://github.com/heimdal/heimdal/actions?query=workflow%3Alinux)
|
||||
[](https://github.com/heimdal/heimdal/actions?query=workflow%3Aosx)
|
||||
[](https://github.com/heimdal/heimdal/actions?query=workflow%3Awindows)
|
||||
[](https://coveralls.io/github/heimdal/heimdal?branch=master)
|
||||
|
||||
Heimdal
|
||||
=======
|
||||
@@ -34,4 +33,3 @@ Build Status
|
||||
[](https://github.com/heimdal/heimdal/actions?query=workflow%3Alinux)
|
||||
[](https://github.com/heimdal/heimdal/actions?query=workflow%3Aosx)
|
||||
[](https://github.com/heimdal/heimdal/actions?query=workflow%3Awindows)
|
||||
[](https://coveralls.io/github/heimdal/heimdal?branch=master)
|
||||
|
||||
+27
-50
@@ -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);
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
@@ -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
|
||||
|
||||
])
|
||||
|
||||
@@ -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
@@ -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
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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.
|
||||
|
||||
|
||||
@@ -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
@@ -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": {
|
||||
|
||||
@@ -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
@@ -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
@@ -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
|
||||
|
||||
|
||||
@@ -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
@@ -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
@@ -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
@@ -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
|
||||
|
||||
@@ -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
@@ -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);
|
||||
|
||||
@@ -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
@@ -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
@@ -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;
|
||||
|
||||
@@ -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
@@ -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
@@ -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
@@ -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);
|
||||
|
||||
|
||||
@@ -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
@@ -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));
|
||||
|
||||
@@ -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 \
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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]);
|
||||
|
||||
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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;
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
@@ -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:
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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");
|
||||
|
||||
|
||||
@@ -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
@@ -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
@@ -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) {
|
||||
|
||||
@@ -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-----
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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
@@ -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)
|
||||
|
||||
@@ -41,6 +41,8 @@
|
||||
#include <sys/un.h>
|
||||
#endif
|
||||
|
||||
#include <poll.h>
|
||||
|
||||
#include <ctype.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
+38
-111
@@ -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)
|
||||
¤t_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)
|
||||
¤t_version, NULL);
|
||||
}
|
||||
|
||||
if (nready == 0) {
|
||||
if (ret == 0) {
|
||||
kadm5_log_get_version_fd(server_context, -1, LOG_VERSION_LAST,
|
||||
¤t_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,
|
||||
¤t_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);
|
||||
}
|
||||
|
||||
@@ -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
@@ -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
@@ -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;
|
||||
|
||||
@@ -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
@@ -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
@@ -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)
|
||||
|
||||
@@ -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+";
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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 ,
|
||||
|
||||
@@ -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
@@ -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
@@ -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
File diff suppressed because it is too large
Load Diff
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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");
|
||||
|
||||
}
|
||||
|
||||
@@ -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
@@ -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;
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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.
|
||||
@@ -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.
|
||||
|
||||
@@ -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
|
||||
@@ -0,0 +1 @@
|
||||
Thanks to the NetBSD Project maintainers of libedit!
|
||||
@@ -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)])
|
||||
])
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
@@ -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/&/\&/g; s/</\</g; s/>/\>/g;' $(srcdir)/$< > $@;
|
||||
|
||||
|
||||
@@ -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.
|
||||
@@ -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
Reference in New Issue
Block a user